i have written this code to copy 5 names in a structure

#include<conio.h>
#define loop_count 5
char copy_name(char *);

 typedef struct{
        int count;
        char name[3][20];
        }student;
 student *p;            //declare structure pointer;

int main()
{
    student s;  //declare variable of type student ;
     p=&s;      //giving p address of s;
    p->count=0;    //initialize p->count value 0;

    char input_name[20];  // an array to input names;

    int i;//i for loop count;

    for(i=0;i<loop_count;i++){
          fgets(input_name,20,stdin);
          copy_name(input_name);  //call function ;

           if(p->count==loop_count)//for breaking the loop when (p->count==5);
              break;
          }

     for(i=0;i<loop_count;i++){
                     printf("%s",p->name[i]);//print the names copied in structure;
                     }
                     getch();
                     }


 char copy_name(char *q){

     strncpy(p->name[(p->count)++],q,20);//copy names inside structure;
     }

my question is here

strncpy(p->name[(p->count)++],q,20);

first name is copied to p->name[0]; then when we input the next name if it is not incremented to p->name[1] after copying p->name[0]; it (p->name[0])should be over written. if it is not then when it is incremented to next array p->count[1] ??

if it is incremented to p->name[1] after copying p->name[0]; then after copying fourth name the value of p->count will be 4. for this the loop will break cause(p->count==loop_count==5) and we cannot copy the fifth name.
please help.

First, you only allow for 3 names in you structure (name[3][20]) so copying 5 is going to do potentially bad things.

p->count++ increments the counter. There is no if is does, if it doesn't

Also, I'm confused by your comments:

... p->count will be 4. for this the loop will break cause(p->count==loop_count==5)...

p->count is either 4 or 5 - not both. I think what you are trying to do is use p-count as a loop terminator and that is fine. You need to allocate enough room for that in your structure or lower the expected maximum loop count. Perhaps something like:

#define MAX_NAMES 5
#define NAME_LENGTH 20

struct name_struct {
   int count; 
   char names[MAX_NAMES][NAME_LENGTH];
};

// ... somewharere later in the code

for (p->count = 0; p->count < MAX_NAMES; p->count++) {
   fgets(input_name,NAME_LENGTH,stdin);
   strncpy (p->name[p->count], input_name, NAME_LENGTH);
}

The macro names add to the readability of the code and help to ensure that you don't introduce and off-by-one error somewhere.

sorry for unwanted mistakes.what i tried to ask is--
1.user will input "first name" and called function will send it to strncpy to copy in the structure;and it copies;

2.then it returns and user inter next name,then function call send it to strncpy ,then strncpy will check whether p->name[0] is free or not.if not then it incremented to p->name[1]and copy name there and so on;

3.OR the array index is incremente to p->name[1] just after copying first name to p->name[0];

which is true???i need to know that bcoz sometimes it is necessary to send names via function to copy.

The p-count value is incremented by the ++ operator. No check is made by strncpy at any time for the availability of space - you need to ensure that on your own. If you call the strncpy function the way you have things set up you will have an incremented counter if the call returns.

you will have an incremented counter if the call returns.

ok but can ou tell me is it incremented after the new call is made or before the previous call return??

This:

strncpy(p->name[(p->count)++], q, 20);

Is roughly equivalent to this:

strncpy(p->name[p->count], q, 20);
++p->count;

I'm not sure where your confusion lies, but I'm all but certain you're overcomplicating things.

I dont understand your question. The call happens (roughly) like this:

strncpy (p->name[(p->count)++], input_name, NAME_LENGTH);
  • store value of p->count somewhere (call that v1)
  • increment value of p->count (p->count is now one more than it was in the previous step)
  • use v1 (original p->count value) to index into p->name. Looks something like p->name[v1]
  • Use result of previous step as first argument to strncpy

So the value is incremented previous to the actual call to strncpy but you can not access the variable until the call returns. The call itself uses the previous value of the variable because you are using the post increment operator. The story would be different if you were using the pre increment operator (placing the ++ before the variable).

The example I provided in my previous post removes the confusion entirely. If you are not certain how these things work it might be better to take an approach like that to avoid pitfalls until you understand things better.

thnx guys.those two comments made my confusions clear.that is all i wanted to know.

thnx guys.those two comments made my confusions clear.that is all i wanted to know.

Cool. Actually, I think the function call entry sequence point is the most difficult of them to wrap your head around because often it's academic in nature and makes no apparent difference in practice.

All of the other sequence points are pretty straightforward, with the possible exception of the comma operator because not every use of a comma in C is the comma operator (what kind of existential mess is that?).

yes i didnt know that arguments have to be compleatly evaluated first .thnx to you guys for making me clear.initial value is executed first and then incremented and is reserved somewhere to be used for the next call.still dont know much about comma operator .wish to work on that too.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.