Thread: Help reading file streams

  1. #1
    Registered User
    Join Date
    May 2010
    Posts
    13

    Help reading file streams

    I would appreciate some help with reading input input file streams into data structure.

    First, so that I can demonstrate that I understand the basics of reading input file streams I present a code fragment that reads the following file into an array and prints the array:

    grades.txt:

    Code:
    91, 92, 85, 58, 87, 75, 89, 97, 79, 65, 88, 72, 81, 94, 90, 61, 72, 75, 68, 
    77, 75, 49, 87, 79, 65, 64, 62, 51, 44, 70, 81, 72, 85, 78, 77, 75, 79, 87, 69,
    55, 88, 62, 71, 74, 80, 71, 62, 85,68, 87, 75, 89, 97, 79, 65, 48, 72, 61, 64, 90
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define STU_ROWS 5
    #define GRD_COLS 12
    
    int main (void)
    {
        //Local declarations
        int stuGrdAry[STU_ROWS][GRD_COLS]
    
        spStuGrds = fopen("grade.txt", "r");
    
        if ((spStuGrds = fopen("grades.txt", "r")) == NULL)
            {
                printf("Error in opening input file");
                exit(101);
            }
    
            for (stuRow = 0; stuRow < STU_ROWS; stuRow++)
                {
                    for (grdCol = 0; grdCol < GRD_COLS; grdCol++)
                        {
                          fscanf(spStuGrds, "%d%*c ", &stuGrdAry[stuRow][grdCol]);
                        }
                }
    
            for (stuRow = 0; stuRow < STU_ROWS; stuRow++)
                {
                    for (grdCol = 0; grdCol < GRD_COLS; grdCol++)
                        {
                          printf("%d ", stuGrdAry[stuRow][grdCol]);
                        }
                    printf("\n");
                }
    }
    I know this code works both because I have used it successfully as part of a larger program and because I have compiled and run it on its own and gotten the desired output.

    Now, I am trying to write a program that takes a more heavily formatted file and reads it into a structure and prints the structure:

    grade_struct.txt:

    Code:
    Student 1:   91, 92, 85, 68, 87, 75, 89, 97, 79, 65, 88, 72, 81, 94, 90
     Student 2:   61, 72, 75, 68, 77, 75, 69, 87, 79, 65, 64, 62, 51, 44, 70
     Student 3:   81, 72, 85, 78, 77, 75, 79, 87, 69, 55, 88, 82, 71, 74, 80
     Student 4:   71, 62, 85, 88, 87, 75, 89, 97, 79, 65, 88, 72, 61, 64, 90
     Student 5:   90, 52, 75, 68, 77, 85, 59, 87, 79, 65, 88, 72, 81, 90, 91
     Student 6:   51, 52, 55, 58, 67, 75, 69, 97, 99, 85, 88, 72, 81, 94, 90
     Student 7:   45, 62, 75, 68, 77, 75, 89, 67, 69, 65, 88, 72, 81, 84, 80
     Student 8:   56, 52, 85, 78, 87, 74, 79, 97, 79, 65, 68, 72, 84, 94, 70
     Student 9:   77, 42, 55, 88, 57, 75, 80, 67, 79, 65, 88, 73, 81, 91, 95
     Student 10:  57, 92, 85, 78, 81, 85, 84, 97, 79, 85, 58, 72, 81, 74, 70
     Student 11:  92, 95, 85, 98, 87, 75, 89, 97, 79, 69, 88, 72, 81, 94, 90
     Student 12:  91, 92, 85, 98, 87, 78, 89, 97, 79, 86, 88, 72, 81, 94, 96
    Code:
    #include <stdio.h> 
    #include <stdlib.h>
    
    #define STU_NUM_MAX 11
    #define STU_STRUCT_ROWS 12
    #define GRD_ARY_COLS 15
    
    typedef struct
    {
        char stuNumStr[STU_NUM_MAX];
        int  stuGrdAry[GRD_ARY_COLS];
    } STUDENT;
    
    int main (void)
    {
        int stuStructRow;
        int stuNumChr;
        int grdAryCol;
        FILE* spStuGrds;
    
        spStuGrds = fopen("grade_struct.txt", "r");
        if ((spStuGrds = fopen("grade_struct.txt", "r")) == NULL)
            {
                printf("Error in opening input file");
                exit(101);
            }
    
        while (fgetc(spStuGrds) != EOF)
              {
                for (stuStructRow = 0; stuStructRow < STU_STRUCT_ROWS; stuStructRow++)
                    {
                         for(stuNumChr = 0; stuNumChr < STU_NUM_MAX && fgetc(spStuGrds)!= ':'; stuNumChr++)
                            {
                                fscanf(spStuGrds, "%c", stuStructAry[stuStructRow].stuNumStr[stuNumChr]);
                            }
                         fscanf(spStuGrds, "%*c");
        
                         for (grdAryCol = 0; grdAryCol < GRD_ARY_COLS; grdAryCol++)
                             {
                                 fscanf(spStuGrds, " %d%*c ", stuStructAry[stuStructRow].stuGrdAry[grdAryCol]);
                             }
                    }
             }
        For (stuStructRow = 0; stuStructRow < STU_STRUCT_ROWS; stuStructRow++)
            {
                 printf("%s", &stuStructAry[stuStructRow].stuNumStr);
                 for (grdAryCol = 0; grdAryCol < GRD_ARY_COLS; grdAryCol++)
                     {
                          printf(" %d%*c ", &stuStructAry[stuStructRow].stuGrdAry[grdAryCol]);
                     }
            }
    }
    Basically, I want to read the 11- or 12-character sequence, "Student X(X)", into a string while suppressing the colon and each integer after that into an array of integers. In previous versions of this code, I seemed to be having trouble getting the characters all read into the string properly because, after performing sums and averages on the integer array I would sometimes get negative number. Now, Windows just send me its standard "(blank).exe has encountered a problem" error message and terminates the program's execution.

    I have tried several things but didn't notice any appreciable difference in the output . First, I tried scanf("%s%*c ", stuStructAry[stuStructRow].stuNumStr);. I now understand that it didn't work, because the %s conversion specifier stops after it encounters whitespace, so I was essentially scanning "Student" into the string, suppressing the space, and scanning the student's number in to first element in the integer array. For that same reason, any statement containing the %s conversion specifier won't read the string as I want it to be read, so I have tried reading it as an undelimited character sequence, but by that time, Windows had started terminating my programs, so I am not sure how the out put might have actually differed.

    Any help would be very much appreciate.
    Last edited by mjpam; 05-13-2010 at 04:27 PM.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You can put literal characters in your format strings if you know they are there. An outrageously outrageous example:
    Code:
    fscanf(spStuGrds, "Student %*d:"); /* suck in the header and ignore it*/

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can you help me about tolower() in file
    By nctar in forum C Programming
    Replies: 7
    Last Post: 05-12-2010, 10:04 AM
  2. opening empty file causes access violation
    By trevordunstan in forum C Programming
    Replies: 10
    Last Post: 10-21-2008, 11:19 PM
  3. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 12:36 PM
  4. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM