Thread: I cannot find out the error in the program.

  1. #1
    Registered User
    Join Date
    Jun 2011
    Posts
    5

    I cannot find out the error in the program.

    Code:
    #include "stdio.h"
    #include "string.h"
    #include "stdlib.h"
    struct stu {
          char *sno;
          char *sname;
          char  *sex;
    };
    void main() {
             FILE *fp;
             stu stus[100];
             char str[15];
             int i = 0;
             if((fp = fopen("d:\\student.txt","rt+")) == NULL) {
            
                     printf("Cannot open the file!");
                     exit(1);
             } else {   
                     while(fgets(str,20,fp) !=NULL)
                   {
                             stus[i].sno = strtok(str,",");
                             stus[i].sname = strtok( NULL, "," );
                             stus[i].ssex = strtok( NULL, "," );
                             printf("%s %s %s\n", stus[i].sno,stus[i].sname,stus[i].ssex);
                             i++;       
                     }
                    
                     for(int j = 0; j < i; j++) {
                             printf(" %s %s %s \n", stus[j].sno,stus[j].sname,stus[j].ssex);
                     }
             }        
    }
    IF the data of student.txt is :
    1,Jim,boy
    2,Bruce,boy
    3,Sala,girl


    and run the program,why it shows this?
    1,Jim,boy
    2,Bruce,boy
    3,Sala,girl
    3,Sala,girl
    3,Sala,girl
    3,Sala,girl


    Could you help me? Thank you!!My English just so so.
    Last edited by from_china; 06-18-2011 at 10:50 PM. Reason: there is a problem

  2. #2
    Registered User
    Join Date
    Jun 2011
    Posts
    5
    All are sleeping now!

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Please note for the future, bumping your thread (replying to it yourself with useless info to move it up the list) is considered rude, and against the forum guidelines: Announcements - C Programming.

    Also, please provide compilable code in the future. I can't very well solve a run time problem if you code wont even compile. It's not cool to make us fix syntax errors because you typed the code off the top of your head, instead of copy-pasting from your editor. Copy-paste the code and the output (the "output" you listed is not what the program actually produces). Often times we can diagnose the problem by sight without having to compile and debug if we can see the actual code and actual output. Here's a list of errors/warnings with the code you provided:
    Code:
    $ gcc -Wall student.c
    student.c: In function ‘main’:
    student.c:13: error: ‘stu’ undeclared (first use in this function)
    student.c:13: error: (Each undeclared identifier is reported only once
    student.c:13: error: for each function it appears in.)
    student.c:13: error: expected ‘;’ before ‘stus’
    student.c:22: error: ‘stus’ undeclared (first use in this function)
    student.c:29: error: ‘for’ loop initial declaration used outside C99 mode
    and the actual, bad output:
    Code:
    1 Jim boy
    
    2 Bruce boy
    
    3 Sala girl
    
     3 Sala
     3 Sala irl
    
     3 Sala girl
    First things first, the correct form is int main(void), and return an int at the end, usually 0. Read why it matters here:
    Cprogramming.com FAQ > main() / void main() / int main() / int main(void) / int main(int argc, char *argv[])
    void main(void) - the Wrong Thing

    As for your problem, it has to do with the way strtok works. strtok operates on the string you pass in, in this case, str. When you read the first line (Jim), you set stus[0].sno, stus[0].sname and stus[0].ssex to places in the str array. Since you only have one copy, and keep reading the next line into that, you end up with each student record pointing into the same array, which contains the last student's info when you're done reading the file. Since the names are different lengths, you end up with slightly different variations of "3 Sala girl".

    To fix this, you could make sno, sname and ssex actual arrays in the structure, and use strcpy to move the result of strtok into the number, name or sex field.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > and run the program,why it shows this?
    Well look at when various bits of the output are printed.
    1,Jim,boy
    2,Bruce,boy
    3,Sala,girl

    3,Sala,girl
    3,Sala,girl
    3,Sala,girl


    Code:
                     while(fgets(str,20,fp) !=NULL)
                   {
                             stus[i].sno = strtok(str,",");
                             stus[i].sname = strtok( NULL, "," );
                             stus[i].ssex = strtok( NULL, "," );
                             printf("%s %s %s\n", stus[i].sno,stus[i].sname,stus[i].ssex);
                             i++;       
                     }
                    
                     for(int j = 0; j < i; j++) {
                             printf(" %s %s %s \n", stus[j].sno,stus[j].sname,stus[j].ssex);
                     }
    The problem is, you're storing pointers to the SAME str buffer for all your input (so basically last one wins).

    You should have char arrays in your struct (or call malloc), so you make a COPY of the data as you parse it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    There might be multiple reasons why it keeps going, including blank lines at the end of the file...

    You would be smarter to check strlen() on your str buffer and NULL in your fgets loop.

    Code:
    while(fgets(str,15,fp) !=NULL)
      { if (strlen(str) > 3)    // ignore blank lines
           { // extract data } }
    But there are a couple of other things...

    1) Your char array is defined as str[15] but you are allowing 20 characters for fgets() this can lead to array bounds overruns causing unpredictable behavior.

    2) It would be much simpler (and cleaner) to use sscanf() to extract the data and you could check the return of sscanf() to find out how many conversions were made, as a means of error trapping.

    3) You can eliminate the else clause from your first if statement. If the file fails to open the exit() function will prevent the remainder of the code from executing.

    4) The for() and printf() loop probably should not be in the else clause of your first if statement.

    5) As already pointed out this is not a good place to use pointers in structs... Your stu struct should look like this...
    Code:
    struct stu {
          int sno;
          char sname[15];
          char  sex[5];
    };
    You can then write directly to the struct with sscanf().
    Last edited by CommonTater; 06-18-2011 at 11:37 PM.

  6. #6
    Registered User
    Join Date
    Jun 2011
    Posts
    5
    Thank you very much!

  7. #7
    Registered User
    Join Date
    Jun 2011
    Posts
    5
    Code:
    #include "stdio.h"
    #include "string.h"
    #include "stdlib.h"
    struct stu {
          char *sno;
          char *sname;
          char  *sex;
    };
    struct arry{
         char str[15];
    }a[15];
    
    void main() {
             FILE *fp;
             struct stu stus[100];
            int i = 0;
             if((fp = fopen("d:\\student.txt","rt+")) == NULL) {
                     printf("Cannot open the file!");
                     exit(1);
             } else {   
                     while(fgets(a[i].str,20,fp) !=NULL)
                   {
                             stus[i].sno = strtok(a[i].str,",");
                             stus[i].sname = strtok( NULL, "," );
                             stus[i].sex = strtok( NULL, "," );
                             printf("%s %s %s\n", stus[i].sno,stus[i].sname,stus[i].sex);
                             i++;       
                     }
                    
                     for(int j = 0; j < i; j++) {
                             printf(" %s %s %s \n", stus[j].sno,stus[j].sname,stus[j].sex);
                     }
             }        
    }
    Is that right?

  8. #8
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by from_china View Post

    Is that right?
    No...

    Code:
    #include "stdio.h"
    #include "string.h"
    #include "stdlib.h"
    struct stu {
          int sno;    
          char sname[15]; 
          char sex[5];   
    };
    
    struct arry{               <--- lose this part entirely     
    char str[15];
    }a[15];
    
    
    int main (void)
    {   
             FILE *fp;
             struct stu stus[100];
              char buff[21];           <---- add this
            int i = 0;
             if((fp = fopen("d:\\student.txt","rt+")) == NULL) {
                     printf("Cannot open the file!");
                     exit(1); }
    
             while(fgets(buff,20,fp) != NULL)
                {
                 sscanf(buff,"%d,%14s,%4s",&stus[i].sno,stus[i].sname,stus[i].sex);                        
    
                  printf("%s %s %s\n", stus[i].sno,stus[i].sname,stus[i].sex);
                  i++;       
                }
                    
             for(int j = 0; j < i; j++) {
                printf(" %s %s %s \n", stus[j].sno,stus[j].sname,stus[j].sex);
             
       return 0;}
    Last edited by CommonTater; 06-19-2011 at 12:10 AM.

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well it's an interesting approach to say the least.

    But you need to make some numbers the same. I suggest some #define constants.

    Code:
    struct arry{
         char str[15];
    }a[15];
    
    void main() {
             FILE *fp;
             struct stu stus[100];
            int i = 0;
             if((fp = fopen("d:\\student.txt","rt+")) == NULL) {
                     printf("Cannot open the file!");
                     exit(1);
             } else {   
    // should be                 while(i < 15 && fgets(a[i].str,20,fp) !=NULL)
                     while(fgets(a[i].str,20,fp) !=NULL)
                   {
                             stus[i].sno = strtok(a[i].str,",");
                             stus[i].sname = strtok( NULL, "," );
                             stus[i].sex = strtok( NULL, "," );
                             printf("%s %s %s\n", stus[i].sno,stus[i].sname,stus[i].sex);
                             i++;       
                     }
                    
                     for(int j = 0; j < i; j++) {
                             printf(" %s %s %s \n", stus[j].sno,stus[j].sname,stus[j].sex);
                     }
             }        
    }
    The red numbers should be the same, and so should the blue numbers.

    And main should return int, not void (see the FAQ)
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    Jun 2011
    Posts
    5
    Thank you!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. can't find error(s) in my program..help?
    By jennyt in forum C Programming
    Replies: 1
    Last Post: 11-23-2010, 08:11 PM
  2. Cant Find Error
    By Toonzaka in forum C Programming
    Replies: 3
    Last Post: 08-10-2008, 02:00 PM
  3. Need Help to Find the Error in this program
    By sangken in forum C Programming
    Replies: 7
    Last Post: 10-03-2006, 06:12 PM
  4. Please find an error in my noob program
    By alexpos in forum C Programming
    Replies: 2
    Last Post: 10-23-2005, 02:55 PM
  5. Math Equation Program (I can't find the problem with my program!)
    By masked_blueberr in forum C Programming
    Replies: 14
    Last Post: 07-06-2005, 11:53 AM

Tags for this Thread