Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Problems when reading from a file with fscanf

Reply
Thread Tools

Problems when reading from a file with fscanf

 
 
Benedicte
Guest
Posts: n/a
 
      02-04-2004
Hi,

I'm getting some problems when using fscanf to read a file.

This is a piece of the program code:

main ()
{
/*** Variable declaration ***/
FILE *vpfile; /*** Data file ***/

struct line
{
char old_al[10];
char new_al[10];
char vp[5];
char new_dl[17];
};
struct line l[1000]={0};
int i=0;
int nl=0; /*** number of lines read ***/
int res=0;

/*** Executable statements ***/
/*** Open VpMove.txt file ***/
vpfile=fopen("/export/home/granite/CAPI/prog/bin/VpMove.txt","r");
if(vpfile==NULL)
{
printf("The file VpMove.txt could not be opened\n");
return;
}
/*** Read datafile ***/
while(fscanf(vpfile,"%s",l[i].old_al)!=EOF)
{
fscanf(vpfile,"%s",l[i].new_al);
fscanf(vpfile,"%s",l[i].vp);
fscanf(vpfile,"%s",l[i].new_dl);
i++;
}
nl=i-1; /*** undo i++ ***/
for(i=0;i<=nl;i++)
{
printf("Line %d %s\t %s\t %s\t
%s\n",i,l[i].old_al,l[i].new_al,l[i].vp,l[i].new_dl);
}
fclose(vpfile);
}

The VpMove.txt file looks like this:
003360073 003362061 240 AP-B_LIE_PP01-523
003360073 003351154 244 AP-B_LIE_PP01-10
003360073 003351154 243 AP-B_LIE_PP01

The output is the following:
Line 0 003360073 003362061 240 AP-B_LIE_PP01-523003360073
Line 1 003360073 003351154 244 AP-B_LIE_PP01-10
Line 2 003360073 003351154 243 AP-B_LIE_PP01

The problem is that when the word ends with a minus sign followed by 3
digits (see first line) he takes directly the following word: so
instead of AP-B_LIE_PP01-523 I receive AP-B_LIE_PP01-523003360073.

Can someone help me on this one?????
 
Reply With Quote
 
 
 
 
Rob van der Leek
Guest
Posts: n/a
 
      02-04-2004
In article <(E-Mail Removed) >,
Benedicte <(E-Mail Removed)> wrote:
>Hi,
>
>I'm getting some problems when using fscanf to read a file.
>
>This is a piece of the program code:
>


It's great you posted a working program, but please rember to
also include apropriate headers, e.g.: 'stdio.h' in this case.

>main ()
>{
> /*** Variable declaration ***/
> FILE *vpfile; /*** Data file ***/
>
> struct line
> {
> char old_al[10];
> char new_al[10];
> char vp[5];
> char new_dl[17];
> };
> struct line l[1000]={0};
> int i=0;
> int nl=0; /*** number of lines read ***/
> int res=0;
>
> /*** Executable statements ***/
> /*** Open VpMove.txt file ***/
> vpfile=fopen("/export/home/granite/CAPI/prog/bin/VpMove.txt","r");
> if(vpfile==NULL)
> {
> printf("The file VpMove.txt could not be opened\n");
> return;
> }
> /*** Read datafile ***/
> while(fscanf(vpfile,"%s",l[i].old_al)!=EOF)
> {
> fscanf(vpfile,"%s",l[i].new_al);
> fscanf(vpfile,"%s",l[i].vp);
> fscanf(vpfile,"%s",l[i].new_dl);
> i++;
> }
> nl=i-1; /*** undo i++ ***/
> for(i=0;i<=nl;i++)
> {
> printf("Line %d %s\t %s\t %s\t
>%s\n",i,l[i].old_al,l[i].new_al,l[i].vp,l[i].new_dl);
> }
> fclose(vpfile);
>}
>
>The VpMove.txt file looks like this:
>003360073 003362061 240 AP-B_LIE_PP01-523
>003360073 003351154 244 AP-B_LIE_PP01-10
>003360073 003351154 243 AP-B_LIE_PP01
>
>The output is the following:
>Line 0 003360073 003362061 240 AP-B_LIE_PP01-523003360073
>Line 1 003360073 003351154 244 AP-B_LIE_PP01-10
>Line 2 003360073 003351154 243 AP-B_LIE_PP01
>
>The problem is that when the word ends with a minus sign followed by 3
>digits (see first line) he takes directly the following word: so
>instead of AP-B_LIE_PP01-523 I receive AP-B_LIE_PP01-523003360073.
>
>Can someone help me on this one?????


The problem is that you overflow the character array of 'new_dl' fields.
This array is 17 characterss big, 'AP-B_LIE_PP01-523' has 17 characters,
leaving no space for the '\0' (zero terminator) that fscanf(...) wants
to insert at the end. When you print the value of 'new_dl' you run into
UB since printf expects a zero terminator to end strings. You might
find this zero terminator at the first field of the next record, that
explains the '003360073' part.
Increase the size of 'new_dl' from 17 to 18 and you'll see it works,
this is of course by no means a constructive solution.

Regards,
--
Rob van der Leek | rob(at)ricardis(dot)tudelft(dot)nl
Ricardishof 73-A | http://www.ricardis.tudelft.nl/~rob
2614 JE Delft, The Netherlands
+31 (0)6 155 244 60
 
Reply With Quote
 
 
 
 
Victor Nazarov
Guest
Posts: n/a
 
      02-04-2004
Benedicte wrote:
>
> struct line
> {
> char old_al[10];
> char new_al[10];
> char vp[5];
> char new_dl[17];
> };


So you have allocated 17 charecters for new_dl

> fscanf(vpfile,"%s",l[i].new_dl);


fscanf has wrote 18 charecters to new_dl. So undefined behavior.
Really it has wrote ending '\0' to the old_al of the second array member.

> nl=i-1; /*** undo i++ ***/
> for(i=0;i<=nl;i++)
> {


for (i = 0; i < nl; i++)
is consider to be standart among programmers. So use it insted of
decreasing nl

Using scanf is not safe because of buffer overrun as in your example.
You can use fgets and break the line into tokens by strtok or strpbrk
If you don't like fgets you can use some thing like:

char *afgets (char *s, size_t *lenp, FILE *f)
{
char *t;
ptrdiff_t tmp;
size_t l = 0;

if (lenp)
l = *lenp;
if (!s)
l = 0;
if (l == 0) {
l = 10;
s = malloc (l);
}
t = s;
for (; {
fgets (t, l, f);
t += strlen (t) - 1;
if (*t == '\n' || feof (f))
break;
tmp = t - s;
if ((t = realloc (s, l *= 2)) == NULL) {
l /= 2;
break;
}
s = t;
t += tmp;
}
if (lenp)
*lenp = l;
return s;
}

 
Reply With Quote
 
Al Bowers
Guest
Posts: n/a
 
      02-04-2004


Benedicte wrote:
> Hi,
>
> I'm getting some problems when using fscanf to read a file.
>
> This is a piece of the program code:

#include <stdio.h>
>
> main ()

int main(void)

> {
> /*** Variable declaration ***/
> FILE *vpfile; /*** Data file ***/
>
> struct line
> {
> char old_al[10];
> char new_al[10];
> char vp[5];
> char new_dl[17];
> };


You have not made some of the character arrays in the struct large
enough for the data. Looking at the data you supplied:

The VpMove.txt file looks like this:
003360073 003362061 240 AP-B_LIE_PP01-523
003360073 003351154 244 AP-B_LIE_PP01-10
003360073 003351154 243 AP-B_LIE_PP01

The struct, at a minimum should be:

struct line
{
char old_al[11]; /* allows enough for the string ending '\0' char */
char new_al[11];
char vp[4];
char new_dl[18];
};

> struct line l[1000]={0};
> int i=0;
> int nl=0; /*** number of lines read ***/
> int res=0;
>

What is res used for?

> /*** Executable statements ***/
> /*** Open VpMove.txt file ***/
> vpfile=fopen("/export/home/granite/CAPI/prog/bin/VpMove.txt","r");
> if(vpfile==NULL)
> {
> printf("The file VpMove.txt could not be opened\n");
> return;


main returns an int. You could make this:
return 1;
> }



> /*** Read datafile ***/
> while(fscanf(vpfile,"%s",l[i].old_al)!=EOF)
> {
> fscanf(vpfile,"%s",l[i].new_al);
> fscanf(vpfile,"%s",l[i].vp);
> fscanf(vpfile,"%s",l[i].new_dl);
> i++;
> }
> nl=i-1; /*** undo i++ ***/
> for(i=0;i<=nl;i++)
> {
> printf("Line %d %s\t %s\t %s\t
> %s\n",i,l[i].old_al,l[i].new_al,l[i].vp,l[i].new_dl);
> }


You can modify the above to:

for(nl = 0; 4 == fscanf(vpfile, " %s %s %s %s ",l[nl].old_al,
l[nl].new_al, l[nl].vp, l[nl].new_dl) ; nl++) ;
for(i=0;i < nl;i++)
printf("Line %d %s\t %s\t %s\t %s\n",
i,l[i].old_al,l[i].new_al,l[i].vp,l[i].new_dl);

> fclose(vpfile);


return 0;
> }


--
Al Bowers
Tampa, Fl USA
mailto: http://www.velocityreviews.com/forums/(E-Mail Removed) (remove the x to send email)
http://www.geocities.com/abowers822/

 
Reply With Quote
 
 
 
Reply

Thread Tools

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 On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
no error by fscanf on reading from output file V.Subramanian, India C Programming 18 10-31-2011 08:46 PM
can fscanf skip reading data conditionally? John C Programming 4 09-27-2006 08:07 PM
fscanf reading lines bhanuprakash@gmail.com C Programming 7 03-08-2006 03:29 PM
Re: How to put comments in initialization file read by fscanf()? David Rubin C Programming 0 07-14-2003 09:14 PM
Re: How to put comments in initialization file read by fscanf()? Chris Torek C Programming 0 07-14-2003 05:33 AM



Advertisments