#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    1
    Rep Power
    0

    Why does my fscanf not read?


    I have to write a program that finds a path of maximum value in a triangular maze of integer numbers.

    This program should calculate the highest sum of numbers passed on a route that starts at the top and ends somewhere on the base.
    Each step can go either diagonally down to the left or diagonally down to the right.
    The number of rows in the triangle is > 1 but <= 100.
    The numbers in the triangle, all integers, are between 0 and 99.
    I have a problem with the fscanf function. It doesn't read for some reason. I would highly appreciate any help or advise as this project is due ASAP.

    Here is an example of a maze:

    30

    47 1

    35 65 21

    0 74 94 58

    71 29 34 28 60

    97 6 29 19 26 68

    37 1 48 98 57 89 64

    60 38 33 23 49 57 19 50

    4 83 52 47 84 60 16 56 90

    19 59 6 10 97 47 96 93 59 50

    And this is what I've got so far:

    #include <stdio.h>
    #include <stdlib.h>
    #define MAX 100

    void read (int maze [][MAX]);
    int findPath (int maze[][MAX], int map[][MAX], int size);
    void print (int map [][MAX]);

    int main()
    {
    int maze [][MAX] = {};
    int map [][MAX] = {};

    int sum = 0;
    int size = MAX;

    read (maze);
    findPath (maze, map,size);
    print (map);

    return;
    }

    void read (int maze[][MAX])
    {
    FILE * mazeFile;
    int num, r, c, count;

    if ((mazeFile = fopen ("t4.txt", "r")) == NULL)
    {
    printf ("Error opening a file\n");
    }
    else
    {
    while (mazeFile != EOF)
    {
    fscanf (mazeFile, "%d", &maze[r][c]);

    for (r = 0; r < 100 ; r++)
    {
    count = r + 1;
    for (c = 0; c <= count; c++)
    {
    printf ("(%d, %d) = %d\n",r, c, maze[r][c]);
    }
    }
    fclose (mazeFile);
    return;
    }
    }
    }

    int findPath (int maze[][MAX], int map[][MAX], int size)
    {
    int sum [MAX][MAX] = {0};
    int row, col, maxNum;

    for(row=(size-1); row >= 1; --row)
    {
    for (col-row;col>=1;--col)
    {
    maxNum = (sum[row+1][col] > sum [row+1][col+1] ? col : col + 1);
    sum[row][col]= maze[row][col] + sum [row+1][maxNum];

    map[row][col] = maxNum;
    }
    }
    return sum [0][0];
    }

    void print (int map [][MAX])
    {
    printf ("(%d, %d) = ", map[0][0], map[0][1]);
    return;
    }
  2. #2
  3. Java Junkie
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jan 2004
    Location
    Mobile, Alabama
    Posts
    4,021
    Rep Power
    1285
    I would look at this line.

    Code:
    while (mazeFile != EOF)
  4. #3
  5. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,162
    Rep Power
    2222
    That is an unreadable mess. Use code tags to preserve your code's indenting and thus retain its readability. Here's how your code should look:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define MAX 100
    
    void read    (int maze [][MAX]);
    int findPath (int maze[][MAX], int map[][MAX], int size);
    void print   (int map [][MAX]);
    
    int main()
    {
        int maze [][MAX] = {};
        int map  [][MAX] = {};
    
        int sum = 0;
        int size = MAX;
    
        read     (maze);
        findPath (maze, map,size);
        print    (map);
    
        return;
    }
    
    void read (int maze[][MAX])
    {
        FILE * mazeFile;
        int num, r, c, count;
    
        if ((mazeFile = fopen ("t4.txt", "r")) == NULL)
        {
            printf ("Error opening a file\n");
        }
        else
        {
            while (mazeFile != EOF)
            {        
                fscanf (mazeFile, "%d", &maze[r][c]);
    
                for (r = 0; r < 100 ; r++)
                {
                    count = r + 1;
                    for (c = 0; c <= count; c++)
                    {
                        printf ("(%d, %d) = %d\n",r, c, maze[r][c]);
                    }
                }
                fclose (mazeFile);
                return;
            }
        }
    }
    
    int findPath (int maze[][MAX], int map[][MAX], int size)
    {
        int sum [MAX][MAX] = {0};
        int row, col, maxNum;
    
        for(row=(size-1); row >= 1; --row)
        {
            for (col-row;col>=1;--col)
            {
                maxNum = (sum[row+1][col] > sum [row+1][col+1] ? col : col + 1);
                sum[row][col]= maze[row][col] + sum [row+1][maxNum];
    
                map[row][col] = maxNum;
            }
        }  
        return sum [0][0];
    }
    
    void print (int map [][MAX])
    {
        printf ("(%d, %d) = ", map[0][0], map[0][1]);
        return;
    }
    Why are you trying to run a program that does not compile cleanly? Why are you ignoring warnings? A program that generates warnings cannot be trusted to behave in a predictable manner. You have no idea what such a program is really doing, so your questions and assumptions about what fscanf is doing are all rendered moot. First get your program to compile cleanly, then worry about what it's doing or not doing.

    When I compile your program with MinGW gcc with all warnings turned on, this is what I get:
    C:TEST>gcc -Wall denys01.c
    denys01.c: In function `main':
    denys01.c:21: warning: `return' with no value, in function returning non-void
    denys01.c:14: warning: unused variable `sum'
    denys01.c: In function `read':
    denys01.c:35: warning: comparison between pointer and integer
    denys01.c:27: warning: unused variable `num'
    denys01.c: In function `findPath':
    denys01.c:55: warning: missing braces around initializer
    denys01.c:55: warning: (near initialization for `sum[0]')
    denys01.c:60: warning: statement with no effect

    C:TEST>
    main needs to return an int, not nothing. return 0; to indicate that it ran normally (eg, failure to open an input file would require premature termination, for which you should return a non-zero value to let the system know that the program failed).

    Line 35 is what bullet had spotted:
    while (mazeFile != EOF)
    Here the warning pointed you directly to a line with a problem and described the problem to you: mazeFile is a pointer and EOF is not, so comparing them is not allowed.
    {ABE: look into the function, feof().}

    Line 55: the initialization of sum is somehow malformed. Research that. It seems to have something to do with sum being two-dimensional whereas the initializer list is only one-dimensional.

    Line 60: the for statement is malformed, so it has no effect:
    for (col-row;col>=1;--col)
    I think you might have meant col=row, an equals sign instead of a minus sign. A hard-to-spot typo which the warning pointed you to directly.

    Always turn warnings on and up! Warnings are much more important than error messages. A program does not compile cleanly until it has no warnings. Never run a program that does not compile cleanly.

    PS
    BTW, that was a very nice job of indenting your code. You shouldn't hide that, so use code tags to post your code:

    [code] {paste your code listing here} [/code]

    If you use the advanced editor on this site, there's supposed to be a button to do the same, but I have no knowledge of that. Typing the code tags explicitly always works.
    Last edited by dwise1_aol; May 10th, 2013 at 10:34 AM.
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,162
    Rep Power
    2222
    Also, now that I can read your code (after I retrieved its formatting via the Reply button), I noticed this:
    Code:
            while (mazeFile != EOF)
            {        
                fscanf (mazeFile, "%d", &maze[r][c]);
    
                for (r = 0; r < 100 ; r++)
                {
                    count = r + 1;
                    for (c = 0; c <= count; c++)
                    {
                        printf ("(%d, %d) = %d\n",r, c, maze[r][c]);
                    }
                }
                fclose (mazeFile);
                return;
            }
    When you fscanf that value into maze[r][c], what are the values of r and of c?

    For the first fscanf, neither has been initialized, so they're both garbage, whatever random values had last been written to those locations. As a result, it is very likely that you are writing far outside the bounds of the array, thus clobbering other values which can have either subtle or drastic deliterious effects depending on just what random location you happen to be clobbering. Never use an uninitialized variable, especially not an uninitialized pointer or array index.

    For all subsequent fscanf calls, r is 100 and c is count+1 .

    Also, this is very highly suspect:
    Code:
        int maze [][MAX] = {};
        int map  [][MAX] = {};
    So the first dimension of those arrays are either 0 or 1? That way, you cannot help but to access outside the bounds of the arrays.

    PS
    I spotted what appeared to be a big problem in the while loop of your read function, but then I saw the return statement. If it weren't for that return, then you would have been looping and trying to read from and close yet again a file you had already closed.

    Instead, you only try to read the first number from the file, which because r and c are uninitialized gets written at some random location thus clobbering whatever's there. And since the for loops iterating through the array never look at that random location, you never see the number you read in.

    I do not understand what you are trying to do in that while loop. All I can do is to tell you what it's doing.
    Last edited by dwise1_aol; May 10th, 2013 at 11:41 AM.

IMN logo majestic logo threadwatch logo seochat tools logo