Thread: Something wrong with output

  1. #1
    Registered User
    Join Date
    Apr 2009
    Posts
    33

    Something wrong with output

    Hi all. I'm a beginner in C so please bear with my noobness.

    My code outputs characters like these when I run my program: ◄úÄ┬» even when it's supposed to output readable strings...

    To illustrate here are sample inputs and outputs:

    Example inputs

    ENTER STUDENT ID :123456789
    ENTER NAME: huh whatever
    ENTER SCORE: 0
    ENTER COURSE : phd

    ENTER STUDENT ID :987654321
    ENTER NAME: meh whatever
    ENTER SCORE: 1
    ENTER COURSE : phd


    The output's fine if only the first record is entered / modified. But once I add the 2nd record and try to modify it, the output suddenly becomes wrong.

    An example modification

    Change this:
    Code:
    STUDENT ID          NAME                       SCORE                COURSE
     
    987654321           meh whatever                1                    phd
    To this:

    Code:
    STUDENT ID          NAME                       SCORE               COURSE 
    
    111111111           lalala whatever            100                 phd

    Example output after modification

    Code:
    STUDENT ID        NAME                        SCORE               COURSE 
    
    123456789         huh whatever                 0                   phd
    3543143           ±╟ìú┬Yever                   31                  54

    I wonder why the output's like this. I think the problem has something to do with the fseek function I used? Please help me.

    Here's my code for adding one record:

    Code:
    void add_record() 
    {
    
       record stud;
       char ch;
       FILE *fp;
       
       fp=fopen("std.dat","r+");
       if(fp==NULL)
            fp=fopen("std.dat","w");
    
        clrscr();
        gotoxy(35,1);printf("\n\nADD RECORD\n\n");
    
        do
        {
            printf("\nStudent ID  = ");
            scanf("%lld", &stud.sid);
            printf("\nName          = ");
            scanf("%s", &stud.name);
            printf("\nScore          = ");
            scanf("%s", &stud.score);
            printf("\nCourse        = ");
            scanf("%s", &stud.course);
    
            fseek(fp,0,SEEK_END);
            fwrite(&stud,sizeof(stud),1,fp);
    
            printf("\n\nAdd another record? Y if yes\n\n");
            ch=toupper(getche());
    
        } while(ch=='Y');
    
        fclose(fp);
        getch();
    }
    Displaying all records:


    Code:
    void display_all() 
    {
       record stud;
       FILE *fp;
       fp=fopen("std.dat","r+");
       if(fp==NULL)
            fp=fopen("std.dat","w");
    
        clrscr();
        printf("STUDENT ID\t%-16s%-12s%-12s\n\n","NAME","SCORE", "COURSE  ");
    
        while(fread( &stud,sizeof(stud),1,fp))
        {
            printf("%lld\t", stud.sid);
            printf("%-16s", stud.name);
            printf("%-12s", stud.score);
            printf("%-12s\n", stud.course);
        }
    
        fseek(fp,0,SEEK_END);
        printf("\n\nPress any key to go back to menu.");
    
        getch();
    
    }
    Modifying one record:

    Code:
    void modify_record() 
    {
       record stud;
       long long int sid;
       int i=0;
       int j=0;
       int x=0;
       FILE *fp;
       fp=fopen("std.dat","r+");
       if(fp==NULL)
            fp=fopen("std.dat","w");
    
    
        clrscr();
        gotoxy(35,2);printf("\n\nMODIFY STUDENT RECORD."); 
        printf("Enter student ID    = ");
        scanf("%lld", &sid);
    
    
    
        while(fread(&stud,sizeof(stud),1,fp))
        {
            i++;
            if(sid==stud.sid)
            {
                x++;
                j=i-1;
                printf("\n\n\n\nORIGINAL RECORD:\n");
                printf("\nStudent ID      =  %lld", stud.sid);
                printf("\nName              =  %s,", stud.name);
                printf("\nScore              =  %d", stud.score);
                printf("\nCourse            =  %s", stud.course);
    
                fseek(fp,sizeof(stud)*j,SEEK_SET);
    
                printf("\n\n\n\nENTER NEW RECORD...\n");
    
                printf("\nStudent ID  = ");
                scanf("%lld", &stud.sid);
                printf("\nName          = ");
                scanf("%s", &stud.name);
                printf("\nScore          = ");
                scanf("%s", &stud.score);
                printf("\nCourse        = ");
                scanf("%s", &stud.course);
    
    
                fwrite(&stud,sizeof(stud),1,fp);
                printf("\n\nRecord successfully modified!");
                getch();
            }
    
            fseek(fp,sizeof(stud)*i,SEEK_SET);
    
        }
        if(x==0)
        {
            printf("\n\nNo record found...");
            getch();
        }
    
        fclose(fp);
    }

    Thanks for any help...
    Last edited by preeengles; 04-14-2009 at 10:54 AM.

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    You have j as an int in modify_record, and fseek() usually expects a long int. Is it possible that j is overflowing?

  3. #3
    Registered User
    Join Date
    Apr 2009
    Posts
    33
    Really? I didn't know that. Please care to elaborate...

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Your j variable will overflow if the file becomes large, but I believe your problem is just with your scanf() on student name.

    Remove the & in front of sudent.name.

    Student.name is an array of char, so the name is the address of the base of the array. So you're getting the address of the address, there.

  5. #5
    Registered User
    Join Date
    Apr 2009
    Posts
    33
    I tried what you suggested and removed &, but this didn't do much difference.

    I was experimenting with my code a while ago and here's what I got (I've decided to place the full code for you to have a clearer view of my code. Though it's quite long, you'll be able to run and test it):

    Code:
     // long code erased
    I'm thinking maybe the problem has something to do with the garbage characters that were included when the file was read. Or maybe it's all because of the fseek or something (maybe it has limitations? or maybe it was misplaced?). Also, maybe I used the wrong mode in reading & rewriting the file. But I tried correcting these already with the little knowledge I have but it turns out that in every attempt, I only make the bug even worse. Maybe I'm not doing it right? Or maybe something's wrong with my compiler. Because as I have noticed, it has a lot of inconsistencies (such as when I run my code one time and it works fine, and when I rerun it, something goes wrong out of the blue). I'm using Turbo C++ IDE, by the way (I don't know which version this is exactly but seems like a primitive version).
    Last edited by preeengles; 04-14-2009 at 06:38 PM.

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Here's an idea, cut about 1000 lines out of your problem, then come back and post a small sample. Very few people will take the time to read that entire thing just to help you with an issue, especially since we don't even have whatever data file you're pulling from in the first place.


    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Registered User
    Join Date
    Apr 2009
    Posts
    33
    Lol...sorry for posting such a long code...I was already sleepy at that time I simply copy-pasted the whole thing.

    Anyway, how about this?


    Code:
    #include<conio.h>
    #include<stdio.h>
    #include<ctype.h>
    #include<string.h>
    #include<stdlib.h>
    
    /****************************************************************************/
    
    typedef struct student
      {
      long long int snum;
      char password[50];
      char fname[31];
      char lname[31];
      char mi[3];
      char bday[7];
      char course[6];
      }record;
    
    /****************************************************************************/
    
    //DECLARATION OF MAJOR FUNCTIONS
    
    void add_record();
    void disp_all();
    void modifySR();
    void delSR();
    void delAll();
    
    
    /***************************************************************************/
    
    //MAIN
    
    int main()
    {
       FILE* fp;
       int menu_choice;
       record stud;
       
     
    
        
            do
            {
                clrscr();
                printf("\n\nADMIN MENU:\n\n");
                printf("\n1 -  Add student record\n");
                printf("\n2 -  Display all entries\n");
                printf("\n3 -  Modify student record\n");
                printf("\n4 -  Delete student record\n");
    	    printf("\n5 -  Delete all entries\n");
    	    printf("\n6 -  Log-out and Exit\n");
                printf("\nEnter Choice: ");
                scanf("%d", &menu_choice);
                if(menu_choice==1) {add_record();}
                if(menu_choice==2) {disp_all();}
                if(menu_choice==3) {modifySR();}
                if(menu_choice==4) {delSR();}
    	    if(menu_choice==5) {delAll();}
    	    if(menu_choice==6) {clrscr(); printf("\n\n\nThank you for using SRMS! GoodBye!");}
           }while(menu_choice!=6);
    
          getch();
       return 0;
    }
    
    /***************************************************************************/
    
    void add_record() 
    {
    
       record stud;
       char ch;
       FILE *fp;
       fp=fopen("std.dat","r+");
       if(fp==NULL)
            fp=fopen("std.dat","w");
    
        clrscr();
        printf("\n\nADD STUDENT RECORD\n\n");
    
        do
        {
            printf("\n\nStudent number (must be 9 digits) = ");
            scanf("%lld", &stud.snum);
            printf("\nPassword                          = ");
            scanf("%s", &stud.password);
            printf("\nLast name                         = ");
            scanf("%s", &stud.lname);
            printf("\nFirst name                        = ");
            scanf("%s", &stud.fname);
            printf("\nMiddle initial                    = ");
            scanf("%s", &stud.mi);
            printf("\nBirthdate (MMDDYY)                = ");
            scanf("%s", &stud.bday);
            printf("\nCourse (ex.BSM)                   = ");
            scanf("%s", &stud.course);
    
            fseek(fp,0,SEEK_END);
            fwrite(&stud,sizeof(stud),1,fp);
    
            printf("\n\nAdd another record? Y if yes\n\n");
            ch=toupper(getche());
    
        } while(ch=='Y');
    
        fclose(fp);
        getch();
    }
    
    /***************************************************************************/
    
    void disp_all() 
    {
       record stud;
       FILE *fp;
       fp=fopen("std.dat","r+");
       if(fp==NULL)
            fp=fopen("std.dat","w");
    
        clrscr();
        printf("STUDENT#\t%-16s%-16s%-12s%-12s%-12s\n\n","LAST NAME","FIRST NAME","MI","BDAY", "COURSE  ");
    
        while(fread( &stud,sizeof(stud),1,fp))
        {
            printf("%lld\t", stud.snum);
            printf("%-16s", stud.lname);
            printf("%-16s", stud.fname);
            printf("%-12s", stud.mi);
            printf("%-12s", stud.bday);
            printf("%-12s\n", stud.course);
        }
    
        fseek(fp,0,SEEK_END);
        printf("\n\nPress any key to go back to menu.");
    
        getch();
    
    }
    
    /****************************************************************************/
    
    void modifySR() 
    {
       record stud;
       long long int snum;
       int i=0;
       int j=0;
       int x=0;
       FILE *fp;
       fp=fopen("std.dat","r+");
       if(fp==NULL)
            fp=fopen("std.dat","w");
    
    
        clrscr();
        gotoxy(35,2);printf("\n\nMODIFY STUDENT RECORD. Enter student to be modified.\n\n");
        printf("Enter student number    = ");
        scanf("%lld", &snum);
    
    
    
        while(fread(&stud,sizeof(stud),1,fp))
        {
            i++;
            if(snum==stud.snum)
            {
                x++;
                j=i-1;
                printf("\n\n\n\nORIGINAL RECORD:\n");
                printf("\nStudent number    =  %lld", stud.snum);
                printf("\nPassword          =  %s", stud.password);
                printf("\nName              =  %s, %s %s", stud.lname, stud.fname, stud.mi);
                printf("\nBirthdate         =  %s", stud.bday);
                printf("\nCourse            =  %s", stud.course);
    
                fseek(fp,sizeof(stud)*j,SEEK_SET);
    
                printf("\n\n\n\nENTER NEW RECORD...\n");
    
                printf("\nStudent number    =  ");
                scanf("%lld", &stud.snum);
                printf("\nPassword          =  ");
                scanf("%s", &stud.password);
                printf("\nLast name         =  ");
                scanf("%s", &stud.lname);
                printf("\nFirst name        =  ");
                scanf("%s", &stud.fname);
                printf("\nMiddle initial    =  ");
                scanf("%s", &stud.mi);
                printf("\nBirthdate         =  ");
                scanf("%s", &stud.bday);
                printf("\nCourse            =  ");
                scanf("%s", &stud.course);
    
                fwrite(&stud,sizeof(stud),1,fp);
                printf("\n\nRecord modified...");
                getch();
            }
    
            fseek(fp,sizeof(stud)*i,SEEK_SET);
    
        }
        if(x==0)
        {
            printf("\n\nNo record found...");
            getch();
        }
    
        fclose(fp);
    }
    
    /***************************************************************************/
    
    void delSR()
    
    {
        record stud;
        int q=0, ch, i, j=0;
        int sz;
        int tot_rec;
        long long int snum;
        char password[50];
        char fname[31];
        char lname[31];
        char mi[3];
        char bday[7];
        char course[6];
        long long int snum1;
        char password1[50];
        char fname1[31];
        char lname1[31];
        char mi1[3];
        char bday1[7];
        char course1[6];
        long long int num;
        FILE *fp,*fp1;
    
            fp=fopen("std.dat","r+");
            if(fp==NULL)
                fp=fopen("std.dat","w");
    
            fp1=fopen("new.dat","r+");
            if(fp1==NULL)
                fp1=fopen("new.dat","w");
    
        clrscr();
        gotoxy(35,2);printf("\n\nDELETE STUDENT RECORD. Enter student to be deleted.");
        printf("\n\nStudent number   = ");
        scanf("%lld", &num);
    
    
        while( fread (&stud,sizeof(stud),1,fp) )
        {
            q++;
            if(num==stud.snum)
            {
                j++;
                fseek(fp,sizeof(stud)*(q-1),SEEK_SET);
    
                printf("\n\nStudent found: \n\n");
    
                fread( &stud,sizeof(stud),1,fp);
    
                printf("\nStudent number    =  %lld", stud.snum);
                printf("\nPassword          =  %s", stud.password);
                printf("\nName              =  %s, %s %s", stud.lname, stud.fname, stud.mi);
                printf("\nBirthdate         =  %s", stud.bday);
                printf("\nCourse            =  %s", stud.course);
    
    
                printf("\n\n\nAre you sure you want to delete the above student record(s)? Y if yes\n\n");
                ch=toupper(getche());
    
                if(ch=='Y')
                {
                    fseek(fp,0,SEEK_END);
                    sz = ftell(fp);
                    tot_rec = sz/(sizeof(stud));
    
                    rewind(fp);
    
                    for(i=0;i<(q-1);i++)
                    {
    
                        fread( &stud,sizeof(stud),1,fp);
                        snum = stud.snum;
                        strcpy(password,stud.password);
                        strcpy(lname,stud.lname);
                        strcpy(fname,stud.fname);
                        strcpy(mi,stud.mi);
                        strcpy(bday,stud.bday);
                        strcpy(course,stud.course);
    
                        stud.snum = snum;
                        strcpy(stud.password,password);
                        strcpy(stud.lname,lname);
                        strcpy(stud.fname,fname);
                        strcpy(stud.mi,mi);
                        strcpy(stud.bday,bday);
                        strcpy(stud.course,course);
                        fwrite(&stud,sizeof(stud),1,fp1);
                    }
    
                    fseek(fp,sizeof(stud)*(q),SEEK_SET);
    
                    for( i=q;i<tot_rec;i++)
    
                    {
    
                        fread( &stud,sizeof(stud),1,fp);
                        snum1 = stud.snum;
                        strcpy(password1,stud.password);
                        strcpy(lname1,stud.lname);
                        strcpy(fname1,stud.fname);
                        strcpy(mi1,stud.mi);
                        strcpy(bday1,stud.bday);
                        strcpy(course1,stud.course);
    
                        stud.snum = snum1;
                        strcpy(stud.password,password1);
                        strcpy(stud.lname,lname1);
                        strcpy(stud.fname,fname1);
                        strcpy(stud.mi,mi1);
                        strcpy(stud.bday,bday1);
                        strcpy(stud.course,course1);
    
                        fwrite(&stud,sizeof(stud),1,fp1);
    
                    }
    
                    printf("\n\nStudent record deleted... ");
    
                    rewind(fp1);
    
                    remove("std.dat");
                    rename("new.dat","std.dat");
                    getch();
    
                }
    
                else
                {
                    printf("\n\nNo Record Deleted...");
                    getch();
                }
            }
    
        }
    
        if(j==0)
        {
            printf("\n\nNo Record Found...");
        }
        getch();
    
    
    }
    
    /****************************************************************************/
    
    void delAll()
    {
        record stud;
        char ch;
    
        FILE *fp,*fp1;
    
            fp=fopen("std.dat","r+");
            if(fp==NULL)
                fp=fopen("std.dat","w");
    
            fp1=fopen("new.dat","r+");
            if(fp1==NULL)
                fp1=fopen("new.dat","w");
    
    
        clrscr();
        printf("\n\nAre you sure you want to delete all student records?\n\n");
        ch=toupper(getche());
    
        if(ch == 'Y')
        {
            remove("std.dat");
            rename("new.dat","std.dat");
            printf("\n\nAll student records deleted...");
            getch();
    
        }
    
        else
        {
            printf("Press any key to go back to menu.");
            getch();
        }
    
    
    }
    
    /****************************************************************************/
    Last edited by preeengles; 04-14-2009 at 06:49 PM.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Yes, fseek() has limitations. The first one is the offset (the middle parameter), which I mentioned previously. Turbo C++ IDE is what I use a lot, and I have an early version (1.01). The 16 bit integers overflow at 32,568, which isn't very many bytes on files, these days.

    Make j an unsigned long, (or maybe a long long), and you should be ok on that part.

    It's not the compiler - it's your code. It has "undefined behavior" because you have references to memory that are beyond the proper bounds.

    I have felt the same way (that it was the compiler messing up, but in every case, it was just my program).

    I appreciate having the whole program, and knowing the compiler helps a lot, also.

    I'll run your program through it's paces, and see what shakes out. Your code is well styled and easy to read. If it wasn't, and appears "logical", if I may use that term. I wouldn't bother with it, otherwise.

  9. #9
    Registered User
    Join Date
    Apr 2009
    Posts
    33
    Quote Originally Posted by Adak View Post
    Yes, fseek() has limitations. The first one is the offset (the middle parameter), which I mentioned previously. Turbo C++ IDE is what I use a lot, and I have an early version (1.01). The 16 bit integers overflow at 32,568, which isn't very many bytes on files, these days.

    Make j an unsigned long, (or maybe a long long), and you should be ok on that part.

    It's not the compiler - it's your code. It has "undefined behavior" because you have references to memory that are beyond the proper bounds.

    I have felt the same way (that it was the compiler messing up, but in every case, it was just my program).

    I appreciate having the whole program, and knowing the compiler helps a lot, also.

    I'll run your program through it's paces, and see what shakes out. Your code is well styled and easy to read. If it wasn't, and appears "logical", if I may use that term. I wouldn't bother with it, otherwise.
    Haha...and I thought the compiler was at fault. I probably just got too frustrated. Thanks so much for the help. I really, really appreciate it! *bows*

  10. #10
    Registered User
    Join Date
    Apr 2009
    Posts
    33
    Alright. I changed j. It didn't seem to affect anything. So I changed the other values that were included in the fseeks I used (such as i and q). But that didn't make any difference still.

    It seems like the problem is, the program can only read the 1st input right. All other inputs are read wrong (or so it seems).The example on my 1st post proves this.

    I wonder what the root-cause of this is...I know this is just a teeny bit of a problem, I just can't figure it out.

    Any ideas anyone?

  11. #11
    Registered User
    Join Date
    Apr 2009
    Posts
    33
    Quote Originally Posted by quzah View Post
    Here's an idea, cut about 1000 lines out of your problem, then come back and post a small sample. Very few people will take the time to read that entire thing just to help you with an issue, especially since we don't even have whatever data file you're pulling from in the first place.


    Quzah.
    I know my code's quite long (even when I've cut like 200 lines from it already), but I thought that if I gave you only a very small part of my code, you wouldn't see the other bugs I might've overlooked myself. It would be helpful if others tested it and see what else was wrong. It's like, seeing the bigger picture of my program.

    Also, the user of the program is the one who adds contents to the data file. You will automatically have the data file once you run the program.
    Last edited by preeengles; 04-14-2009 at 07:28 PM.

  12. #12
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Anytime you're dealing with strings and you get:
    My code outputs characters like these when I run my program: ◄úÄ┬» even when it's supposed to output readable strings...
    It means you've forgotten to include a null character some place. In other words, your string really isn't a string. (Or, you're using memory you haven't properly allocated, in which case, like the former, expect a crash sooner or later.)

    Instead of including loads of code, it's best to take the one item you think is the problem, and make a test program for it. Having problems writing to a disk? Make a quick little program that simply writes out your structure the way you want it. Now that you've got that function done, move to the next problem. Having problems reading? Make a small program that reads from disk. Having a problem displaying information? Make a function that takes just one structure, and displays it.

    Now take one of those functions you've made, and mix it with one of the others. How about displaying what you read?

    The point is, you don't really need all of those menu options and such to test where you think the problem is. Unless of course you think that's the problem, in which case, make a small menu program that just displays the choice you've made, and test it.


    Quzah.
    Hope is the first step on the road to disappointment.

  13. #13
    Registered User
    Join Date
    Apr 2009
    Posts
    33
    @Adak: Yeah, maybe your hypotheses is right regarding the overflow (I didn't understand what you meant at first but I looked it up and it seems to be the only likely cause of my problem).

    Also, I had someone check my code, and he said that my code works just fine when he compiled and ran it on a Unix system. I'm not well-versed regarding overflows but I'm thinking maybe I'm putting too much data on my struct. I tried putting only 3 data in it and the program didn't crash. But I want to insist on putting 7 data in it. Aside from the tip you gave on changing j to unsigned long/long long, what other counter-measures could you suggest to avoid this overflow? Please give me a hint. I just don't get this.

    Thanks again.

  14. #14
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Oh, and you have more fields in your structure than your sample input provides for.


    Quzah.
    Hope is the first step on the road to disappointment.

  15. #15
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I added two records to the program, and immediately had a problem - the display would find and show the student, but I could not modify that record. It told me "no record found".

    I see that several of your entries are scanf("%s", etc.). Then I noticed that the major I had entered was "sociology", and that overflowed the field.

    Then the program crashed upon trying to exit.

    So I would go through the add record function and allow only a maximum length of 1 less than the length of the field it is to fit into. That will leave a space for the end of string char: '\0', to be placed there.

    For a field width of 8 char's then:
    scanf("%7s", someCharArrayField);

    That should solve a lot of your problems, if not all of them.

    Come back if you have any more. I'll wait until I have that code to try and sort out anything else.

    That's a good point - you can't leave fields empty - fill them with '\0''s if they're strings, or 0's if they're numbers, perhaps when they're created is best so you won't forget or have to code something special to do that.
    Last edited by Adak; 04-14-2009 at 08:53 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Wrong Output!
    By kolliash in forum C++ Programming
    Replies: 6
    Last Post: 06-19-2008, 07:55 AM
  2. Something Wrong with my function in Linux!
    By Matus in forum C Programming
    Replies: 5
    Last Post: 04-30-2008, 10:00 PM
  3. Getting wrong output from a class
    By orikon in forum C++ Programming
    Replies: 11
    Last Post: 11-18-2005, 07:58 PM
  4. Why is the output of this wrong?
    By Tokimasa in forum C++ Programming
    Replies: 4
    Last Post: 11-30-2004, 01:58 PM
  5. Leap year program prints wrong output
    By Guti14 in forum C Programming
    Replies: 8
    Last Post: 08-24-2004, 11:56 AM