Thread: Help with understanding file pointers

  1. #1
    Registered User
    Join Date
    Jun 2010
    Posts
    21

    Unhappy Help with understanding file pointers

    Hi all,
    I am relatively new at programming in C so forgive me if this question sound a bit idiotic. I have a problem regarding passing file pointers in a program I am writing. So my input is in the following format from a file:
    Code:
    0 3 1 
    0 2 
    0 3 
    0 4 
    1 2 
    1 3 
    1 4 
    2 3 
    2 4 
    3 1 4
    What I want to do is compare each pair of numbers in each line but NOT do comparisons in between lines. What I have right now looks something like this:
    Code:
    void betweeness(int n){
    int a;
    int b;
    char line[LINE_MAX];
    int flag=0;
    char d;
    FILE * fin = fopen("path.txt" ,"r");
    flag=0;//new line flag
    while(fgets(line, LINE_MAX, fin)!=NULL) 
        {
          flag=0;
          fputs ( line, stdout );
          
    while((sscanf(line,"%c",&d)) != '\n')
       {	
          if(flag==0)
          		 {
    		  sscanf(line, "%d %d",&a,&b);
    		  printf("Test one %d %d \n" ,a,b);
    		  betweenmat[a][b]=betweenmat[a][b]+1;
    		  a=b;
    		  flag=1;
    
    		}
          else if(flag==1)
    		{
    		  sscanf(line, "%d", &b);
    		  printf("Test two %d %d \n" ,a,b);
    		  betweenmat[a][b]=betweenmat[a][b]+1;
    		  a=b;
    		}
        
        }}
    fclose(fin);
    FILE * fout = fopen("between.txt" ,"w");
    for (a = 0; a < n; ++a) {
    		  for (b = 0; b < n; ++b)
    		  {
    		    fprintf(fout,"%d to %d :%d \n",a,b, betweenmat[a][b]);
    		  }}
    fclose(fout);
    }
    the program is supposed to get a single line(say 0 3 1) then while the end of the line is not reached, it is supposed to scan the pairs of numbers(say 0 3) and add 1 to the matrix element[0,3]. Thus at the end I am supposed to get a matrix which has the number of times every pair appears.
    The problem in the code is that the pointer line is not moving forward in the second "while" loop. I tried the following things:
    1). using a secondary pointer
    2). moving code around
    3). various getc, scanf,fgets and other functions
    4). blood sacrifice

    but none of them are working and either cause the program to go into an infinite loop(like in the case of the code above). Can someone please either guide me in the right path or help me correct the code. I will be most obliged.
    Cheers!

  2. #2
    Registered User MacNilly's Avatar
    Join Date
    Oct 2005
    Location
    CA, USA
    Posts
    466
    Please post your output.

    Try removing the inner while loop, just read and echo a line to see if you are able to process the file one line at a time. Make sure you're using the right input file, too.

    The problem is that the second while loop doesn't modify the FILE object at all, since you're using SSCANF, not FSCANF.
    Last edited by MacNilly; 06-29-2010 at 04:29 PM.

  3. #3
    Registered User
    Join Date
    Jun 2010
    Posts
    21
    The program is reading the input file just fine because I commented out the while loops and just looked at what the fgets was putting out and it worked perfectly.

    So the output is basically an infinite loop consisting of
    Code:
    Test two 0 0 
    Test two 0 0 
    Test two 0 0 
    Test two 0 0 
    Test two 0 0 
    Test two 0 0 
    Test two 0 0 
    Test two 0 0 
    Test two 0 0
    what I believe the program is doing is reading 0 3 and making a comparison which outputs just fine(cant really show it because the of infinite loop thing). Then what it does it is that it goes up and scans the value and it reads 0 again because the pointer has not moved to 1 which it should have. However now that the flag is set to 1, it only reads the first value 0 AGAIN and saves it to the integer b. This means that both a and b are now 0 with no chance of getting out of the loop. Thus my dilemma about the non-moving pointer.

  4. #4
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Do you have access to a debugger? Sometimes it is instructive to set a breakpoint just before the bit you want to examine, and then step through the code, line by line, examining the values of the variables as you do so.

  5. #5
    Registered User
    Join Date
    Jun 2010
    Posts
    21
    So the debugger(I used GDB, dont know if there is something better) basically told me what I was suspecting. The line pointer is not shifting forward which in 3 steps causes the program to go into an infinite loop. Any one have any ideas?

    I was thinking of creating another array and just copying stuff over and using the pointer from that one, but I doubt this will work. Any C gurus out there who have some jedi-esque command that will do the trick?
    Thanks and Cheers!

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Don't know if this is all that's to blame, but this is incorrect use of sscanf():

    Code:
    while((sscanf(line,"%c",&d)) != '\n')
    Sscanf() returns the number of successful assignments. The most you could have here is 1, but the integer value of '\n' is 10.

    So that would be an infinite loop, since it is impossible for the condition to ever be false.
    Last edited by MK27; 06-30-2010 at 10:27 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    Jun 2010
    Posts
    21
    What do you recommend? I am really confused right now.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    The inside while loop is goofed, as you suspected, and as others have mentioned.

    If the numbers represent row and column specifiers, such that:

    array[row][col]++;

    which will count up the number of times row and column pairs are given, then the third digit seen in two of the rows, purpose is unclear.

    In any case, get rid of the inner while loop, and just do something like:


    Code:
    while(you have another line of input) {
      sscanf() and get the row number
      sscanf() and get the column number
      increment array[row][col]
    }//end of while loop.
    If that doesn't make sense, clear up my confusion about that third number, and I can be more specific

  9. #9
    Registered User
    Join Date
    Jun 2010
    Posts
    21
    So what these numbers are the shortest distance between 2 nodes on a graphs.
    Therefore something like 0 3 1 means that the shortest distance between 0 and 1 has to pass through 3 i.e 0--->3--->1. What I want to do is calculate how many any one edge appears in ALL possible pathways.
    So in my data set 0--->3 appears twice and 0---->2 appears once and so on.
    The problem with your solution is that while it will capture the 0--->3 connection it wont capture the 3--->1 connection because it will end the loop and get another line.
    That is why I was trying to add another loop to check for \n but the "line" pointer is apparently a stationary and can only point to the start of the desired stream.

  10. #10
    Registered User
    Join Date
    Jun 2010
    Posts
    21
    Okay I got it working!!!!!!
    I talked to a guy in another lab and he talked about "strtok". After messing around I finally have the desired results.
    Here's the code in case someone is interested.
    Code:
    void betweeness(int n){
    int a;
    int b;
    char line[LINE_MAX];
    int flag=0;
    int c;
    char * pch;
    int i;
    FILE * fin = fopen("path.txt" ,"r");
    flag=0;//new line flag
    while(fgets(line, LINE_MAX, fin)!=NULL)
    {
    fputs(line, stdout);
    pch = strtok (line," ");
    while (pch != NULL)
      {
        a=atoi(pch);
        printf ("The first # is %d \n ",a);
        pch = strtok (NULL," ");
        if(pch != NULL)
        {
        b=atoi(pch);
        printf ("The 2nd # is %d \n ",b);
        betweenmat[a][b]=betweenmat[a][b]+1;
        printf ("The betweeness is %d \n ",betweenmat[a][b]);
        }
      }
    }
    fclose(fin);
    FILE * fout = fopen("between.txt" ,"w");
    for (a = 0; a < n; ++a) {
    		  for (b = 0; b < n; ++b)
    		  {
    		    fprintf(fout,"%d to %d :%d \n",a,b, betweenmat[a][b]);
    		  }}
    fclose(fout);
    }
    Thanks!!!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory Leak in AppWizard-Generated Code
    By jrohde in forum Windows Programming
    Replies: 4
    Last Post: 05-19-2010, 04:24 PM
  2. Encryption program
    By zeiffelz in forum C Programming
    Replies: 1
    Last Post: 06-15-2005, 03:39 AM
  3. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  4. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM