Question about read data from a text file.

B

bowlderster

Hello, all.

This is the text file named test.txt.

1041 1467 7334 9500 2169 7724 3478 3358 9962 7464
6705 2145 6281 8827 1961 1491 3995 3942 5827 6436
6391 6604 4902 1153 1292 4382 9421 1716 2718 2895

I wanna to read the data to an array, as the follows:

#include <stdio.h>
#define MAX 30
int main()
{
int i = 0 ;
FILE *fp ;
int a[30] = {0};
if( (fp = fopen("test.txt", "r")) == NULL )
printf("Open file fail!!!\n");
for(i = 0 ; i < MAX ; i++)
{
fscanf(fp, "%i", &a) ;
printf("%i\t",a);
}
fclose(fp);
return 0;
}

It is successful.

And I change the type of the array to float
....
float a[30];
....
fscanf(fp,"%f",&a);
printf("%f\t",a);
....

It works as well.

But when I change the type of the array to double
....
double a[30];
....
fscanf(fp,"%g",&a);
printf(fp,"%g",a);
....

It cannot work. It seams that the array is zero.

I wanna to know the reason and how can read the data to a double array.This is one question.

Another is that:
If the data file test.txt is in the following format,
a b c d e f g h i j
=============================================
1041 1467 7334 9500 2169 7724 3478 3358 9962 7464
6705 2145 6281 8827 1961 1491 3995 3942 5827 6436
6391 6604 4902 1153 1292 4382 9421 1716 2718 2895

how to read the file directly to the 3rd line? I mean that I just wanna to read the numbers.

I know fseek function can move the file pointer to a certain position.
But for a text file, how to caculate he offset?
If it can work, please give me your example for the above file.


I am learning the language at the beginning. Any encouragement will be helpful.
 
A

Army1987

"bowlderster" <[email protected]> ha scritto nel messaggio
[snip]
if( (fp = fopen("test.txt", "r")) == NULL )
printf("Open file fail!!!\n");
If I redirect the output to a file, I won't be able to read the error until
I read that file.
You must write to stderr, not stdin. If you use perror() it will also add a
colon, a space, an explaination of the error, and a newline char.
perror("Open file fail");
Also, if the test fails, the rest of the program will run as if fp wasn't
NULL.
use exit(EXIT_FAILURE); (you must #include said:
for(i = 0 ; i < MAX ; i++)
{
fscanf(fp, "%i", &a) ;
printf("%i\t",a);
}
fclose(fp);
return 0;
}

It is successful.

And I change the type of the array to float
...
float a[30];
...
fscanf(fp,"%f",&a);
printf("%f\t",a);
...

It works as well.

But when I change the type of the array to double
...
double a[30];
...
fscanf(fp,"%g",&a);
printf(fp,"%g",a);
...

It cannot work. It seams that the array is zero.

I wanna to know the reason and how can read the data to a double
array.This is one question.

Another is that:
If the data file test.txt is in the following format,
a b c d e f g h i j
=============================================
1041 1467 7334 9500 2169 7724 3478 3358 9962 7464
6705 2145 6281 8827 1961 1491 3995 3942 5827 6436
6391 6604 4902 1153 1292 4382 9421 1716 2718 2895

how to read the file directly to the 3rd line? I mean that I just wanna to
read the numbers.

I know fseek function can move the file pointer to a certain position.
But for a text file, how to caculate he offset?
If it can work, please give me your example for the above file.


I am learning the language at the beginning. Any encouragement will be
helpful.
 
A

Army1987

"bowlderster" <[email protected]> ha scritto nel messaggio
[snip]
int a[30] = {0};
You meant a[MAX]. If you change MAX at the beginning and forget to change 30
here, that could be a problem.
if( (fp = fopen("test.txt", "r")) == NULL )
printf("Open file fail!!!\n");
If I redirect the output to a file, I won't be able to read the error until
I read that file.
You must write to stderr, not stdin. If you use perror() it will also add a
colon, a space, an explaination of the error, and a newline char.
perror("Open file fail");
Also, if the test fails, the rest of the program will run as if fp wasn't
NULL.
But when I change the type of the array to double
...
double a[30];
...
fscanf(fp,"%g",&a);
printf(fp,"%g",a);
...

It cannot work. It seams that the array is zero.

http://c-faq.com/stdio/scanf2.html
 
W

Walter Roberson

If the data file test.txt is in the following format,
a b c d e f g h i j
=============================================
1041 1467 7334 9500 2169 7724 3478 3358 9962 7464
6705 2145 6281 8827 1961 1491 3995 3942 5827 6436
6391 6604 4902 1153 1292 4382 9421 1716 2718 2895
how to read the file directly to the 3rd line? I mean that I just wanna to read the numbers.
I know fseek function can move the file pointer to a certain position.
But for a text file, how to caculate he offset?

You cannot do that. As the local man page says for fseek()

The ANSI C Standard restricts the use of offsets, when stream refers to a
text file. When operating on these files, the value of offset must be
zero unless whence is SEEK_SET. This restriction is necessary as the
unit of offsets may not be bytes on some systems, and arithmetic may not
meaningfully be performed on them.

And if you are using SEEK_SET on a text stream, then the value
you pass in must be the result of an ftell(), and ftell() on
a text stream theoretically returns an opaque value, not an
integral offset value.

Text files are not necessarily linearly structured (e.g., on the
VMS operating system), and even on systems that do structure text
files linearly, there is no way to query what the line termination
sequence is. (You can also run into issues such as the possibility
that the OS might consider as a valid line termination one or more
carriage returns before a linefeed; the first line might happen to
end CR LF internally, but the second line might happen to end
CR CR CR CR LF internally, so you cannot assign any fixed
predictable size for line termination offset calculations.)


If you were willing to lose portability and only deal with
systems that did use linear text files, and on which you knew
that the line termination was always the same size, then you
could read the file as a binary file and calculate byte offsets
if you knew the exact length of the first and second lines ahead
of time. But there is no portable way to fseek() to any given
line in a text stream -- not that doesn't involve reading
the file through once to find all the line offsets.
 
M

Michael

This is the text file named test.txt.

1041 1467 7334 9500 2169 7724 3478 3358 9962 7464
6705 2145 6281 8827 1961 1491 3995 3942 5827 6436
6391 6604 4902 1153 1292 4382 9421 1716 2718 2895

I wanna to read the data to an array, as the follows:

#include <stdio.h>
#define MAX 30
int main()
{
int i = 0 ;
FILE *fp ;
int a[30] = {0};
if( (fp = fopen("test.txt", "r")) == NULL )
printf("Open file fail!!!\n");
for(i = 0 ; i < MAX ; i++)
{
fscanf(fp, "%i", &a) ;
printf("%i\t",a);}

fclose(fp);
return 0;

}

But when I change the type of the array to double
...
double a[30];
...
fscanf(fp,"%g",&a);
printf(fp,"%g",a);
...

It cannot work. It seams that the array is zero.


fscanf(fp, "%lf", &a) ;
Another is that:
If the data file test.txt is in the following format,
a b c d e f g h i j
=============================================
1041 1467 7334 9500 2169 7724 3478 3358 9962 7464
6705 2145 6281 8827 1961 1491 3995 3942 5827 6436
6391 6604 4902 1153 1292 4382 9421 1716 2718 2895

how to read the file directly to the 3rd line? I mean that I just wanna to read the numbers.

You could use fgets (twice) to read each of the first two lines.

Michael
 
B

bowlderster

Army1987 said:
"bowlderster" <[email protected]> ha scritto nel messaggio
[snip]
int a[30] = {0};
You meant a[MAX]. If you change MAX at the beginning and forget to change 30
here, that could be a problem.
Thanks.I just want to test.
if( (fp = fopen("test.txt", "r")) == NULL )
printf("Open file fail!!!\n");
If I redirect the output to a file, I won't be able to read the error until
I read that file.
You must write to stderr, not stdin. If you use perror() it will also add a
colon, a space, an explaination of the error, and a newline char.
perror("Open file fail");
Also, if the test fails, the rest of the program will run as if fp wasn't
NULL.
But when I change the type of the array to double
...
double a[30];
...
fscanf(fp,"%g",&a);
printf(fp,"%g",a);
...

It cannot work. It seams that the array is zero.

http://c-faq.com/stdio/scanf2.html


This is helpful.

Thank you.
 
B

bowlderster

You cannot do that. As the local man page says for fseek()

The ANSI C Standard restricts the use of offsets, when stream refers to a
text file. When operating on these files, the value of offset must be
zero unless whence is SEEK_SET. This restriction is necessary as the
unit of offsets may not be bytes on some systems, and arithmetic may not
meaningfully be performed on them.

And if you are using SEEK_SET on a text stream, then the value
you pass in must be the result of an ftell(), and ftell() on
a text stream theoretically returns an opaque value, not an
integral offset value.

Text files are not necessarily linearly structured (e.g., on the
VMS operating system), and even on systems that do structure text
files linearly, there is no way to query what the line termination
sequence is. (You can also run into issues such as the possibility
that the OS might consider as a valid line termination one or more
carriage returns before a linefeed; the first line might happen to
end CR LF internally, but the second line might happen to end
CR CR CR CR LF internally, so you cannot assign any fixed
predictable size for line termination offset calculations.)


If you were willing to lose portability and only deal with
systems that did use linear text files, and on which you knew
that the line termination was always the same size, then you
could read the file as a binary file and calculate byte offsets
if you knew the exact length of the first and second lines ahead
of time. But there is no portable way to fseek() to any given
line in a text stream -- not that doesn't involve reading
the file through once to find all the line offsets.

I know a lot from your words.
 
N

Nick Keighley

bowlderster said:
This is the text file named test.txt.

1041 1467 7334 9500 2169 7724 3478 3358 9962 7464
6705 2145 6281 8827 1961 1491 3995 3942 5827 6436
6391 6604 4902 1153 1292 4382 9421 1716 2718 2895

I wanna to read the data to an array, as the follows:

"want to" standard english is easier to read.

code is more readable if indented and with appropriate whitespace
#include <stdio.h>
#define MAX 30

int main()

int main (void)
is better style
{
int i = 0 ;
FILE *fp ;
int a[30] = {0};

if ( (fp = fopen("test.txt", "r")) == NULL )
printf("Open file fail!!!\n");

for (i = 0 ; i < MAX ; i++)
{
fscanf(fp, "%i", &a) ;


always check the return value of fscanf()

printf("%i\t",a);
}

fclose(fp);
return 0;
}


I am learning the language at the beginning. Any encouragement will be helpful.

not bad for a beginner
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top