By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,936 Members | 2,023 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,936 IT Pros & Developers. It's quick & easy.

Reading a file...

P: n/a
Hi all, I'm not a newbie with C, but I don't use it since more than 5 years...

I'm trying to read a text file which has doubles in it:

1.0 1.1 1.2 1.3 1.4
2.0 2.1 2.2 2.3 2.4
I'm doing this (it's only a test trying to achieve the goal...):

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

int main () {
FILE* pFile;
long lSize;
double* buffer;

pFile = fopen ( "fichero_test.txt" , "r" );
if (pFile==NULL) exit (1);

// obtain file size.
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);

// allocate memory to contain the whole file.
buffer = (double*) malloc (lSize);
if (buffer == NULL) exit (2);

// copy the file into the buffer.
fread (buffer,1,lSize,pFile);
printf("Pos 2 - %lf\n", buffer[2]);
printf("Pos 2 - %lf\n", buffer[sizeof(double)*2]);

// terminate
fclose (pFile);
free (buffer);
return 0;
}

The output is:

Pos 2 - 0.000000
Pos 2 - 0.000000

What am I doing wrong?, Can I read the whole file into a buffer?

Mar 22 '06 #1
Share this Question
Share on Google+
21 Replies


P: n/a
EdUarDo wrote:
Hi all, I'm not a newbie with C, but I don't use it since more than 5 years...
you have some severe misconceptions about how C i/o works. I recomend
you get yourself a good book (eg K&R) which will explain things
clearly.
I'm trying to read a text file which has doubles in it:

1.0 1.1 1.2 1.3 1.4
2.0 2.1 2.2 2.3 2.4
to be honest the simplest method is something like:-

void read_line (double dd [5], FILE *f)
{
if (fscanf(f, "%lf %lf %lf %lf %lf", &dd[0], &dd[1], &dd[2],
&dd[3], &dd[4)
!= 5)
{
exit (EXIT_FAILURE);
}
}

code is untested, uncompiled etc.
I'm doing this (it's only a test trying to achieve the goal...):

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

int main () {
int main (void)

is better style
FILE* pFile;
long lSize;
double* buffer;

pFile = fopen ( "fichero_test.txt" , "r" );
if (pFile==NULL) exit (1);
error checking, good!

// obtain file size.
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);
I'm not certain this works on a text file...

// allocate memory to contain the whole file.
buffer = (double*) malloc (lSize);
don't cast malloc()
if (buffer == NULL) exit (2);

// copy the file into the buffer.
fread (buffer,1,lSize,pFile);
printf("Pos 2 - %lf\n", buffer[2]);
so you've read about 40 characters into a buffer. Why do you expect to
find and doubles in the buffer? In ascii that's something like

31 2E 30 20 31 2E 31 etc.

(yes I know it doesn't have to be ascii but I thought this made the
point
better than '1' '.' '0' ' ' '1' '.' '1' etc. you disagree?)

You can't jsut stuff characters into a buffer and expect sane results.
printf("Pos 2 - %lf\n", buffer[sizeof(double)*2]);
// terminate
fclose (pFile);
free (buffer);
return 0;
}

The output is:

Pos 2 - 0.000000
Pos 2 - 0.000000

What am I doing wrong?, Can I read the whole file into a buffer?


yes, but you have to convert from characters to double. The best
combination is fgets() to read a line followed by sscanf() to parse the
line.
Always check the return value of sscanf().

--
Nick Keighley

Mar 22 '06 #2

P: n/a
> you have some severe misconceptions about how C i/o works. I recomend
you get yourself a good book (eg K&R) which will explain things
clearly.
Sure, now I'm used to other languages and indeed I don't remember anything about C I/O
1.0 1.1 1.2 1.3 1.4
2.0 2.1 2.2 2.3 2.4

void read_line (double dd [5], FILE *f)
{
if (fscanf(f, "%lf %lf %lf %lf %lf", &dd[0], &dd[1], &dd[2],
&dd[3], &dd[4)
!= 5)
{
exit (EXIT_FAILURE);
}
}


Well, it doesn't works for me because the real file could have 5, 6 or 1000 items per line.
// obtain file size.
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);

I'm not certain this works on a text file...


It does...


// allocate memory to contain the whole file.
buffer = (double*) malloc (lSize);

don't cast malloc()


ok
You can't jsut stuff characters into a buffer and expect sane results.
Yeah, I guess that, but I wasn't sure of it, that's the reason I've asked for help....
yes, but you have to convert from characters to double. The best
combination is fgets() to read a line followed by sscanf() to parse the
line.
I suppose there isn't a readLine function, so I'll need to read until I reach a '\n' character, isn't it?
Always check the return value of sscanf().


Mar 22 '06 #3

P: n/a
EdUarDo wrote:
Hi all, I'm not a newbie with C, but I don't use it since more than 5
years...
I'm trying to read a text file which has doubles in it:

1.0 1.1 1.2 1.3 1.4
2.0 2.1 2.2 2.3 2.4
I'm doing this (it's only a test trying to achieve the goal...):

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

int main () {
FILE* pFile;
long lSize;
double* buffer;

pFile = fopen ( "fichero_test.txt" , "r" );
if (pFile==NULL) exit (1);

// obtain file size.
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);

// allocate memory to contain the whole file.
buffer = (double*) malloc (lSize);
if (buffer == NULL) exit (2);

// copy the file into the buffer.
fread (buffer,1,lSize,pFile);
printf("Pos 2 - %lf\n", buffer[2]);
printf("Pos 2 - %lf\n", buffer[sizeof(double)*2]);

// terminate
fclose (pFile);
free (buffer);
return 0;
}

The output is:

Pos 2 - 0.000000
Pos 2 - 0.000000

What am I doing wrong?, Can I read the whole file into a buffer?


Does this thread on 'c file reading' help?

http://groups.google.com/group/comp....41f9f1ba8ac3d9
--
==============
Not a pedant
==============
Mar 22 '06 #4

P: n/a
> Does this thread on 'c file reading' help?

Yes, thanks.
Mar 22 '06 #5

P: n/a
EdUarDo wrote:
Hi all, I'm not a newbie with C, but I don't use it since more than 5 years...

I'm trying to read a text file which has doubles in it:

1.0 1.1 1.2 1.3 1.4
2.0 2.1 2.2 2.3 2.4
I'm doing this (it's only a test trying to achieve the goal...):

#include <stdio.h>
#include <stdlib.h>
int main () { FILE* pFile;
long lSize;
double* buffer;

pFile = fopen ( "fichero_test.txt" , "r" );
if (pFile==NULL) exit (1);


exit(EXIT_FAILURE) or return EXIT_FAILURE might be more portable.
// obtain file size.
Same for the comment syntax.
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);
I don't know how well this will work. Unless your file is very large,
why not calculate it's size by reading each byte till EOF?
// allocate memory to contain the whole file.
buffer = (double*) malloc (lSize);
The cast is unnecessary and might hide the failure to include stdlib.h,
which on some systems might result in the compiler using the wrong
value as the return from malloc().
if (buffer == NULL) exit (2);
See comment about exit().
// copy the file into the buffer.
fread (buffer,1,lSize,pFile);
printf("Pos 2 - %lf\n", buffer[2]);
printf("Pos 2 - %lf\n", buffer[sizeof(double)*2]);
Here's your problem. The values read from the file will be present as
characters in memory. But you supply a conversion specifier doubles.
You'll need to convert the values using possibly sscanf() or strtod()
and then display them.
What am I doing wrong?, Can I read the whole file into a buffer?


If you allocated the required memory, then yes, you can.

Mar 22 '06 #6

P: n/a
Since my last reply apparently got lost in the aether...

EdUarDo wrote:
Hi all, I'm not a newbie with C, but I don't use it since more than 5 years...

I'm trying to read a text file which has doubles in it:

1.0 1.1 1.2 1.3 1.4
2.0 2.1 2.2 2.3 2.4
I'm doing this (it's only a test trying to achieve the goal...):

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

int main () {
FILE* pFile;
long lSize;
double* buffer;

pFile = fopen ( "fichero_test.txt" , "r" );
if (pFile==NULL) exit (1);

// obtain file size.
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);

// allocate memory to contain the whole file.
buffer = (double*) malloc (lSize);
Unless you're using a pre-C89 compiler (or C++), don't cast the result
of malloc. You don't need to, and doing so can mask an error if you
forget to include stdlib.h.
if (buffer == NULL) exit (2);

Okay, first problem: the size of the file does not correspond to the
number of double values represented in that file. You have 10 strings
representing double values taking up (at least) 40 bytes. So sizing
your buffer based on the number of bytes in the file isn't going to do
what you want.

You're better off by allocating a small buffer and extending it with
realloc() as you read from the file. Granted, storing the contents of
an entire file in memory isn't terribly scalable whether you allocate
the memory in one huge gulp or in smaller chunks, but at least this way
you'll be allocating the right amount.
// copy the file into the buffer.
fread (buffer,1,lSize,pFile);
Second problem: fread() does not convert the text representation of a
double value ("1.23") to the equivalent value (1.23). Basically what
you're doing is interpreting the bytes for "1.0 1.1 1.2..." as a series
of doubles, which is going to give you gibberish.
printf("Pos 2 - %lf\n", buffer[2]);
printf("Pos 2 - %lf\n", buffer[sizeof(double)*2]);

// terminate
fclose (pFile);
free (buffer);
return 0;
}

The output is:

Pos 2 - 0.000000
Pos 2 - 0.000000

What am I doing wrong?, Can I read the whole file into a buffer?


Here's how I'd write it (uncompiled, untested, all the usual caveats
apply):

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

#define BASE 10
#define EXTENT 5

int main(void)
{
double *buffer = NULL;
file *pFile = NULL;
size_t curSize = BASE;
size_t index = 0;
int moreData = 1;

if ((pFile = fopen("fichero_test.txt", "r")) == NULL)
{
fprintf(stderr, "Could not open fichero_test.txt!\n");
return EXIT_FAILURE;
}

/*
* Allocate the buffer at its initial size.
*/
buffer = malloc(sizeof *buffer * curSize);
if (!buffer)
{
fprintf(stderr, "Could not allocate initial buffer!\n");
return EXIT_FAILURE;
}

while (moreData)
{
/*
* Extend the buffer as necessary.
*/
if (index == curSize)
{
double *tmp = realloc(buffer, sizeof *buffer * (curSize +
EXTENT));
if (tmp)
{
buffer = tmp;
curSize += EXTENT;
}
else
{
fprintf(stderr, "Could not extend buffer past %lu
bytes; exiting...\n", curSize);
free(buffer);
return EXIT_FAILURE;
}
}

/*
* To keep this example simple, we're going to assume
* that the input file is *always* well-formatted, and
* that we don't have to handle any malformed
* strings.
*/
if (fscanf(pFile, "%f", &buffer[index++]) == 0)
{
/*
* Previous read failed; either we hit
* EOF or there was an error. Either
* way we're going to break out of the loop.
*/
if (feof(pFile))
{
fprintf(stderr, "Hit end-of-file...exiting loop\n");
}
else
{
fprintf(stderr, "Error reading from file...exiting
loop\n");
}
moreData = 0;
}
}

fprintf(stdout, "Read %lu doubles from input file.\n", index+1);
fprintf(stdout, "buffer[%lu] = %f\n", index, buffer[index]);

free(buffer);
fclose(pFile);

return EXIT_SUCCESS;
}

Mar 22 '06 #7

P: n/a

"EdUarDo" <ed*****************@NOSPAMgmail.com> wrote in message
news:48************@individual.net...
Hi all, I'm not a newbie with C, but I don't use it since more than 5
years...

I'm trying to read a text file which has doubles in it:

1.0 1.1 1.2 1.3 1.4
2.0 2.1 2.2 2.3 2.4
I'm doing this (it's only a test trying to achieve the goal...):

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

int main () {
FILE* pFile;
long lSize;
double* buffer;

pFile = fopen ( "fichero_test.txt" , "r" );
if (pFile==NULL) exit (1);

// obtain file size.
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);

// allocate memory to contain the whole file.
buffer = (double*) malloc (lSize); Don't cast malloc!

lSize is now set to the number of characters in the file.
What does this have to do with the number of values that represent real
numbers?
(Answer: nothing, other than a upper limit to the possible number of values)

if (buffer == NULL) exit (2);

// copy the file into the buffer.
fread (buffer,1,lSize,pFile);
Why are yoiu using fread? fread is for reading binary data.
You have already stated that the file is text.
printf("Pos 2 - %lf\n", buffer[2]);
printf("Pos 2 - %lf\n", buffer[sizeof(double)*2]);

// terminate
fclose (pFile);
free (buffer);
return 0;
}

The output is:

Pos 2 - 0.000000
Pos 2 - 0.000000

What am I doing wrong?, Can I read the whole file into a buffer?


If the number of values per line is not relevant and all you want to do is
just read all of the double values, you could just loop
forever using fscanf() until you get EOF. Your buffer is guaranteed
to be large enough (way too large, as a matter of fact).

A better way might be to start with a small buffer, read until it is
full, then realloc it by some increment, keeping track of the current size
and the current number of items reads.

--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Technical Architect, Software Reuse Project

Mar 22 '06 #8

P: n/a
John Bode wrote:
Since my last reply apparently got lost in the aether...

EdUarDo wrote:
Hi all, I'm not a newbie with C, but I don't use it since more than 5 years...

I'm trying to read a text file which has doubles in it:

1.0 1.1 1.2 1.3 1.4
2.0 2.1 2.2 2.3 2.4

Here's how I'd write it (uncompiled, untested, all the usual caveats
apply):

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

#define BASE 10
#define EXTENT 5

int main(void)
{
double *buffer = NULL;
file *pFile = NULL;
size_t curSize = BASE;
size_t index = 0;
int moreData = 1;

if ((pFile = fopen("fichero_test.txt", "r")) == NULL)
{
fprintf(stderr, "Could not open fichero_test.txt!\n");
return EXIT_FAILURE;
}

/*
* Allocate the buffer at its initial size.
*/
buffer = malloc(sizeof *buffer * curSize);
if (!buffer)
{
fprintf(stderr, "Could not allocate initial buffer!\n");
return EXIT_FAILURE;
}

while (moreData)
{
/*
* Extend the buffer as necessary.
*/
if (index == curSize)
{
double *tmp = realloc(buffer, sizeof *buffer * (curSize +
EXTENT));
if (tmp)
{
buffer = tmp;
curSize += EXTENT;
}
else
{
fprintf(stderr, "Could not extend buffer past %lu
bytes; exiting...\n", curSize);
free(buffer);
return EXIT_FAILURE;
}
}

/*
* To keep this example simple, we're going to assume
* that the input file is *always* well-formatted, and
* that we don't have to handle any malformed
* strings.
*/
if (fscanf(pFile, "%f", &buffer[index++]) == 0)
{
/*
* Previous read failed; either we hit
* EOF or there was an error. Either
* way we're going to break out of the loop.
*/
if (feof(pFile))
{
fprintf(stderr, "Hit end-of-file...exiting loop\n");
}
else
{
fprintf(stderr, "Error reading from file...exiting
loop\n");
}
moreData = 0;
}
}

fprintf(stdout, "Read %lu doubles from input file.\n", index+1);
fprintf(stdout, "buffer[%lu] = %f\n", index, buffer[index]);

free(buffer);
fclose(pFile);

return EXIT_SUCCESS;
}


D:\Files\src\C\tmp\fischero>gcc -Wall -ansi -pedantic -o fichero.exe
fichero.c
fichero.c: In function `main':
fichero.c:47: warning: long unsigned int format, size_t arg (arg 3)
fichero.c:59: warning: float format, double arg (arg 3)
fichero.c:78: warning: long unsigned int format, size_t arg (arg 3)
fichero.c:79: warning: long unsigned int format, size_t arg (arg 3)

Running the output, fichero.exe just hangs with 100% CPU usage, until
it's killed with CTRL-C.

Mar 22 '06 #9

P: n/a
John Bode wrote:
Since my last reply apparently got lost in the aether...
Here's how I'd write it (uncompiled, untested, all the usual caveats
apply):

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

#define BASE 10
#define EXTENT 5

int main(void)
{
double *buffer = NULL;
file *pFile = NULL;
size_t curSize = BASE;
size_t index = 0;
int moreData = 1;

if ((pFile = fopen("fichero_test.txt", "r")) == NULL)
{
fprintf(stderr, "Could not open fichero_test.txt!\n");
return EXIT_FAILURE;
}

/*
* Allocate the buffer at its initial size.
*/
buffer = malloc(sizeof *buffer * curSize);
if (!buffer)
{
fprintf(stderr, "Could not allocate initial buffer!\n");
return EXIT_FAILURE;
}

while (moreData)
{
/*
* Extend the buffer as necessary.
*/
if (index == curSize)
{
double *tmp = realloc(buffer, sizeof *buffer * (curSize +
EXTENT));
if (tmp)
{
buffer = tmp;
curSize += EXTENT;
}
else
{
fprintf(stderr, "Could not extend buffer past %lu
bytes; exiting...\n", curSize);
free(buffer);
return EXIT_FAILURE;
}
}

/*
* To keep this example simple, we're going to assume
* that the input file is *always* well-formatted, and
* that we don't have to handle any malformed
* strings.
*/
if (fscanf(pFile, "%f", &buffer[index++]) == 0)
What if EOF is returned? Better to store the return value into a
temporary and check against both zero and EOF. I did that and it fixed
the infinite loop hang mentioned in the previous post.
{
/*
* Previous read failed; either we hit
* EOF or there was an error. Either
* way we're going to break out of the loop.
*/
if (feof(pFile))
{
fprintf(stderr, "Hit end-of-file...exiting loop\n");
}
else
{
fprintf(stderr, "Error reading from file...exiting
loop\n");
}
moreData = 0;
}
}

fprintf(stdout, "Read %lu doubles from input file.\n", index+1);
fprintf(stdout, "buffer[%lu] = %f\n", index, buffer[index]);


Both these fprintf() statements print the wrong values, even if an
empty file is given.
I think the problem lies in the use of the variable 'index'.

Mar 22 '06 #10

P: n/a

santosh wrote:
John Bode wrote:
Since my last reply apparently got lost in the aether...
Here's how I'd write it (uncompiled, untested, all the usual caveats
apply):

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

#define BASE 10
#define EXTENT 5

int main(void)
{
double *buffer = NULL;
file *pFile = NULL;
size_t curSize = BASE;
size_t index = 0;
int moreData = 1;

if ((pFile = fopen("fichero_test.txt", "r")) == NULL)
{
fprintf(stderr, "Could not open fichero_test.txt!\n");
return EXIT_FAILURE;
}

/*
* Allocate the buffer at its initial size.
*/
buffer = malloc(sizeof *buffer * curSize);
if (!buffer)
{
fprintf(stderr, "Could not allocate initial buffer!\n");
return EXIT_FAILURE;
}

while (moreData)
{
/*
* Extend the buffer as necessary.
*/
if (index == curSize)
{
double *tmp = realloc(buffer, sizeof *buffer * (curSize +
EXTENT));
if (tmp)
{
buffer = tmp;
curSize += EXTENT;
}
else
{
fprintf(stderr, "Could not extend buffer past %lu
bytes; exiting...\n", curSize);
free(buffer);
return EXIT_FAILURE;
}
}

/*
* To keep this example simple, we're going to assume
* that the input file is *always* well-formatted, and
* that we don't have to handle any malformed
* strings.
*/
if (fscanf(pFile, "%f", &buffer[index++]) == 0)


What if EOF is returned? Better to store the return value into a
temporary and check against both zero and EOF. I did that and it fixed
the infinite loop hang mentioned in the previous post.
{
/*
* Previous read failed; either we hit
* EOF or there was an error. Either
* way we're going to break out of the loop.
*/
if (feof(pFile))
{
fprintf(stderr, "Hit end-of-file...exiting loop\n");
}
else
{
fprintf(stderr, "Error reading from file...exiting
loop\n");
}
moreData = 0;
}
}

fprintf(stdout, "Read %lu doubles from input file.\n", index+1);
fprintf(stdout, "buffer[%lu] = %f\n", index, buffer[index]);


Both these fprintf() statements print the wrong values, even if an
empty file is given.
I think the problem lies in the use of the variable 'index'.


Yeah, that's embarrassing; even though I stated it was untested, I
should have at least built the damn thing once before posting it.

It's a lesson I keep having to relearn.

FWIW, the main problems were that I wasn't checking for EOF (which is
distinct from not being able to convert; shows how long it's been since
I've used fscanf() for anything), and that I was incrementing index one
too many times. So, here's how that section *should* read:

if(fscanf(pFile, "%lf", buffer[index]) != 1)
{
/* feof(), print error messages */
moreData = 0;
}
else
{
index++;
}

...

fprintf(stdout, "Read %lu values\n", (unsigned long) index);
fprintf(stdout, "buffer[%lu] = %lf\n", (unsigned long) index-1,
buffer[index-1]);

Mar 22 '06 #11

P: n/a
EdUarDo wrote:
.... snip ...
yes, but you have to convert from characters to double. The best
combination is fgets() to read a line followed by sscanf() to
parse the line.


I suppose there isn't a readLine function, so I'll need to read
until I reach a '\n' character, isn't it?


Please don't remove attribution lines for material you quote.
Those are the lines that say "joe wrote:" or the equivalent at the
beginning. Also limit your output linelength to under 72 chars, to
survive several quotations without wrapping.

There are several functions in the C library, but the maximum user
simplicity is probably found with my ggets. The source is
completely portable, and is available at:

<http://cbfalconer.home.att.net/download/ggets.zip>

This inputs complete text lines, and assigns the storage for such.
When done with the line just free() it.

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
Mar 23 '06 #12

P: n/a
Hello again, thanks to all for your answers. I've tried to follow all of
your advices and this is the result:

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

#define INITIAL_SIZE 5;

int main(void) {
FILE* fp = NULL;
double number = 0.0;
int read = 0;
double* numbers = NULL;
double* aux = NULL;
int i = 0;
int size = INITIAL_SIZE;

// Opening the file
if((fp = fopen("fichero_test.txt", "rb")) != NULL) {
// Reseve memory
numbers = (double*) calloc(size, sizeof(double));
// Read a number
while (read = fscanf(fp, "%lf", &number) != EOF) {
if (read == 1) {
// Check if needs more memory
if (i >= size) {
size = i + INITIAL_SIZE;
aux = realloc(numbers, sizeof(double) * (size));
if (aux == NULL) {
printf("Memory not available\n");
return EXIT_FAILURE;
} else {
numbers = aux;
}
}
// Save the number read into the buffer
numbers[i++] = number;
}
}

// Display buffer content
size = i - 1;
for (i = 0; i < size; i++) {
printf("Pos %d, value %lf\n", i, numbers[i]);
}

} else {
return EXIT_FAILURE;
}

if (numbers != NULL) {
free(numbers);
}
if (fp != NULL) {
fclose(fp);
}
}

Do I need to cast returned value from calloc?
Mar 23 '06 #13

P: n/a

EdUarDo wrote:

<snip>
Do I need to cast returned value from calloc?


No. If you do, it may hide non-inclusion of <stdlib.h>.

--
BR, Vladimir

Mar 23 '06 #14

P: n/a
>>Do I need to cast returned value from calloc?


No. If you do, it may hide non-inclusion of <stdlib.h>.


Ok.
..... It wasn't so hard my return to C... :), thanks to all.
Mar 23 '06 #15

P: n/a
EdUarDo wrote:

Hello again, thanks to all for your answers. I've tried to follow
all of your advices and this is the result:
.... snip ...
// Opening the file
if((fp = fopen("fichero_test.txt", "rb")) != NULL) {
// Reseve memory .... snip long extended code ...
} else {
return EXIT_FAILURE;
}


Here's a readability tip. When you have a long clause, and a short
clause, arrange to have the short clause first. That way the
reader can quickly determine what controls entry to any particular
clause. The above could be:

if (NULL == (fp = fopen("fichero_test.txt", "rb")))
return EXIT_FAILURE;
else {
... long extended code ...
}

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
Mar 23 '06 #16

P: n/a
On Thu, 23 Mar 2006 10:28:24 +0100, EdUarDo wrote:
// Read a number
while (read = fscanf(fp, "%lf", &number) != EOF) {
if (read == 1) {


This looks a little odd although it is fine. There is no reason to assign
to read the value of the test (fscanf(...) != EOF) since you use read only
on the next line and you can't get to the next line unless read is 1.

while (fscanf(fp, "%lf", &number) != EOF) {

does the same job.

--
Ben.
Mar 24 '06 #17

P: n/a
CBFalconer wrote:
EdUarDo wrote:
Hello again, thanks to all for your answers. I've tried to follow
all of your advices and this is the result:


... snip ...
// Opening the file
if((fp = fopen("fichero_test.txt", "rb")) != NULL) {
// Reseve memory


... snip long extended code ...
} else {
return EXIT_FAILURE;
}

Here's a readability tip. When you have a long clause, and a short
clause, arrange to have the short clause first. That way the
reader can quickly determine what controls entry to any particular
clause. The above could be:

if (NULL == (fp = fopen("fichero_test.txt", "rb")))
return EXIT_FAILURE;
else {
... long extended code ...
}


My preference is to avoid that style altogether:

fp = fopen("fichero_test.txt", "rb");
if ( !fp )
{
return EXIT_FAILURE;
}
else
{
... long extended code ...
}

or just:

if ( !fp )
{
return EXIT_FAILURE;
}

.... long extended code ...

This makes it easier for debugging and jives well with things like
PC-lint and MISRA rules.

YMMV.

--
jay
Mar 24 '06 #18

P: n/a
On Wed, 22 Mar 2006 18:09:45 UTC, "Fred Kleinschmidt"
<fr******************@boeing.com> wrote:
// copy the file into the buffer.
fread (buffer,1,lSize,pFile);


Why are yoiu using fread? fread is for reading binary data.
You have already stated that the file is text.


No, fread is used to read the specified number of blocks in specified
length. fopen() specifies if the file is to read as binary (no
transation is made) or as test (some characters like cr, lf are
translated to the system specific layout.

Yeah, the OP uses the wrong I/O method to get data in as the data he
reads is not of constant length and even the length of the date he has
to read in a line is not constant.

I would not try to read using fscanf() because the variant number of
floats in a line, but would siply use fgetc() like

#define MAXFLOATCHARS 15 /* a double may been ... chars */

/* read a number of of doubles from a file, whereas */
/* the file contains a unknown number of doubles, */
/* separated with white spaces */
/* return: pointer to array containing readed doubles */
/* return parameters: */
/* pointer to number of readed doubles */
/* */
/* remark: caller has to free() result */
double *doubles read_doubles(unsigned int *count_doubles) {
int c;
unsigned int in_double = 0; /* count no. of chars stored */
unsigned int reserved doubles = 0;
char double_as_text[MAXDOUBLECHARS+1]
double *doubles = NULL;

while ((c = fgets(file)) != EOF) {
if (isspace(c)) { /* possible delemitters */
if (in_double) {
/* at least one digit or decimal delemitter readed */
double_as_text[in_double] = '\0';
doubles = conv_a_double(double_as_text,
doubles,
&count_doubles,
&reserved_doubles);
}
in_double = 0;
continue;
}
/* missing: test of guilty char that is possible
for a double (e.g. one decimal delemitter,
exponent char,.... */
double_as_text[in_double++] = c;
}
if (in_double) {
double_as_text[in_double] = '\0';
doubles = conv_a_double(double_as_text, doubles, &count_doubles,
&reserved_doubles);
}
return doubles;
}

/* convert a double from string */
/* parameters: */
/* char *double_as_text string holding a double to convert */
/* double *doubles pointer to array holding doubles */
/* unsigned int count_doubles pointer to no. of readed doubles */
/* unsigned int reserved doubles pointer to no, of reserved d. */
/* return: pointer to array of doubles stored */
/* return parameter: number of doubles reserved in no_of_doubles */
double* conv_a_double(char *double_as_text,
double *doubles,
unsigned int *count_doubles,
unsigned int *reserved doubles) {
double *result;
if ((*reserved_doubles == count_doubles) {
result = realloc(*doubles,
(*reserved_doubles += 100) * sizeof(*result))
if (!result) {
fprintf("failed to allocate enough memory\n");
exit(EXIT_FAILTURE);
}
*doubles = result;
}
sscanf(double_as_text, "%f", &doubles[*count_doubles++]);
return doubles;
}

Untested!

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
Mar 24 '06 #19

P: n/a
CBFalconer <cb********@yahoo.com> wrote:
EdUarDo wrote:

// Opening the file
if((fp = fopen("fichero_test.txt", "rb")) != NULL) {
// Reseve memory
Here's a readability tip. When you have a long clause, and a short
clause, arrange to have the short clause first. That way the
reader can quickly determine what controls entry to any particular
clause. The above could be:

if (NULL == (fp = fopen("fichero_test.txt", "rb")))


Ew. Shades of RPN.

Richard
Mar 24 '06 #20

P: n/a
Ben Bacarisse <be********@bsb.me.uk> writes:
On Thu, 23 Mar 2006 10:28:24 +0100, EdUarDo wrote:
// Read a number
while (read = fscanf(fp, "%lf", &number) != EOF) {
if (read == 1) {


This looks a little odd although it is fine. There is no reason to assign
to read the value of the test (fscanf(...) != EOF) since you use read only
on the next line and you can't get to the next line unless read is 1.

while (fscanf(fp, "%lf", &number) != EOF) {

does the same job.


It seems very likely that EdUarDo wanted:

while((read = fscanf(fp, "%lf", &number)) != EOF) {

In which case, he'll still want to test read on the next line.
Mar 24 '06 #21

P: n/a
On Fri, 24 Mar 2006 20:19:15 +0000, Micah Cowan wrote:
Ben Bacarisse <be********@bsb.me.uk> writes:
On Thu, 23 Mar 2006 10:28:24 +0100, EdUarDo wrote:
> // Read a number
> while (read = fscanf(fp, "%lf", &number) != EOF) {
> if (read == 1) {


This looks a little odd although it is fine. There is no reason to assign
to read the value of the test (fscanf(...) != EOF) since you use read only
on the next line and you can't get to the next line unless read is 1.

while (fscanf(fp, "%lf", &number) != EOF) {

does the same job.


It seems very likely that EdUarDo wanted:

while((read = fscanf(fp, "%lf", &number)) != EOF) {

In which case, he'll still want to test read on the next line.


I agree, and I thought that was the original intent also, but since the
OP's code took no action when 0 is returned (the only other possible value
in this case) I concluded that they were content to assume the input
contains no "matching errors" and I consequently simplified what I had to
write by only offering an equivalent piece of code.

A better answer might have been to add the parentheses and suggest an
action to take when read == 0, or to suggest

while (fscanf(fp, "%lf", &number) == 1)

which at least terminates on all possible inputs! Yes, I should at least
have suggested that.

--
Ben.
Mar 26 '06 #22

This discussion thread is closed

Replies have been disabled for this discussion.