|
From: Luigi S. <gi...@li...> - 2001-07-19 17:26:15
|
Iuri-
Suppose that your problem is the following: you have a text file (say it=20
"script") with lines of different lengths, you wish to load a line and=20
print it on the screen until all the lines have been processed.
script
------
aaaaaa
bbbbb
iuri
------
1- assume that you know that no line has more than 10 chars
Here is how I would solve it.
#include <stdio.h>
#include <assert.h>
#define MAX_LEN 11
#define FILE_NAME "script"
int main()
{
char buf[MAX_LEN];
FILE *inp =3D fopen(FILE_NAME, "r");
assert(inp !=3D 0); /* a quick way to report errors */
while (fgets(buf, MAX_LEN, inp))
printf("%s", buf);
fclose(inp);
return 0;
}
As you can see the second argument of fgets is the size of the array where=
=20
the line will be stored, not the size of the line that will be read. Also=20
keep in mind that fgets will read only MAX_LEN - 1 =3D 10 chars, the last=
one=20
will be used by fgets as the place for the '\0'.
So when you write:
fgets(linha1_ptr, sizeof(linha1_ptr), script);
It is "strange" (because usually you already know how big a string is), but=
=20
OK, if by "sizeof(linha1_ptr)" you mean the length of the string linha1_ptr=
=20
before the call to fgets, it is not correct if you mean: "read the line and=
=20
get its length, return this length as the value of sizeof(linha1_ptr)".
Suppose you say: (assume linha1_ptr is an array of 31 chars)
fgets(linha1_ptr, 31, script); /* and load the string "123\n" */
/* now sizeof(linha1_ptr) is 4 */
fgets(linha1_ptr, sizeof(linha1_ptr), script); /* trying to load "iuri\n" */
/* fgets will read 3 chars, "iur", the fourth will be '\0' */
Of course when you say:
fgets(linha1_ptr, 31, script); /* and load the string "123\n" */
fgets(linha1_ptr, 31, script); /* trying to load "iuri\n" */
/* now "iuri" will be loaded as expected */
Hope this clearly explains what should be used as the second argument of=
fgets.
2 - assume that you do not know the size of the biggest line
Here is how I would solve it.
#include <stdio.h>
#include <assert.h>
#include <string.h>
#define FILE_NAME "script"
char *getline(FILE *);
int main(int argc, char *argv[])
{
char *buf;
FILE *inp =3D fopen(FILE_NAME, "r");
assert(inp !=3D 0);
while (buf =3D getline(inp))
{
printf("%s", buf);
free(buf);
}
fclose(inp);
return 0;
}
/*
getline =3D read a line from the file, return the line read.
The string that is returned is always terminated by a '\n'
*/
#define SIZE 6
#define GET_MEM (char *)calloc(len + 1, sizeof(char))
char *getline(FILE *file)
{
char buf[SIZE];
char *line =3D 0;
int len =3D 0;
while (fgets(buf, SIZE, file))
{
char *tmp =3D line;
int n =3D strlen(buf);
len +=3D n;
line =3D GET_MEM;
assert(line !=3D 0);
if (tmp)
{
strcpy(line, tmp);
free(tmp);
}
strcat(line, buf);
if (buf[n - 1] =3D=3D '\n') /* finished reading line */
break;
}
return line;
}
Hope this is of some help
At 14.46 18/07/01 -0300, you wrote:
>Dear Luigi,
> Thank you for your help. I tried to use calloc because de string=
=20
> read from the
>file string has diferent sizes. I.e. the first line of the file script is=
=20
>"iuri", when I write:
>fgets (linha1_ptr ,sizeof(linha1_ptr), script);
> It returns: iur
>If I write:
>fgets (linha1_ptr , 30 , script);
> It returns: iuri
>
>With static memory the problem is that it reads the hole thing:
>So if my string is:
> aaaaaaaaaa
> bbbb
>With the fgets it will read:
> aaaaaaaaaa
> bbbb\0aaaa
>
>I think with sizeof it shouldn't happen, but it does. He reads the size of=
=20
>the 1=BA line and
>returns this same size for every line, even if it's bigger.
>
> Thanks,
> Iuri
---
gisan
|