Sorry for the NOOB question..

Z

Zach Heath

I'm just starting C and haven't done programming for a few
years...could you guys please take a look at this? Thanks for your
time!

I have an input file that looks like:

1.5 2.5 Bob, Joe
4.5 5.5 Bob, Jolene

The first time through the do while loop it works fine but the second
time it looks like this:


Bob, Joe 38.50 12.75 490.88
Jolene 0.00 0.00 0.00
, Janet 0.00 0.00 0.00


- It cuts off last name and all of the floats show up zeros...

command line: ./a.out < inputFile.c



int main()
{
float inHrs, inRt, myTot;
char inName[16];

do {
/* while ( fgets(inName, sizeof(inName), stdin) ) {
*/ scanf ( "%f%f", &inHrs, &inRt );
myTot = inHrs * inRt;

fgets( inName, sizeof( inName ), stdin);

char * p = strchr( inName,'\n' );
if ( p != NULL ){
*p = '\0';
};

printf ( "%s\t%4.2f %4.2f %4.2f \n", inName, inHrs,
inRt, myTot );
inHrs = 0;
inRt = 0;
} while ( fgets(inName, sizeof(inName), stdin) != NULL );
/*
};
*/
return 0;
}
 
U

user923005

I'm just starting C and haven't done programming for a few
years...could you guys please take a look at this? Thanks for your
time!

I have an input file that looks like:

1.5 2.5 Bob, Joe
4.5 5.5 Bob, Jolene

The first time through the do while loop it works fine but the second
time it looks like this:

Bob, Joe 38.50 12.75 490.88
Jolene 0.00 0.00 0.00
, Janet 0.00 0.00 0.00

- It cuts off last name and all of the floats show up zeros...

command line: ./a.out < inputFile.c

int main()
{
float inHrs, inRt, myTot;
char inName[16];

do {
/* while ( fgets(inName, sizeof(inName), stdin) ) {
*/ scanf ( "%f%f", &inHrs, &inRt );
myTot = inHrs * inRt;

fgets( inName, sizeof( inName ), stdin);

char * p = strchr( inName,'\n' );
if ( p != NULL ){
*p = '\0';
};

printf ( "%s\t%4.2f %4.2f %4.2f \n", inName, inHrs,
inRt, myTot );
inHrs = 0;
inRt = 0;
} while ( fgets(inName, sizeof(inName), stdin) != NULL );
/*
};
*/
return 0;



}- Hide quoted text -

- Show quoted text -

No need for three fgets() calls per iteration.
Call fgets() once and then parse the string.
Strtok() is probably fine to peel apart the tokens.
You can also use the is*() functions declared in ctype.h such as
isdigit(), isalpha(), ispunct()

In summary:
1. Read a line of input
2. Separate the contents of the line into components. You could use
strtok() or even sscanf()
3. Process the components
4. Get the next line (if any) and repeat.
 
L

Lafatus

I'm just starting C and haven't done programming for a few
years...could you guys please take a look at this? Thanks for your
time!
I have an input file that looks like:
1.5 2.5 Bob, Joe
4.5 5.5 Bob, Jolene
The first time through the do while loop it works fine but the second
time it looks like this:
Bob, Joe 38.50 12.75 490.88
Jolene 0.00 0.00 0.00
, Janet 0.00 0.00 0.00
- It cuts off last name and all of the floats show up zeros...
command line: ./a.out < inputFile.c
int main()
{
float inHrs, inRt, myTot;
char inName[16];
do {
/* while ( fgets(inName, sizeof(inName), stdin) ) {
*/ scanf ( "%f%f", &inHrs, &inRt );
myTot = inHrs * inRt;
fgets( inName, sizeof( inName ), stdin);
char * p = strchr( inName,'\n' );
if ( p != NULL ){
*p = '\0';
};
printf ( "%s\t%4.2f %4.2f %4.2f \n", inName, inHrs,
inRt, myTot );
inHrs = 0;
inRt = 0;
} while ( fgets(inName, sizeof(inName), stdin) != NULL );
/*
};
*/
return 0;
}- Hide quoted text -
- Show quoted text -

No need for three fgets() calls per iteration.
Call fgets() once and then parse the string.
Strtok() is probably fine to peel apart the tokens.
You can also use the is*() functions declared in ctype.h such as
isdigit(), isalpha(), ispunct()

In summary:
1. Read a line of input
2. Separate the contents of the line into components. You could use
strtok() or even sscanf()
3. Process the components
4. Get the next line (if any) and repeat.

Thanks for the help!
 
B

Barry Schwarz

I'm just starting C and haven't done programming for a few
years...could you guys please take a look at this? Thanks for your
time!

I have an input file that looks like:

1.5 2.5 Bob, Joe
4.5 5.5 Bob, Jolene

Since the only input in your code is from stdin, what does this file
have to do with anything.
The first time through the do while loop it works fine but the second
time it looks like this:


Bob, Joe 38.50 12.75 490.88
Jolene 0.00 0.00 0.00
, Janet 0.00 0.00 0.00


- It cuts off last name and all of the floats show up zeros...

command line: ./a.out < inputFile.c



int main()
{
float inHrs, inRt, myTot;
char inName[16];

do {
/* while ( fgets(inName, sizeof(inName), stdin) ) {
*/ scanf ( "%f%f", &inHrs, &inRt );

Exactly what did you type in at this point?
myTot = inHrs * inRt;

fgets( inName, sizeof( inName ), stdin);

And what did you type here?
char * p = strchr( inName,'\n' );
if ( p != NULL ){
*p = '\0';
};

printf ( "%s\t%4.2f %4.2f %4.2f \n", inName, inHrs,
inRt, myTot );
inHrs = 0;
inRt = 0;
} while ( fgets(inName, sizeof(inName), stdin) != NULL );

And what did you type here?

I think at least part of your problem is you have inputs without
prompts and lost track of where you were. Did you remember to type a
dummy name for this last fgets (because the real name comes after you
input the figures)?
/*
};
*/
return 0;
}


Remove del for email
 
A

Army1987

I have an input file that looks like:

1.5 2.5 Bob, Joe
4.5 5.5 Bob, Jolene

Since the only input in your code is from stdin, what does this file
have to do with anything. [snip]
command line: ./a.out < inputFile.c
[snip]
Exactly what did you type in at this point?

Maybe stdin isn't the keyboard in this program?
 
A

Army1987

I have an input file that looks like:

1.5 2.5 Bob, Joe
4.5 5.5 Bob, Jolene

The first time through the do while loop it works fine but the second
time it looks like this:


Bob, Joe 38.50 12.75 490.88
Jolene 0.00 0.00 0.00
, Janet 0.00 0.00 0.00


- It cuts off last name and all of the floats show up zeros...

command line: ./a.out < inputFile.c [removing comments]
int main()
{
float inHrs, inRt, myTot;
char inName[16];

do {
scanf ( "%f%f", &inHrs, &inRt );
The first time, you read 1.5 and 2.5. All fine.
myTot = inHrs * inRt;

fgets( inName, sizeof( inName ), stdin);
Now you read up to the end of the line. Still fine.
char * p = strchr( inName,'\n' );
if ( p != NULL ){
*p = '\0';
};

printf ( "%s\t%4.2f %4.2f %4.2f \n", inName, inHrs,
inRt, myTot );
inHrs = 0;
inRt = 0; Here you assign 0 to those.
} while ( fgets(inName, sizeof(inName), stdin) != NULL );
This will read the first 15 characters of the next line. After
them, scanf won't be able to find any float in the input, and will
fail. inHrs and inRt stay zero. myTot becomes 0, and fgets() reads
up to 15 characters till the end of the line, that is "Jolene\n".

You didn't actually mean do { ... } while (fgets(...)), did you?
 
L

Lafatus

I wasn't really planning on using a do/while, I wanted to use a while
loop but reached that point where I was trying everything and was
getting frustrated that I couldn't complete such a simple program.

I'm supposed to use stdin, however, it isn't the keyboard. It's
supposed to be the input from the file.
 
C

Charlie Gordon

Lafatus said:
I wasn't really planning on using a do/while, I wanted to use a while
loop but reached that point where I was trying everything and was
getting frustrated that I couldn't complete such a simple program.

As a rule of thumb, do/while loops are more difficult master than regular
while or far loops.

Your problem can typically be solved with a while loop:

while (fgets(buf, sizeof buf, fp)) {
// parse the buffer and perform appropriate task or report error
}
 
C

CBFalconer

Lafatus said:
I wasn't really planning on using a do/while, I wanted to use a while
loop but reached that point where I was trying everything and was
getting frustrated that I couldn't complete such a simple program.

I'm supposed to use stdin, however, it isn't the keyboard. It's
supposed to be the input from the file.

This is a meaningless message, because Usenet is a 'best efforts'
delivery mechanism, with no guarantees. There is no reason to
assume your readers have ever seen, or ever will see, any previous
messages in the thread. This is why the practice is to always
quote enough of the previous message so that the complete message
makes sense standing by itself.

You should also realize that google is not the messageing system,
it is only a rather poor form of message reader, with which you can
interface via http. It is so bad, and attracts so many Usenet
ignorant newbies, that many readers simply ban all messages
originating on google. So you would be well advised to get a
proper Usenet message reader, such as Thunderbird.
 
K

Keith Thompson

Charlie Gordon said:
As a rule of thumb, do/while loops are more difficult master than regular
while or far loops.

Let me guess, "far loops" are a DOS-specific extension that allows the
code for the loop body to span more than one memory segment, right?

(In case anyone is confused, that was a joke; "far loops" is a typo
for "for loops".)
 
C

Charlie Gordon

Keith Thompson said:
Let me guess, "far loops" are a DOS-specific extension that allows the
code for the loop body to span more than one memory segment, right?

You too remember the Pharlap days ;-)
(In case anyone is confused, that was a joke; "far loops" is a typo
for "for loops".)

yes, many typos in this post (un loupé)

As a rule of thumb, do/while loops are more difficult to master than regular
while or for loops.
 
K

Keith Thompson

CBFalconer said:
You should also realize that google is not the messageing system,
it is only a rather poor form of message reader, with which you can
interface via http. It is so bad, and attracts so many Usenet
ignorant newbies, that many readers simply ban all messages
originating on google. So you would be well advised to get a
proper Usenet message reader, such as Thunderbird.

That's a trifle overstated. It is possible to post properly to Usenet
using Google Groups. (But I think the folks who manage to do so are
mostly people who have used real newsreaders in the past.)

The previous poster erred in posting a followup with no context, but
that's not Google's fault; the misfeature that encouraged this was
corrected some time ago, and it's a mistake that can easily be made
with a real newsreader as well.

See <http://cfaj.freeshell.org/google/>.
 
C

CBFalconer

Charlie said:
.... snip much banditry ...

yes, many typos in this post (un loupé)

As a rule of thumb, do/while loops are more difficult to master
than regular while or for loops.

Why should you think that? "do { something() } while(foo);" is no
more complex than "while (foo) {something())". The only difference
is that the foo test is applied after execution in the do/while
loop, and before execution in the while loop.
 
C

CBFalconer

Keith said:
That's a trifle overstated. It is possible to post properly to
Usenet using Google Groups. (But I think the folks who manage to
do so are mostly people who have used real newsreaders in the past.)

But finding out how to post properly through Google will not get
anyone past the traps set to eliminate all google posters. A
proper newsreader will.
 
C

Charlie Gordon

CBFalconer said:
Why should you think that? "do { something() } while(foo);" is no
more complex than "while (foo) {something())". The only difference
is that the foo test is applied after execution in the do/while
loop, and before execution in the while loop.

My own experience proofreading millions on lines of C code tells me that.
It is not a matter of complexity... it is just more error prone.
do/while loops written by average programmers tend to have more bugs than
regular for or while loops.
do/while loops produced by newbies tend to be always wrong.
A great classic is this:

int c;
/* skip to end of line */
do {
c = getc(fp);
} while (c != '\n');

Of course regular while loops can be bogus too:

while (!feof(fp)) {
fgets(buf, sizeof buf, fp);
/* do something or naught */
}

Please do the test, take any project at random to which you can access the
source code and examine the do/while loops, you will find bugs!
 
B

Ben Bacarisse

Charlie Gordon said:
My own experience proofreading millions on lines of C code tells me
that.

....and my experience teaching programming leads to the same
conclusion. There seems to be something seductive about do ... while.
So much so that I just dropped the form from lecture notes as soon as
I saw the problem.

It may be that it reads naturally. It might also be that one of the
rare cases when it is correct:

do {
print prompt;
get reply;
} while (reply not suitable);

crops up in beginners programs more often than production code and the
idea sticks.

A great classic is this:

int c;
/* skip to end of line */
do {
c = getc(fp);
} while (c != '\n');

Yes, but that is not wrong because of the do .. while. You probably
intended to leave out the declaration of c (or at least to add
.... suggesting more intervening code) so that this code comes after
some other input that might already have set c to '\n' (at least that
is the form of this bug I've seen repeatedly in student code).
 
C

Charlie Gordon

Ben Bacarisse said:
...and my experience teaching programming leads to the same
conclusion. There seems to be something seductive about do ... while.
So much so that I just dropped the form from lecture notes as soon as
I saw the problem.

I'm glad to see I'm not alone in the desert.
It may be that it reads naturally. It might also be that one of the
rare cases when it is correct:

do {
print prompt;
get reply;
} while (reply not suitable);

crops up in beginners programs more often than production code and the
idea sticks.



Yes, but that is not wrong because of the do .. while. You probably
intended to leave out the declaration of c (or at least to add
... suggesting more intervening code) so that this code comes after
some other input that might already have set c to '\n' (at least that
is the form of this bug I've seen repeatedly in student code).

That's a good point, but there is worse: this loop will run forever if the
stream ends without a new-line.
The classic idiom is safer:

while ((c = getc(fp)) != EOF && c != '\n')
continue;

or if EOF is a condition worth reporting:

while ((c = getc(fp)) != '\n') {
if (c == EOF) {
report_error("unexpected end of file);
break;
}
}

For some reason, people tend to overlook special cases when they program
even the simplest tasks with do/while loops.
 
K

Keith Thompson

Ben Bacarisse said:
...and my experience teaching programming leads to the same
conclusion. There seems to be something seductive about do ... while.
So much so that I just dropped the form from lecture notes as soon as
I saw the problem.
[...]

I learned Pascal before I learned C. In Pascal, I used
REPEAT
...
UNTIL <condition>;
(similar to C's do-while) much more than I used
WHILE <condition> DO
BEGIN
...
END;

In C, I think the last time I used a do-while loop was in my IOCCC
entry.

Pascal's I/O model, unlike C's, encourages test-at-the-bottom loops.
(Well, C's I/O model seems to encourage such loops too, but not in
correct code.)
 
U

user923005

...and my experience teaching programming leads to the same
conclusion. There seems to be something seductive about do ... while.
So much so that I just dropped the form from lecture notes as soon as
I saw the problem.

[...]

I learned Pascal before I learned C. In Pascal, I used
REPEAT
...
UNTIL <condition>;
(similar to C's do-while) much more than I used
WHILE <condition> DO
BEGIN
...
END;

In C, I think the last time I used a do-while loop was in my IOCCC
entry.

Pascal's I/O model, unlike C's, encourages test-at-the-bottom loops.
(Well, C's I/O model seems to encourage such loops too, but not in
correct code.)

To me, the choice is clear:

1. If you always want to perform the code _at least_ once, then use
do {} while(cond);
2. If you may not want to perform the code even one time (because
cond is false), then use while (cond) {} ;

I don't see any reason why one is easier or harder to understand than
the other. To me the complexity is identical.
 
C

Charlie Gordon

Ben Bacarisse said:
"CBFalconer" <[email protected]> a écrit dans le message de (e-mail address removed)...
Charlie Gordon wrote:

As a rule of thumb, do/while loops are more difficult to master
than regular while or for loops.
Why should you think that? "do { something() } while(foo);" is no
more complex than "while (foo) {something())". The only difference
is that the foo test is applied after execution in the do/while
loop, and before execution in the while loop.
My own experience proofreading millions on lines of C code tells me
that.
...and my experience teaching programming leads to the same
conclusion. There seems to be something seductive about do ... while.
So much so that I just dropped the form from lecture notes as soon as
I saw the problem.

[...]

I learned Pascal before I learned C. In Pascal, I used
REPEAT
...
UNTIL <condition>;
(similar to C's do-while) much more than I used
WHILE <condition> DO
BEGIN
...
END;

In C, I think the last time I used a do-while loop was in my IOCCC
entry.

Pascal's I/O model, unlike C's, encourages test-at-the-bottom loops.
(Well, C's I/O model seems to encourage such loops too, but not in
correct code.)

To me, the choice is clear:

1. If you always want to perform the code _at least_ once, then use
do {} while(cond);
2. If you may not want to perform the code even one time (because
cond is false), then use while (cond) {} ;

I don't see any reason why one is easier or harder to understand than
the other. To me the complexity is identical.

The debate is not so simple.
The example I gave is typical of erroneous uses do/while:

people write

do {
operation;
maybe_more_operations;
} while (cond);

where they should write

while (operation, cond && other_cond) {
maybe_more_operations;
}

or

for (;;) {
operation;
if (!cond)
break;
if (!other_cond)
break;
}

definitely the do/while *seems* simpler and more straightforward, but
it tends to be bogus with conditions ignored or tested at the wrong
place.
 

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,007
Latest member
obedient dusk

Latest Threads

Top