468,278 Members | 1,582 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,278 developers. It's quick & easy.

C File I/O... working with array structures

Hi, I have a array structure called people

It is properly initialized to 100 array structure elements. Now, I'm
reading in from the command line a txt file, and I get them to open
correctly. In this .txt file, there is a name and a weight.

Josh 123.32
Jim 212.123
Steph 213.2

.... etc.

Now, I have this code:

FILE *ptr, *ptr1;
ptr = fopen(argv[1], "r"); //argv[1] is the txt file with al the
people/weight

while( (fscanf(ptr, "%s %f", people[i].name, &people[i].weight)) == 1
)
{
printf("%s %f", people[i].name, people[i].weight);
i += 1;
}
Why doesn't this work? Nothing gets printed out.

Nov 30 '06 #1
10 1441
pa******@gmail.com said:

<snip>
>
FILE *ptr, *ptr1;
ptr = fopen(argv[1], "r"); //argv[1] is the txt file with al the
people/weight
It's no big deal on this occasion, but in general it is wise to avoid //
comments in Usenet articles - they tend to wrap, making it difficult for
others to compile your code. Furthermore, they provoke diagnostic messages
from C90-conforming implementations.
>
while( (fscanf(ptr, "%s %f", people[i].name, &people[i].weight)) == 1
)
Two problems here. Firstly, you said you have 100 elements in your struct
array. What happens if i ever becomes 100?

The second problem is that you're asking fscanf to convert TWO input fields,
not one, so you should be comparing its return value against 2, not 1. And
that's why you're not getting any output - the loop is failing on the first
fscanf call. Do this instead:

while(i < 100 &&
fscanf(ptr,
"%s %f",
people[i].name,
&people[i].weight) == 2)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Nov 30 '06 #2
pa******@gmail.com writes:
Hi, I have a array structure called people
What is an "array structure"? I think you mean an array of structures
(i.e., an array whose elements are structures), but you should say so.
It is properly initialized to 100 array structure elements. Now, I'm
reading in from the command line a txt file, and I get them to open
correctly. In this .txt file, there is a name and a weight.

Josh 123.32
Jim 212.123
Steph 213.2

... etc.

Now, I have this code:

FILE *ptr, *ptr1;
You don't use ptr1.
ptr = fopen(argv[1], "r"); //argv[1] is the txt file with al the
people/weight
fopen() can fail. You don't check the result.
while( (fscanf(ptr, "%s %f", people[i].name, &people[i].weight)) == 1
)
fscanf() returns the number of input items assigned, or EOF (a
negative value) if a failure occurs before any conversion. If this
call successfully reads the name and the weight, it will return 2, and
your while loop will never execute.
{
printf("%s %f", people[i].name, people[i].weight);
i += 1;
There's nothing wrong with "i += 1;", but "i++;" is more idiomatic.
}
Why doesn't this work? Nothing gets printed out.
See above.

Also, fscanf() doesn't deal well with input errors. It isn't
line-oriented; it skips whitespace (in most cases) before reading an
item, and that can include one or more newlines. The "%s" format is
dangerous; it reads a single whitespace-delimited string (e.g., given
"John Smith" it will only read the "John"), but it specifies no limit
on the size of the string. If you've allocated 20 characters for
people[i].name, but the input string is 25 characters, you'll clobber
adjacent memory, with arbitrarily bad results.

Is the "name" member a character array or a pointer? If it's a
pointer, you need to allocate memory for it explicitly before you read
a value into it. Either way, you can and should tell fscanf not to
read more characters than it can hold (see the documentation for the
syntax).

Another option is to read a line at a time using fgets() and then use
sscanf() to parse it. fgets() has some problems with long lines;
there are a number of workarounds if that's an issue. (See
CBFalconer's ggets(), for example.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 30 '06 #3

Hi, I've sent you an e-mail of my code and supporting information.
Thanks :)

On Nov 29, 9:08 pm, Richard Heathfield <r...@see.sig.invalidwrote:
padh....@gmail.com said:

<snip>
FILE *ptr, *ptr1;
ptr = fopen(argv[1], "r"); //argv[1] is the txt file with al the
people/weightIt's no big deal on this occasion, but in general it is wise to avoid //
comments in Usenet articles - they tend to wrap, making it difficult for
others to compile your code. Furthermore, they provoke diagnostic messages
from C90-conforming implementations.
while( (fscanf(ptr, "%s %f", people[i].name, &people[i].weight)) == 1
)Two problems here. Firstly, you said you have 100 elements in your struct
array. What happens if i ever becomes 100?

The second problem is that you're asking fscanf to convert TWO input fields,
not one, so you should be comparing its return value against 2, not 1. And
that's why you're not getting any output - the loop is failing on the first
fscanf call. Do this instead:

while(i < 100 &&
fscanf(ptr,
"%s %f",
people[i].name,
&people[i].weight) == 2)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999http://www.cpax.org.uk
email: rjh at the above domain, - www.
Nov 30 '06 #4
pa******@gmail.com wrote:
Please don't top-post. Also don't quote the sigs unless your commenting
on them.
On Nov 29, 9:08 pm, Richard Heathfield <r...@see.sig.invalidwrote:
padh....@gmail.com said:

<snip>
FILE *ptr, *ptr1;
ptr = fopen(argv[1], "r"); //argv[1] is the txt file with al the
people/weightIt's no big deal on this occasion, but in general it is wise to avoid //
comments in Usenet articles - they tend to wrap, making it difficult for
others to compile your code. Furthermore, they provoke diagnostic messages
from C90-conforming implementations.
Hi, I've sent you an e-mail of my code and supporting information.
Thanks :)
Why? What's wrong with posting to the group and letting others give
their opinions?

Nov 30 '06 #5
On Thu, 30 Nov 2006 02:08:42 +0000, Richard Heathfield
<rj*@see.sig.invalidwrote:
>pa******@gmail.com said:

<snip>
>>
FILE *ptr, *ptr1;
ptr = fopen(argv[1], "r"); //argv[1] is the txt file with al the
people/weight

It's no big deal on this occasion, but in general it is wise to avoid //
comments in Usenet articles - they tend to wrap, making it difficult for
others to compile your code. Furthermore, they provoke diagnostic messages
from C90-conforming implementations.
It's trivial to handle this: if your C90-conforming implementation
does not support // comments, just upgrade to their C99-conforming
implementation :^)

--
jay
I use // comments and I've never had to upgrade!
Nov 30 '06 #6
jaysome said:

<snip>
>
It's trivial to handle this: if your C90-conforming implementation
does not support // comments, just upgrade to their C99-conforming
implementation :^)
My C90-conforming implementation has no C99-conforming equivalent.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Nov 30 '06 #7
Richard Heathfield <rj*@see.sig.invalidwrites:
jaysome said:

<snip>
>>
It's trivial to handle this: if your C90-conforming implementation
does not support // comments, just upgrade to their C99-conforming
implementation :^)

My C90-conforming implementation has no C99-conforming equivalent.
And even if it did, it wouldn't handle // comments that had been
broken by line-wrapping.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 30 '06 #8
pa******@gmail.com said:
>
Hi, I've sent you an e-mail of my code and supporting information.
Presumably, then, you have a follow-up question, but it's not easy to see
what that is. Here are the results of my compilation:

bio1.c: In function `main':
bio1.c:53: warning: double format, different type arg (arg 2)
bio1.c:14: warning: unused parameter `argc'
bio1.c:56: warning: control reaches end of non-void function

The principal line it is complaining about is this:

printf("%f %s\n", acids[i].count, acids[i].name);

where you try to print an int value as if it were a double. The format
specifier for double is %f, but acids[i].count has type int. What is the
correct printf format specifier for int? (Use one side of the paper only. 3
marks. The use of calculators is not permitted.)

The other problems it is complaining about are these: you define, but don't
use, a parameter called argc. The solution is to use it, and there's an
excellent reason why you should: if argc is 2 or less, then your second
fopen call will fail. If it's 1 or less, your first fopen call will fail.
So it's a good idea to check argc before dooming your program to disaster.

Also, note that you have - perfectly correctly - defined main to return int,
as is right and proper and well-defined (unlike any other return type for
main). When we say a function returns a value of a given type, it's good to
return a value of that type from that function. So, just after your final
printf("\n"); but before your closing brace, why not add this line?

return 0;

to indicate (perhaps a trifle optimistically) that your program succeeded in
executing correctly and producing the desired results?

Once you have made these corrections, however, you will notice that your
program continues to produce incorrect results. Just because a program
compiles cleanly (at a decent warning level), that doesn't mean it's
correct! The most obvious problem is that you carefully count (using the
object known as i) how much data you read in - how many records, how many
lines, whatever you want to call it - but then you discard that
information, re-using i as a counter in the next loop. So your program
forgets how many of the 100 available array elements it actually used, and
instead tries to print all 100, most of which are likely to contain
indeterminate values.

After modifying your program to store that value (the number of lines read)
instead of discarding it, and using it in the conditional expression of
subsequent loops, I was able to run your program with what look like
correct results. I suggest, therefore, that you do the same.

One last thing: in future, if you wish to use me as a private consultant, it
might be wiser to find out my fee scale in advance.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Nov 30 '06 #9
Richard Heathfield wrote:
pa******@gmail.com said:
>Hi, I've sent you an e-mail of my code and supporting information.
.... snip ...
>
One last thing: in future, if you wish to use me as a private
consultant, it might be wiser to find out my fee scale in advance.
At a guess, you spent less than a half day on it, so a minimum
charge (for such a half day) would be reasonable. Padh.ayo should
probably forward you about 400 pounds Sterling. I suggest he use
Paypal.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Nov 30 '06 #10
jaysome wrote:
Richard Heathfield <rj*@see.sig.invalidwrote:
>pa******@gmail.com said:

<snip>
>>>
FILE *ptr, *ptr1;
ptr = fopen(argv[1], "r"); //argv[1] is the txt file with al the
people/weight

It's no big deal on this occasion, but in general it is wise to
avoid // comments in Usenet articles - they tend to wrap, making
it difficult for others to compile your code. Furthermore, they
provoke diagnostic messages from C90-conforming implementations.

It's trivial to handle this: if your C90-conforming implementation
does not support // comments, just upgrade to their C99-conforming
implementation :^)
How did you manage to compile "people/weight"? They seem to be
undefined. I am omitting any discussion as to the availability of
that C99-conforming implementation.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Nov 30 '06 #11

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

9 posts views Thread by Brian | last post: by
7 posts views Thread by Joseph | last post: by
7 posts views Thread by John Dann | last post: by
1 post views Thread by Galen Somerville | last post: by
7 posts views Thread by pereges | last post: by
reply views Thread by NPC403 | last post: by
reply views Thread by zattat | last post: by
1 post views Thread by MrBee | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.