Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Reading a data file

Reply
Thread Tools

Reading a data file

 
 
W. eWatson
Guest
Posts: n/a
 
      07-19-2013
It seems every year, I have to write one simple C-program.
If I stare at my only book on C, Comprehensive C, 1992 (way back), my
eyes start to glaze over. It's been along time.

I'm using gcc.

I have a file something like this:

mydata.dat
0.345 12.613 8.100
13.118
8.224 0.777
22.420 0.546 99.000


7.3f specifier. The numbers are lined up, but sometimes there are only
one or two numbers on a line. Actually, I'd be happy to read just one
line. I think I might be able to carry the ball after that.

I want to read it, and display it on the console.

Can someone supply the details?
 
Reply With Quote
 
 
 
 
Tim Rentsch
Guest
Posts: n/a
 
      07-19-2013
"W. eWatson" <(E-Mail Removed)> writes:

> It seems every year, I have to write one simple C-program.
> If I stare at my only book on C, Comprehensive C, 1992 (way back), my
> eyes start to glaze over. It's been along time.
>
> I'm using gcc.
>
> I have a file something like this:
>
> mydata.dat
> 0.345 12.613 8.100
> 13.118
> 8.224 0.777
> 22.420 0.546 99.000
>
>
> 7.3f specifier. The numbers are lined up, but sometimes there are only
> one or two numbers on a line. Actually, I'd be happy to read just one
> line. I think I might be able to carry the ball after that.
>
> I want to read it, and display it on the console.
>
> Can someone supply the details?


You need stdio.h of course:

#include <stdio.h>

The file can be opened with the fopen() function:

FILE *input = fopen( "mydata.dat", "r" );

Lines from the file can be read into a buffer using
the fgets() function:

char line[ 100 ];
while( fgets( line, sizeof line, input ) ){
...

To get the values on a line, use the sscanf() function,
checking the function's return value to see how many
values on the line there were:

double a, b, c;
int n;

n = sscanf( line, " %lf %lf %lf", &a, &b, &c );
/* n == 3 means three values were read - a, b, c */
/* n == 2 means two values were read - a, b */
/* n == 1 means one value was read - a */
/* n anything else means no values were read */

... now use the values ...

When all done reading, the file can be closed with
the fclose() function:

}

fclose( input );

Production-quality code should have checks for error
returns and perhaps accommodate a non-fixed-size
line buffer. Now that you have a better idea where
to look, it shouldn't be too hard to figure out what
those things are and how to do them.

Disclaimer: all I've done is type this stuff in.
It hasn't been compiled or tested in any way. So
don't rely on it except has a hint to point you
in (what I think is) a generally good direction.
 
Reply With Quote
 
 
 
 
W. eWatson
Guest
Posts: n/a
 
      07-19-2013
On 7/18/2013 8:07 PM, Tim Rentsch wrote:
> "W. eWatson" <(E-Mail Removed)> writes:
>
>> It seems every year, I have to write one simple C-program.
>> If I stare at my only book on C, Comprehensive C, 1992 (way back), my
>> eyes start to glaze over. It's been along time.
>>
>> I'm using gcc.
>>
>> I have a file something like this:
>>
>> mydata.dat
>> 0.345 12.613 8.100
>> 13.118
>> 8.224 0.777
>> 22.420 0.546 99.000
>>
>>
>> 7.3f specifier. The numbers are lined up, but sometimes there are only
>> one or two numbers on a line. Actually, I'd be happy to read just one
>> line. I think I might be able to carry the ball after that.
>>
>> I want to read it, and display it on the console.
>>
>> Can someone supply the details?

>
> You need stdio.h of course:
>
> #include <stdio.h>
>
> The file can be opened with the fopen() function:
>
> FILE *input = fopen( "mydata.dat", "r" );
>
> Lines from the file can be read into a buffer using
> the fgets() function:
>
> char line[ 100 ];
> while( fgets( line, sizeof line, input ) ){
> ...
>
> To get the values on a line, use the sscanf() function,
> checking the function's return value to see how many
> values on the line there were:
>
> double a, b, c;
> int n;
>
> n = sscanf( line, " %lf %lf %lf", &a, &b, &c );
> /* n == 3 means three values were read - a, b, c */
> /* n == 2 means two values were read - a, b */
> /* n == 1 means one value was read - a */
> /* n anything else means no values were read */
>
> ... now use the values ...
>
> When all done reading, the file can be closed with
> the fclose() function:
>
> }
>
> fclose( input );
>
> Production-quality code should have checks for error
> returns and perhaps accommodate a non-fixed-size
> line buffer. Now that you have a better idea where
> to look, it shouldn't be too hard to figure out what
> those things are and how to do them.
>
> Disclaimer: all I've done is type this stuff in.
> It hasn't been compiled or tested in any way. So
> don't rely on it except has a hint to point you
> in (what I think is) a generally good direction.
>

Thanks. is sscanf a typo for fscanf?

I played some more and got this:
#include<stdio.h>
#include<stdlib.h>

int
main(void)
{
char str[70];
FILE *p;
if((p=fopen("outfile.txt","r"))==NULL){
printf("\nUnable to open file string.txt");
exit(1);
}
while(fgets(str,70,p)!=NULL)
puts(str);
fclose(p);
exit(0);
}
Needs some adjustments for my situation.

Getting closer.

 
Reply With Quote
 
Ike Naar
Guest
Posts: n/a
 
      07-19-2013
On 2013-07-19, W. eWatson <(E-Mail Removed)> wrote:
> int
> main(void)
> {
> char str[70];
> FILE *p;
> if((p=fopen("outfile.txt","r"))==NULL){
> printf("\nUnable to open file string.txt");


Wouldn't it make more sense to put the end-of-line character
at the end of the line, rather than at the beginning?

> exit(1);

 
Reply With Quote
 
Jorgen Grahn
Guest
Posts: n/a
 
      07-19-2013
On Fri, 2013-07-19, Tim Rentsch wrote:
> "W. eWatson" <(E-Mail Removed)> writes:
>
>> It seems every year, I have to write one simple C-program.
>> If I stare at my only book on C, Comprehensive C, 1992 (way back), my
>> eyes start to glaze over. It's been along time.
>>
>> I'm using gcc.
>>
>> I have a file something like this:
>>
>> mydata.dat
>> 0.345 12.613 8.100
>> 13.118
>> 8.224 0.777
>> 22.420 0.546 99.000
>>
>>
>> 7.3f specifier. The numbers are lined up, but sometimes there are only
>> one or two numbers on a line. Actually, I'd be happy to read just one
>> line. I think I might be able to carry the ball after that.
>>
>> I want to read it, and display it on the console.


OP: really? Because there are standard programs for that, e.g. cat(1)
on Unix. If you do need to do more, do you have to do floating-point
operations on the numbers? In a way it would be better if you could
treat them as strings: "0.345" and so on. No numerical errors to
worry about.

>> Can someone supply the details?


> The file can be opened with the fopen() function:
>
> FILE *input = fopen( "mydata.dat", "r" );


I'd prefer to read from stdin, and/or from a file whose name was provided
in argv. Nitpick perhaps, but I really dislike programs which have odd
user interfaces -- they are hard to automate.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
 
Reply With Quote
 
mark.bluemel@gmail.com
Guest
Posts: n/a
 
      07-19-2013
On Friday, 19 July 2013 04:59:43 UTC+1, W. eWatson wrote:

> ... is sscanf a typo for fscanf?


Nope. See for example <http://linux.die.net/man/3/sscanf> - sscanf() allows you to scan a string for data rather than reading from stdin or some other file.

Parts of section 12 of the C-FAQ <http://c-faq.com> may help you understand why this is a good thing.
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      07-19-2013
On 07/19/2013 03:40 AM, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> On Friday, 19 July 2013 04:59:43 UTC+1, W. eWatson wrote:
>
>> ... is sscanf a typo for fscanf?

>
> Nope. See for example <http://linux.die.net/man/3/sscanf> - sscanf() allows you to scan a string for data rather than reading from stdin or some other file.
>
> Parts of section 12 of the C-FAQ <http://c-faq.com> may help you understand why this is a good thing.


W. eWatson is probably not ready for the following complication, but
I'll mention it for his future consideration, when he's become more
familiar with C:

The behavior of the fscanf() family of functions is undefined when
parsing a string that represents a number too large to be represented in
the corresponding type. For example, a typical value for FLT_MAX is
3.40282346638528859812e+38F, so sscanf("4e38", "%f", &x) has undefined
behavior.

If you want to avoid this problem, you should use the strto*() family of
functions. They have defined behavior regardless of the contents of the
string that is parsed. If something goes wrong, they provide more
information about what went wrong than sscanf() does. Finally, if they
extract a complete number before reaching the end of the string, they
let you know where the number ended, so you can continue parsing the
rest of that string in whatever manner you wish. These advantages have a
cost - using those functions is more complicated than using sscanf(),
which is why I don't think W. eWatson is ready for it yet.

Example of use:

#include <errno.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
for(int arg=1; arg<argc; arg++)
{
char *endptr;

printf("Argument %d:", arg);
errno = 0;
double d = strtod(argv[arg], &endptr);
if(endptr == argv[arg])
{
printf("The subject sequence is empty "
"or does not have the expected form");
}
else if(errno == ERANGE)
{
printf("Conversion to double %sflowed.",
(d >= HUGE_VAL || d <= -HUGE_VAL) ? "over" : "under");
}
else
{
printf("%g", d);
if(*endptr)
printf(" The rest of the string is: \"%s\"", endptr);
}
putchar('\n');
}
return ferror(stdout) ? EXIT_FAILURE : EXIT_SUCCESS;
}
--
James Kuyper
 
Reply With Quote
 
glen herrmannsfeldt
Guest
Posts: n/a
 
      07-19-2013
W. eWatson <(E-Mail Removed)> wrote:
> It seems every year, I have to write one simple C-program.
> If I stare at my only book on C, Comprehensive C, 1992 (way back), my
> eyes start to glaze over. It's been along time.


(snip)
> I have a file something like this:


> mydata.dat
> 0.345 12.613 8.100
> 13.118
> 8.224 0.777
> 22.420 0.546 99.000


> 7.3f specifier. The numbers are lined up, but sometimes there are only
> one or two numbers on a line. Actually, I'd be happy to read just one
> line. I think I might be able to carry the ball after that.


A loop with scanf or fscanf, reading one at a time, will ignore newlines
(line boundaries). Sometimes that is good, sometimes not.

One problem that C doesn't help much with is knowing how many there
will be, so that you can allocate space for them.

-- glen
 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      07-19-2013
Jorgen Grahn <(E-Mail Removed)> writes:

> On Fri, 2013-07-19, Tim Rentsch wrote:
>> "W. eWatson" <(E-Mail Removed)> writes:
>>
>>> It seems every year, I have to write one simple C-program. If I
>>> stare at my only book on C, Comprehensive C, 1992 (way back), my
>>> eyes start to glaze over. It's been along time.
>>>
>>> I'm using gcc.
>>>
>>> I have a file something like this:
>>>
>>> mydata.dat
>>> 0.345 12.613 8.100
>>> 13.118
>>> 8.224 0.777
>>> 22.420 0.546 99.000
>>>
>>>
>>> 7.3f specifier. The numbers are lined up, but sometimes there
>>> are only one or two numbers on a line. Actually, I'd be happy to
>>> read just one line. I think I might be able to carry the ball
>>> after that.
>>>
>>> I want to read it, and display it on the console.
>>>
>>> Can someone supply the details?

>
>> The file can be opened with the fopen() function:
>>
>> FILE *input = fopen( "mydata.dat", "r" );

>
> I'd prefer to read from stdin, and/or from a file whose name was
> provided in argv. [snip]


I might agree with those sentiments, but my comments were
concerned only with answering OP's question. He wasn't
asking for a lesson in programming style, and I didn't feel
a need to give one -- just to answer his question in the
most direct and straightforward way I could. Anything more
would serve to dilute the answer, and thereby lessen its
value.
 
Reply With Quote
 
W. eWatson
Guest
Posts: n/a
 
      07-20-2013
On 7/19/2013 12:40 AM, (E-Mail Removed) wrote:
> On Friday, 19 July 2013 04:59:43 UTC+1, W. eWatson wrote:
>
>> ... is sscanf a typo for fscanf?

>
> Nope. See for example <http://linux.die.net/man/3/sscanf> - sscanf() allows you to scan a string for data rather than reading from stdin or some other file.
>
> Parts of section 12 of the C-FAQ <http://c-faq.com> may help you understand why this is a good thing.
>

OK, I thought I'd give sscanf a try. It must be a somewhat new function
to C. My old C book dated 1992 doesn't mention it.

Anyway I wrote the following program test.c to read the test.dat file
below. sscanf is used, but the printf goes looney when executed.

/* test.c */
#include<stdio.h>
#include<stdlib.h>

int
main(void)
{
float pxm[2][80];
int i,j,k;
float value;
char str[70];
FILE *p;

if((p=fopen("test_array.dat","r"))==NULL){
printf("\nUnable to open file test_array.dat");
exit(1);
}

while(fgets(str,70,p)!=NULL){
sscanf(str,"%5.1f", &value);
printf("value = %5.1f \n", value);
}
fclose(p);
exit(0);
}

test.dat.
100.0 35.3 3.1
18.2 41.7 27.4
986.3 11.6 21.0
 
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
Reading a file and resuming reading. Karim Ali Python 2 05-25-2007 02:04 PM
UnauthorizedAccessException when reading XML files (no problem when reading other file-types) blabla120@gmx.net ASP .Net 0 09-15-2006 02:08 PM
An Automated process of watching a network file folder, reading a file in it and deleting the file using ASP.NET ? Luis Esteban Valencia Muņoz ASP .Net 3 06-04-2005 10:56 AM
reading the DB vs. reading a text file...performance preference? Darrel ASP .Net 3 11-11-2004 02:27 PM
reading output file data as input data Stephen Moon Perl Misc 5 02-29-2004 02:16 PM



Advertisments