LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-30-2007, 02:58 PM   #1
exvor
Senior Member
 
Registered: Jul 2004
Location: Phoenix, Arizona
Distribution: Gentoo, LFS, Debian,Ubuntu
Posts: 1,537

Rep: Reputation: 87
C fscanf function


Ive been trying to write a search algorithm and it searches a test file and im having a bit of an issue being able to get it to work properly and I think I have this narrowed down. Fscaf does not move the file pointer when reading imput from a file or does only when reading a very specific way. I am wondering if this is intended or am I doing something wrong ?

basically if i do a fscanf and then print the file position its in the same place every time its called it never moves.


I apologize if this seams like a simple question but I have searched around the man file and online but have yet to find an answer to my file. From the docs it seams like it should be moving the file position.

Last edited by exvor; 05-30-2007 at 03:16 PM.
 
Old 05-30-2007, 06:17 PM   #2
wjevans_7d1@yahoo.co
Member
 
Registered: Jun 2006
Location: Mariposa
Distribution: Slackware 9.1
Posts: 938

Rep: Reputation: 31
It should move the file position, but fscanf is tricky, especially when dealing with data that's not in the format your program suggests. I always use fgets() to get a line at a time, and then remove the ending line feed (if there is one), and then use sscanf() on the line I've just input.

But to address your problem directly:

Can you isolate the problem down to a tiny program with a tiny data file, and post these things?
  1. the complete tiny program (including absolutely everything, including the #includes, so people can run your exact program on their machine)
  2. the complete tiny data file, and
  3. your complete output when running that program against that data file
 
Old 05-31-2007, 12:09 AM   #3
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Ubuntu 12.04, Antix19.3
Posts: 3,794

Rep: Reputation: 282Reputation: 282Reputation: 282
Without seeing the code, it's difficult to say. However, it happens to me quite often when I open the file and next call another function in a loop to read (part of) the file passing the filepointer as an argument.

To make sure that that works, one has to pass a pointer to the filepointer as the argument and not the filepointer itself.
 
Old 05-31-2007, 09:39 AM   #4
exvor
Senior Member
 
Registered: Jul 2004
Location: Phoenix, Arizona
Distribution: Gentoo, LFS, Debian,Ubuntu
Posts: 1,537

Original Poster
Rep: Reputation: 87
I had considered using fgets to get a line and then parse it out but i was trying to keep so it could handle a dynamic line length or just not care how long the line was and obtain the first line. I'm reconsidering using a text file to store my variables so this all might be a mute point. Thanks for your excellent responses tho.
 
Old 05-31-2007, 11:20 AM   #5
exvor
Senior Member
 
Registered: Jul 2004
Location: Phoenix, Arizona
Distribution: Gentoo, LFS, Debian,Ubuntu
Posts: 1,537

Original Poster
Rep: Reputation: 87
I was playing around with fgets and it seams to give me a very reliable way of finding where something is in a file below is my insanity of work that I was attempting to do. Not sure if I'm going to keep this model tho

Code:
 
#include<stdio.h>
#define BUFF 100

int main()
{
   char *testfile="test.txt";
   char data[BUFF];
   int accnum;
   int pos = 0;
   int sacct;

   FILE *dfile;
    dfile = fopen(testfile,"r");
    printf("\nType the account you looking for\n:>");
    scanf("%i",&sacct);
   do {
    pos = ftell(dfile);

    if ((fgets(data,BUFF,dfile)) != NULL)
         {
            sscanf(data,"%i",&accnum);
            if (accnum == sacct)
              {
                printf("\nAccount found %i\n",accnum);
                printf("\nAt file postion %i\n",pos);
              }
         }
      } while((feof(dfile)) == 0);
  fclose(dfile);
 return 0;
}
the text file looks like this

Code:
 
1 jane dobs 
2 jack ohara 
3 shooter mcgavin 
4 the zapper

Last edited by exvor; 05-31-2007 at 11:22 AM.
 
Old 05-31-2007, 05:44 PM   #6
wjevans_7d1@yahoo.co
Member
 
Registered: Jun 2006
Location: Mariposa
Distribution: Slackware 9.1
Posts: 938

Rep: Reputation: 31
Does that code do what you expect it to?
 
Old 05-31-2007, 05:53 PM   #7
exvor
Senior Member
 
Registered: Jul 2004
Location: Phoenix, Arizona
Distribution: Gentoo, LFS, Debian,Ubuntu
Posts: 1,537

Original Poster
Rep: Reputation: 87
Yes sorry I forgot to add that. This code does in fact do what I was looking for. I do still wonder why fscanf is undefined on what occurs with the file position after it reads data.
 
Old 06-01-2007, 12:02 PM   #8
wjevans_7d1@yahoo.co
Member
 
Registered: Jun 2006
Location: Mariposa
Distribution: Slackware 9.1
Posts: 938

Rep: Reputation: 31
I've just looked at the (old) ANSI C standard. I'm not sure that "undefined" applies here. Probably closer to "complex and counterintuitive". It's just easier to get your code out the door if you stick to fgets()/sscanf().
 
Old 06-01-2007, 02:56 PM   #9
exvor
Senior Member
 
Registered: Jul 2004
Location: Phoenix, Arizona
Distribution: Gentoo, LFS, Debian,Ubuntu
Posts: 1,537

Original Poster
Rep: Reputation: 87
Yeah thats what I thought. Oddly enough when I attempt to put this in a function its not working again ??

below is the code in a function some reason it does not return when return is called.

Can you not use return in a while loop ?

Code:
 
long int searchIO(long int accnum) 
{ 
   
     char parsd[CSIZE]; 
     long int filepos =0; 
     long int check; 

     
      rewind(cdfile); 
      while ((feof(cdfile)) == 0)
        { 
          filepos = ftell(cdfile); 
            
          if ((fgets(parsd,CSIZE,cdfile)) != NULL)
                { 
                  
                  sscanf(parsd,"%i",&check); 
                  
                  if (check == accnum) 
                       { 
                         return filepos; 
                       } 
                 }
         
          } 
   return -1; 
}
 
Old 06-02-2007, 12:35 AM   #10
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Ubuntu 12.04, Antix19.3
Posts: 3,794

Rep: Reputation: 282Reputation: 282Reputation: 282
You can return from a while loop. Either use GDB or add some printf statement in the while loop for debugging.

Without the code that calls the function, it's difficult to say what's wrong.
 
Old 06-02-2007, 12:28 PM   #11
wjevans_7d1@yahoo.co
Member
 
Registered: Jun 2006
Location: Mariposa
Distribution: Slackware 9.1
Posts: 938

Rep: Reputation: 31
There's nothing wrong with that function. I put this data in saturday.dat.

Code:
100
200
300
400
500
Then I ran this program, which contains your function, unmodified:

Code:
#include <stdio.h>
#include <stdlib.h>

const int CSIZE=100;

FILE *cdfile;

long int searchIO(long int accnum) 
{ 
   
     char parsd[CSIZE]; 
     long int filepos =0; 
     long int check; 

     
      rewind(cdfile); 
      while ((feof(cdfile)) == 0)
        { 
          filepos = ftell(cdfile); 
            
          if ((fgets(parsd,CSIZE,cdfile)) != NULL)
                { 
                  
                  sscanf(parsd,"%i",&check); 
                  
                  if (check == accnum) 
                       { 
                         return filepos; 
                       } 
                 }
         
          } 
   return -1; 
}

int main(void)
{
  cdfile=fopen("saturday.dat","r");

  if(cdfile==NULL)
  {
    fprintf(stderr,"open failed\n");
    exit(1);
  }

  printf("file position is %ld\n",searchIO(300));

  fclose(cdfile);

  return 0;

} /* main() */
It output 8, which is the correct answer.
 
Old 06-04-2007, 09:46 AM   #12
exvor
Senior Member
 
Registered: Jul 2004
Location: Phoenix, Arizona
Distribution: Gentoo, LFS, Debian,Ubuntu
Posts: 1,537

Original Poster
Rep: Reputation: 87
I kinda figured it out the value passed to the function is getting modified somehow. I am not exactly sure why as I don't pass any values to the variable. Its got the correct value till it goes into the loop and once it is in the loop is where it gets changed?? By the way this was compiled on a turbo C compiler quite outdated but it the only windows one I have. The code is portable to Linux but I have yet to try and see if the same problem occurs. As far as I can tell I have not made any newb mistakes.



here is the program I was using to test with.

HEADER
Code:
 
#include<stdio.h> 
#define CSIZE 200 
#define FILENAME "datab.txt"

 
FILE *cdfile; 


long int searchIO(long int); /* returns file postion  */ 
                          /* upon sucess -1 if not found */
Code:
 
#include"fileIO.h"

int main() 
{ 
    long int acc =0; 
    long int pos; 
    cdfile = fopen(FILENAME,"r"); 
    printf("\nWhat account do you want to find\n:>"); 
    scanf("%i",&acc); 
    
    if ((pos = searchIO(acc)) == -1) 
         { 
            printf("\nPos was %i",pos); 
            printf("\nRecord not found!\n"); 
         } 
     else 
        printf("\nFound at %i\n",pos); 
    
 return 0; 
} 


long int searchIO(long int accnum) 
{ 
   
     char parsd[CSIZE]; 
     long int filepos =0; 
     long int check; 

     printf("\nAccnum is %i\n",accnum); 
      rewind(cdfile); 
      while ((feof(cdfile)) == 0)
        { 
          filepos = ftell(cdfile); 
          printf("\nFile filepos=%i\n",filepos);  
          if ((fgets(parsd,CSIZE,cdfile)) != NULL)
                { 
                  printf("\nParsd is :%s\n",parsd); 
                  sscanf(parsd,"%i",&check); 
                  printf("\ncheck=%i\naccnum =%i",check,accnum);
                  
                  if (check == accnum) 
                       { 
                         printf("\nI have reached the return\n"); 
                         return filepos; 
                       } 
                 }
         
          } 
   return -1; 
}
Text file used
Quote:
5 daysofour lives 1 days.txt
2 james bond 2 james.txt
and the output here
Quote:
E:\DD>test.exe
What account do you want to find
:>2

Accnum is 2

File filepos=0

Parsd is :5 daysofourlives 1 days.txt

check=5
accnum =-40 << This is where im confused
File filepos=30

Parsd is :5 daysofourlives 1 days.txt

check=2
accnum =-40
File filepos=56

Pos was -1
Record not found!

E:\DD>

Last edited by exvor; 06-04-2007 at 10:00 AM.
 
Old 06-05-2007, 01:50 AM   #13
exvor
Senior Member
 
Registered: Jul 2004
Location: Phoenix, Arizona
Distribution: Gentoo, LFS, Debian,Ubuntu
Posts: 1,537

Original Poster
Rep: Reputation: 87
I found the issue here. Looks to be indeed something with the compiler that I was using probably when it was geting converted to assembly. When I compliled the above program in gcc it worked just fine and as intended. Was also my fault too as i was not explicity declareing the long in the function. anyway Im not intrested in delving too deep into this one any more if you find more data or a better explination feel free.

Last edited by exvor; 06-05-2007 at 02:05 AM.
 
Old 06-05-2007, 02:11 AM   #14
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Ubuntu 12.04, Antix19.3
Posts: 3,794

Rep: Reputation: 282Reputation: 282Reputation: 282
I've compiled your code on a Slackware box and it gives warnings
Code:
lq557823_org.c:19: warning: int format, long int arg (arg 2)
This is the line with the first scanf (where you ask for the account number). This happens a couple of times for each printf as well as each scanf. Reason is that the %i expects and integer and not a long.
Change all %i to %li is one thing you can try.

With or without that change, the code works as expected on my system.

Code:
#include<stdio.h>
#define CSIZE 200
#define FILENAME "datab.txt"


FILE *cdfile;


long int searchIO(long int); /* returns file postion  */
                          /* upon sucess -1 if not found */

int main()
{
    long int acc =0;
    long int pos;
    cdfile = fopen(FILENAME,"r");
    printf("\nWhat account do you want to find\n:>");
    scanf("%li",&acc);

    if ((pos = searchIO(acc)) == -1)
         {
            printf("\nPos was %li",pos);
            printf("\nRecord not found!\n");
         }
     else
        printf("\nFound at %li\n",pos);

 return 0;
}


long int searchIO(long int accnum)
{

     char parsd[CSIZE];
     long int filepos =0;
     long int check;

     printf("\nAccnum is %li\n",accnum);
     rewind(cdfile);
     while ((feof(cdfile)) == 0)
        {
          filepos = ftell(cdfile);
          printf("\nFile filepos=%li\n",filepos);
          if ((fgets(parsd,CSIZE,cdfile)) != NULL)
                {
                  printf("\nParsd is :%s\n",parsd);
                  sscanf(parsd,"%li",&check);
                  printf("\ncheck=%li\naccnum =%li",check,accnum);

                  if (check == accnum)
                       {
                         printf("\nI have reached the return\n");
                         return filepos;
                       }
                 }

          }
   return -1;
}
 
Old 06-05-2007, 09:40 AM   #15
exvor
Senior Member
 
Registered: Jul 2004
Location: Phoenix, Arizona
Distribution: Gentoo, LFS, Debian,Ubuntu
Posts: 1,537

Original Poster
Rep: Reputation: 87
Yeah Gcc gave me the same warnings about the %i in the scanf and in the printf. More then likely that is what the issue was with. The compiler I used to compile this the first time is quite dated.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
using fread with fscanf andystanfordjason Programming 4 12-20-2006 09:49 AM
fscanf returns -1 trutnev Programming 2 06-23-2005 08:50 AM
fscanf & fgetc help billybob2004 Programming 2 02-04-2004 10:24 AM
fscanf c programming tomato Programming 14 01-09-2004 08:33 PM
using fscanf function Linh Programming 2 07-14-2003 12:58 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:23 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration