ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
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?
the complete tiny program (including absolutely everything, including the #includes, so people can run your exact program on their machine)
the complete tiny data file, and
your complete output when running that program against that data file
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.
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.
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
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.
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().
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;
}
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
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.
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;
}
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.