C as an OO Pointer Issue?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • DaemonCoder
    New Member
    • Mar 2008
    • 43

    C as an OO Pointer Issue?

    I am trying to create a structure. reads a name and stores it to a variable in the structure and then print it. Sounds simple enough. Look at the ouput i got. I am so lost its not even funny...

    Code:
    E:\COMMAN~1>gcc st.c -o st.exe -std=c99
    
    E:\COMMAN~1>st
    
     on NTVDM, specify an inval
     on NTVDM, specify an inval
     Name:  on NTVDM, specify an inval
     Name: on NTVDM, specify an inval
     Name: n NTVDM, specify an inval
     Name:  NTVDM, specify an inval
     Name: NTVDM, specify an inval
     Name: TVDM, specify an inval
     Name: VDM, specify an inval
     Name: DM, specify an inval
     Name: M, specify an inval
     Name: , specify an inval
     Name:  specify an inval
     Name: specify an inval
     Name: pecify an inval
     Name: ecify an inval
     Name: cify an inval
     Name: ify an inval
     Name: fy an inval
     Name: y an inval
     Name:  an inval
     Name: an inval
     Name: n inval
     Name:  inval
     Name: inval
     Name: nval
     Name: val
     Name: al
     Name: l
    My code is below... can someone help me with this...
    Code:
    typedef struct 
    	{
    	     char name[30];
    	} Student;     // name of structure 
    
    int myStruct_set_values(Student* s, char data[30])
    {
      
     	for(int i=0;i<29;i++)
    	{
    		s -> name[i] = data[i];
    	}
    }
    
    int main()
    {
    
    	Student sOne;
    	Student* st_ptr = &sOne;
    	
    	char input[30];
    	myStruct_set_values(st_ptr, input);
    	
    	sscanf("%s",input);
    
    	for(int i=0;i<29;i++)
    	{
    		printf(" \n Name: %s", &st_ptr -> name[i]);
    	}
    }
    I think this is a pointer issue.. but i am not sure...
  • DaemonCoder
    New Member
    • Mar 2008
    • 43

    #2
    I changed the sscanf() to scanf(). It accepted the data but i still recieved the same printout.

    Code:
    int main()
    {
    
    	Student sOne;
    	Student* st_ptr = &sOne;
    	
    	char input[30];
    	myStruct_set_values(&st_ptr, input);
    	
    	scanf("%s", input);
    	printf(" \n Name: %s", sOne.name);
    }
    The output is below. Why is this?

    Code:
    E:\COMMAN~1>st
    dsefe
    
     Name: n NTVDM, specify an inval
    E:\COMMAN~1>

    Comment

    • Banfa
      Recognized Expert Expert
      • Feb 2006
      • 9067

      #3
      The strange output is because the array name is never initialised to anything but you copy it's contents to your structure and the for loop at the end of main. Exactly what is it you are trying to do with this loop?

      Also in myStruct_set_va lues you have used a for loop where you could have used strcpy or memcpy but this does not effect the output.

      Comment

      • DaemonCoder
        New Member
        • Mar 2008
        • 43

        #4
        I did something... but i am still not getting the desired output. now i get a zero.
        here is the code and output now...

        Code:
        typedef struct  
        	{
        	char name[30];
        	} Student;     // name of structure 
        
        int myStruct_set_values(Student *s, char data[30])
        {
          
         	for(int i=0;i<29;i++)
        	{
        		memcpy(data, s -> name, sizeof(s -> name));
        	}
        }
        int main()
        {
        
        	
        	
        	Student sOne, *st_ptr;
        	
        	st_ptr = &sOne;
        	
        	st_ptr -> name[0] = '0';
        	char input[30];
        		
        	scanf("%s", input);
        	
        	myStruct_set_values(&st_ptr, input);
        
        	printf(" \n Name: %s", st_ptr -> name);
        }

        Comment

        • DaemonCoder
          New Member
          • Mar 2008
          • 43

          #5
          This is the warning message and output i get when i compiled the version of code above.

          Code:
          E:\COMMAN~1>gcc st.c -o st.exe -std=c99
          st.c: In function `main':
          st.c:35: warning: passing arg 1 of `myStruct_set_values' from incompatible point
          er type
          
          E:\COMMAN~1>st
          fff
          
           Name: 0
          E:\COMMAN~1>

          Comment

          • DaemonCoder
            New Member
            • Mar 2008
            • 43

            #6
            I am starting to think i am talking to myself... I got the program to display the input.. but noe i have another problem even with the max array set at 30, i only get four characters output to the screen...

            Code:
            typedef struct  
            	{
            	char name[30];
            	} Student;     // name of structure 
            
            int myStruct_set_values(Student *s, char data[30])
            {
            	memcpy(s -> name, data, sizeof(data));
            	
            }
            
            int main()
            {
            
            	
            	
            	Student sOne, *st_ptr;
            	
            	st_ptr = &sOne;
            	
            	st_ptr -> name[0] = '0';
            	
            	char input[30];
            		
            	gets(input);
            	
            	myStruct_set_values(st_ptr, input);
            
            	printf(" \n Name: %s", st_ptr -> name);
            }

            Comment

            • DaemonCoder
              New Member
              • Mar 2008
              • 43

              #7
              According to

              Code:
              int sodata = sizeof(data);
              printf("\nThe size of the data element is : %d.\n", sodata);
              The size of data is 4.. no matter what i set any on the array sizes at data is always 4. How do i fix this so that all the inpute gets written to the screen and not just four characters...?? ?

              Comment

              • Banfa
                Recognized Expert Expert
                • Feb 2006
                • 9067

                #8
                Originally posted by DaemonCoder
                [CODE]int myStruct_set_va lues(Student *s, char data[30])
                {
                memcpy(s -> name, data, sizeof(data));
                }
                Sorry it had got past my bed time so I went to sleep.

                OK mistake of the new and inexperienced here so don't worry I have seen loads of people make this mistake. It stems from the fact that you can't pass arrays to functions so when you wrote

                int myStruct_set_va lues(Student *s, char data[30])

                although you appear to have written the 2nd parameter as an array of 30 characters the compiler actually produces a char * (the 30 gets ignored) so this is equivalent to

                int myStruct_set_va lues(Student *s, char *data)

                then in your memcpy you use sizeof(data) but data is not the array you think it is, it is a pointer so hence it's size is 4 bytes (a very common pointer size on 32 bit systems).

                You will have to find another way to get the size of the data pointed to, you have a couple of choices
                1. use size of the destination sizeof(s->name), this actually is an array so you wont get the problem and you protect the name array in MyStruct from overwriting the end of the buffer, so good. However you then have the caveat that data must point to at least sizeof(s->name) bytes or risk a data access exception.
                2. Give the function a 3rd parameter, the number of bytes to copy. Then data can point to a buffer of any size but you will need to check that the size is not > sizeof(s->name) before using it otherwise you will over-write the end of the buffer in MyStruct.

                Comment

                • DaemonCoder
                  New Member
                  • Mar 2008
                  • 43

                  #9
                  I dont have my compiler right here in front of me. If i did i would already have the answer to my question. Since the compile returns a size 4.. and that is the direct size of data... if i use &data like this

                  [code=c]

                  memcpy(s -> name, data, sizeof(&data));

                  int sodata = sizeof(&data);
                  printf("\nThe size of the data element is : %d.\n", sodata);

                  [/code]

                  If data is nothing more than a pointer.. wouldn't the value returned be that of name[30]??

                  Please correct me if im wrong this is just a theory....

                  Comment

                  • Banfa
                    Recognized Expert Expert
                    • Feb 2006
                    • 9067

                    #10
                    Originally posted by DaemonCoder
                    I dont have my compiler right here in front of me. If i did i would already have the answer to my question. Since the compile returns a size 4.. and that is the direct size of data... if i use &data like this

                    [code=c]

                    memcpy(s -> name, data, sizeof(&data));

                    int sodata = sizeof(&data);
                    printf("\nThe size of the data element is : %d.\n", sodata);

                    [/code]

                    If data is nothing more than a pointer.. wouldn't the value returned be that of name[30]??

                    Please correct me if im wrong this is just a theory....
                    Sorry about the delay.

                    firstly data is a pointer, you want to reference it not de-reference it so the correct syntax is sizeof(*data). However like I said in a function declaration/definition the syntax char data[30] is a declaration of a pointer to char (char *) the 30 is ignored sizeof(*data) == 1.

                    To do what you want you would have to declare a pointer to an array of 30 char and the syntax for that is char (*data)[30]. Then sizeof *data == 30.

                    try this

                    [code=c]
                    #include <stdio.h>

                    void Fn1(char data[30])
                    {
                    sprintf(data, "Fn1: %d", sizeof *data);
                    }

                    void Fn2(char (*data)[30])
                    {
                    sprintf(*data, "Fn2: %d", sizeof *data);
                    }

                    int main()
                    {
                    char data[30];

                    Fn1(data);
                    puts(data);
                    Fn2(&data);
                    puts(data);

                    return(0);
                    }[/code]

                    Comment

                    Working...