Thread: Segfault in reading file stream

  1. #1
    Registered User
    Join Date
    Dec 2011
    Posts
    3

    Unhappy Segfault in reading file stream

    For a C++ project, we need to fill in code to play Sudoku. File handling and command input are already in, but we need to write initialization, configuration, output, and adding/erasing values from the board.

    To configure the board, we need to read from an input file that has a structure of:
    Code:
    ###\n
    ###\n
    ###\n        etc.
    where the three #s are integers representing row, column, and value at that point.

    I am trying to use fscanf to fill in the Sudoku grid, yet am running into segmentation faults. I have looked at various resources available to me, including similar topics on this forum, and have yet to work out a solution.

    My code (currently) looks like:
    Code:
    void configure(FILE *puzzle_file) {
    
            int row ;
            int col ;
            int dig ;
    
            while( !feof(puzzle_file) ) {
                    fscanf(puzzle_file, "%d%d%d", &row, &col, &dig) ;
                    puzzle[row][col] = dig ;
                    fixed[row][col] = TRUE ;
            }
    
    }
    Opening the file and the error checking that comes with it is already handled in the code given to me. This is the only method that actually reads the file.

    Any stdio function that reads from the file causes a segfault. I have absolutely no idea what the problem could be, so I need your assistance to identify it.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    How are the arrays puzzle and fixed declared?

    Your use of feof() is wrong
    FAQ > Why it's bad to use feof() to control a loop - Cprogramming.com

    It would be better to have
    while ( fscanf(puzzle_file, "%d%d%d", &row, &col, &dig) == 3 )

    It might be a good idea to check row,col are valid subscripts as well.
    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.

  3. #3
    Registered User
    Join Date
    Dec 2011
    Posts
    3
    The arrays are declared as statics with:

    Code:
    static short puzzle[10][10] ;
    static bool fixed[10][10] ;
    I've changed int to short for dig, and am using %hd instead of %d.

    Reading your comments about the arrays, I looked at commenting out my modifications and the program worked. Printing the values I have for row, col, and dig (now val), I get:
    Code:
    116 157 189
    198 248 253
    262 295 335
    349 351 429
    436 461 492
    537 614 642
    687 724 758
    841 852 863
    913 383 579
    676 765 777
    817 925 959
    and I see that I have erred in my input scanning. Somehow, I am taking
    Code:
    ###
    ###
    ###
    and reading it in as ### = row, ### = col, ### = val, though I don't really understand how this is the case. I'm going to try adding \n to the end of the scan string and see how it works.

    edit: ok, it doesn't actually.
    edit 2: Using the width modifier for my scan specifiers I actually got it working! Thank you for sending me on the right track to figuring out what I needed to do to fix it!
    Code:
    ./sudoku -e p+s/good_puzzle.txt < p+s/script_good_quit.txt
    -------------------------
    | 6     |   7   | 9 8   |
    |       | 8 3 2 |   5   |
    |     5 | 9 1   | 3     |
    -------------------------
    |   9 6 |     1 |   2   |
    |     7 |       |       |
    | 4     | 2     | 7     |
    -------------------------
    |   4   |   8 5 |       |
    | 7     | 1 2 3 |       |
    | 3 5   |   9   |   6   |
    -------------------------
    BAM Though the printing isn't actually working correctly just yet.
    Last edited by brobot; 12-18-2011 at 04:51 AM.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > 116 157 189
    You're reading these as row 116, col 157 and value 189

    You need to read one integer, then use %10 and /10 to extract each digit.

    Or read each field as a string.
    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
    Registered User
    Join Date
    Dec 2011
    Posts
    3
    Yeah I actually got that and fixed it with:
    Code:
    fscanf(puzzle_file, "%1d%1d%1hd", &row, &col, &val)
    Regardless, I now had to check for errors in the input file and read in each field as a string anyway. Lines can have more than 3 characters in them, and I'm supposed to just ignore everything past those first ones.
    Code:
    void configure(FILE *puzzle_file) {
    
            int row = 0 ;
            int col = 0 ;
            short val = 0 ;
    
            char linestr[100] ;
    
            int fline = 1 ;
    
            while( fscanf(puzzle_file, "%s\n", linestr) != EOF ) {
                    row = linestr[0]-48 ; col = linestr[1]-48 ; val = linestr[2]-48 ;
                    if( !in_range(row) || !in_range(col) || !in_range(val) ) {
                            printf("Illegal format in configuration file at line %d\n", fline) ;
                            exit(1) ;
                    }
                    if( puzzle[row][col] != 0 ) {
                            printf("Illegal placement in configuration file at line %d\n", fline) ;
                            exit(1) ;
                    }
                    puzzle[row][col] = val ;
                    fixed[row][col] = TRUE ;
                    fline++ ;
            }
    
            return ;
    
    }
    This works perfectly well. Everything compiles and runs smoothly. Thing is, does checking against EOF work the same as using feof? I assume no, but I can't be sure.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Your fscanf is pretty good actually.
    For that little bit extra, use "%99s" to prevent buffer overruns.

    > if( !in_range(row) || !in_range(col) || !in_range(val) )
    You should probably check that linestr is actually 3 chars long as well.

    Rather than x-48, say x-'0' for readability.
    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. Problem reading from file stream
    By shmitson in forum C Programming
    Replies: 0
    Last Post: 04-05-2011, 04:37 PM
  2. SegFault when reading a file
    By deadpickle in forum C Programming
    Replies: 16
    Last Post: 05-13-2009, 11:05 PM
  3. Reading a txt file into an array: unexpected segfault
    By pistacchio in forum C Programming
    Replies: 3
    Last Post: 05-05-2009, 04:27 PM
  4. help with reading from stream
    By movl0x1 in forum C Programming
    Replies: 7
    Last Post: 05-31-2007, 10:36 PM
  5. IRC, reading the stream
    By Iyouboushi in forum C# Programming
    Replies: 6
    Last Post: 08-03-2006, 05:34 PM