Pretty easy question in C

I have this program which i wrote in C.  Right now it just needs to open a file, then read the pairs of parts from the file (word then int, word then int, over and over) until there are no more pairs and stop.  In my try_to_read function my fscanf is working perfectly and everything dealing with the int y part is working good, however, I have an error in there and im storing the string wrong.  The program compiles fine with no errors.  My teacher told me how to fix the program, but he wants to know, if i leave my program like it is now, where are the words actually being stored to.  (Like are they being put into random bits, or the adress of my struct or what, and i cant figure out where they are going, like what do i have to printf in order to get them out)

struct part
{
char x[20];
int y;
};

int try_to_read_part(FILE *fp, struct part *p);

int main()
{
      struct part p;
      FILE *fp;
      fp=fopen("parts.dat","r");
      while(try_to_read_part(fp, &p);      
      return 0;
}

int try_to_read_part(FILE *fp, struct part *p)
{
      if (fscanf(fp,"%s%d",&(p->x[20]),&(p->y))==2) ********(line im talking about)
            return 1;
      return 0;
}

************(fscanf(fp,"%s%d",p->x,&(p->y))==2) ********correct way to do it
mastergamer232Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

cookreCommented:
Interesting to see what the compiler thinks:

The 'proper' way:
mov     eax, DWORD PTR _p$[esp-4]
mov     edx, DWORD PTR _fp$[esp-4]
lea     ecx, DWORD PTR [eax+20]
push    ecx
push    eax
push    OFFSET FLAT:??_C@_04MOFI@?$CFs?$CFd?$AA@ ; `string'
push    edx
call    _fscanf
add     esp, 16                        ; 00000010H
xor     ecx, ecx
cmp     eax, 2
sete    cl
mov     eax, ecx
The 'wrong way'
mov     eax, DWORD PTR _p$[esp-4]
mov     ecx, DWORD PTR _fp$[esp-4]
add     eax, 20                        ; 00000014H
push    eax
push    eax
push    OFFSET FLAT:??_C@_04MOFI@?$CFs?$CFd?$AA@ ; `string'
push    ecx
call    _fscanf
add     esp, 16                        ; 00000010H
xor     edx, edx
cmp     eax, 2
sete    dl
mov     eax, edx

joele23Commented:
Hi,

so basically you have an array of 20 characters, the starting index at index 0 and going to 19.
In your fscanf you the string you scan in goes to &(p->x[20]) which is saying store the string starting at the memory location of p and shift 20 characters. So basically wrinting into memeory that is just past what you allocated. This memory could really contain anything and it is not allocated for your use.

Another thing to note is that if even when you do it with your teachers 'correct' way this is possibly not safe either. In your teacher case the p->x is the memory location with a 0 offset. Which is what you want but if the string(word) you are reading in is longer than 20 characters then you have once again passed the bounds of memory allocated to it and your writing into that unassigned memory again.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
mastergamer232Author Commented:
thanks joele23, u win
cookreCommented:
FWIW:

struct part
       {
       char x[20];
       int y;
       };

void silly(struct part *);


void main(int argc, char* argv[])
{
struct part p;

strcpy(p.x,"Howdy Do!");
p.y=1234;
printf("<%s> (%d)\n",p.x,p.y);
silly(&p);
return;
}

void silly(struct part *p)
{
printf("  Right: %08x\n",p->x);
printf("  Wrong: %08x\n",&(p->x[20]));
printf("p is at: %08x\n",p);
printf("Other 1: %08x\n",&(p->x)[20]);
printf("Other 2: %08x\n",(&(p->x))[20]);
return;
}

<Howdy Do!> (1234)
    Right: 0012ff6c
  Wrong: 0012ff80
   p is at: 0012ff6c
Other 1: 0012ff80
Other 2: 001300fc

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Programming

From novice to tech pro — start learning today.