Problems passing files by reference and using fscanf

This is a discussion on Problems passing files by reference and using fscanf within the C Programming forums, part of the General Programming Boards category; I am having some problems with passing a file pointer and fscanf. In gdb I am getting incorrect values after ...

  1. #1
    Registered User
    Join Date
    Mar 2012
    Location
    Tucson, Arizona, United States
    Posts
    9

    Problems passing files by reference and using fscanf

    I am having some problems with passing a file pointer and fscanf. In gdb I am getting incorrect values after the fscanf for both the "scan_friends" and "scan_in" functions.
    The input files are

    people.dat:
    bob 1.00 19 stacy 0.00 20


    friends.dat:
    1.00 0.01


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    typedef struct friend_node_t
    {
            int friend_id;
            struct friend_node_t *next;
    } friend_node_t;
    
    
    
    
    typedef struct
    {
            char name[20];
            float id;
            int age;
            friend_node_t *friend_list;
    } friend_t;
    
    void scan_friends(FILE *inp, friend_node_t *root, friend_t *people)
    {
            int i;
            friend_node_t *counter;
            float  z;
    
    
            counter = root;
    //this is meant to scan in a float wich was the the variables before the decimal specifying the person, and the digits after the decimal specifying the friend of the person.
            while (fscanf(inp, "%.2f", &z)!=EOF )
            {
                    for(i=0;i<20;i++)
                    {
                            if(z/(people->id)>=1 && z/(people->id)<=2)
                            {
    
    
                                    counter->friend_id = (z-(people->id))*100;
                                    counter->next = calloc(sizeof(friend_node_t),1);
                                    counter = counter->next;
                            }
                            else if ((people->id)==0 && z>=0 && z<=1)
                            {
                                     counter->friend_id= z*100;
                                     counter->next = calloc(sizeof(friend_node_t),1);
                                     counter = counter->next;
                            }
    
    
    
    
    
    
                    }
            }
    }
    
    
    //input the data for each person from the file pointed at with inp, and a second function to input the friends each person has using inp1
    void scan_in(FILE *inp, friend_t *people)
    {
            fscanf(inp, "%s %.2f %d", people->name, &people->id, &people->age);
    
    
    }
    int main(void)
    {
    // creating two file pointers and initializing them to the file locations
    FILE *inp;
    
    
            inp = fopen("people.dat", "r");
            if (inp == NULL)
            {printf("The input file does not exist\n");
            return (0);
            }
    FILE *inp1;
    
    
            inp1 = fopen("friends.dat", "r");
            if (inp1 == NULL)
            {printf("The input file does not exist\n");
            return (0);
    
    
    
    
            char input_name;
            int i;
            friend_t person[20];
    
    
            friend_node_t *root[20];
    
    
    //initializing array of root pointers to the first node in person[i].friend_list
            for(i=0; i<20; i++)
            {
                    root[i] = calloc(sizeof(friend_node_t),1);
                    root[i]->next=0;
                    person[i].friend_list = root[i];
            }
    //scannin in person data and friends
            for(i=0; i<2; i++)
            {
                    scan_in(inp, &person[i]);
                    scan_friends(inp1, root[i], &person[i] );
            }
    
    
    
    
    
    
            return(0);
    }

    Thanks!
    Eugene Balaguer

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,443
    Your formatting could use a little work, particularly getting rid of unnecessary blank lines and making sure all your if statements have their subordinate statements indented properly. You could also pick some better variable names, particularly for z, inp and inp1.

    Here's what I get when I try to compile your program:
    Code:
    $ make foo
    gcc -Wall -g -std=c99  -lm -lpthread -lcurses -lefence  foo.c   -o foo
    foo.c: In function ‘scan_friends’:
    foo.c:29: warning: unknown conversion type character ‘.’ in format
    foo.c:29: warning: too many arguments for format
    foo.c: In function ‘scan_in’:
    foo.c:61: warning: unknown conversion type character ‘.’ in format
    foo.c:61: warning: format ‘%d’ expects type ‘int *’, but argument 4 has type ‘float *’
    foo.c:61: warning: too many arguments for format
    foo.c: In function ‘main’:
    foo.c:87: warning: unused variable ‘input_name’
    foo.c:115: error: expected declaration or statement at end of input
    make: *** [foo] Error 1
    For the error on line 115, the compiler is confused because you are missing a closing curly brace somewhere, presumably around line 83.

    For the scanf errors, check the documentation. You can't use the . in the format specifier like you can with printf. Frankly, using a float in a file and separating the integer and fractional parts to get two integers is silly. If it were me, I would pick a different separator, like space or tab (or comma if you're not in a country where comma is the whole/fraction separator). If you can't do that, then just scan two integers: scanf(inp, "%d.%d", &person, &friend);.

    Also, you should check the return values of all your IO functions, not just fopen. Check all the fscanf calls to make sure they worked. You should also check the return value of any malloc/calloc/realloc calls.

    Lastly, close your files when you're done, that means close people.dat and friends.dat. You should also close people.dat if you fail to open friends.dat.

  3. #3
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    two ways to check your input: use fgets to read a line then sscanf to parse it. that will let you see what is really being read from the file. check the return value of fscanf/scanf to see how many values you are actually scanning.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 12-06-2010, 02:18 AM
  2. fscanf problems
    By gambit1414 in forum C Programming
    Replies: 1
    Last Post: 04-12-2009, 01:20 PM
  3. passing ** value to fscanf
    By e_zealot in forum C++ Programming
    Replies: 4
    Last Post: 09-01-2004, 12:24 PM
  4. passing by address vs passing by reference
    By lambs4 in forum C++ Programming
    Replies: 16
    Last Post: 01-09-2003, 12:25 AM
  5. fscanf problems
    By QuincyEQ in forum C Programming
    Replies: 2
    Last Post: 07-29-2002, 03:24 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21