need help..

S

slickn_sly

<code>
line = 1;
while( !feof( infile ) )
{
if( line = 2 )
{
fgets( name, 25, infile );
}
else if( line = 3 )
{
fgets( address, 80, infile );
strcat( tempaddress, address );
if( strcmp( address, "?" ) == 0 )
{
line = 4;
}
}
else if( line = 4 )
{
fgets( yearofbirth, 5, infile );
}
else if( line = 5 )
{
fgets( telno, 15, infile );
}

line++;
printf( "%s%s%s%s", name, address, yearofbirth, telno );
addRecord( rptrp , name, address, atoi(yearofbirth), telno
);

}
</code>

I wonder if someone can help me out. For some reason, this while loop
doesn't update. line is always set to 1. i'm trying to get each line
and store it in each array.
Posted at: http://www.groupsrv.com
 
M

Martin Ambuhl

slickn_sly said:
line = 1;
while( !feof( infile ) )
^^^^^^^^^^^^^^^^^^^^^^^^
This is a mistake; check the FAQ, your C textbook, or any of a large
number of previous threads for details.
{
if( line = 2 )
^^^^^^^^^^^^
This, and all subsequent conditions like it, are almost certainly a
mistake. '=' is the assignment operator; '==' is the equality
comparison operatior.
 
C

CBFalconer

Martin said:
slickn_sly wrote:
.... snip ...

^^^^^^^^^^^^
This, and all subsequent conditions like it, are almost certainly
a mistake. '=' is the assignment operator; '==' is the equality
comparison operatior.

Which you can easily avoid at all times by simply cultivating the
habit of writing:

if (2 == line) ...

i.e. put the constant first.
 
A

Allan Bruce

CBFalconer said:
Which you can easily avoid at all times by simply cultivating the
habit of writing:

if (2 == line) ...

i.e. put the constant first.

Or since the OP is using multiple constants, a neater approach would be to
use a switch() statement.
Allan
 
D

dot

<code>
line = 1;
while( !feof( infile ) )
{
if( line = 2 )
{
fgets( name, 25, infile );
}
else if( line = 3 )
{
fgets( address, 80, infile );
strcat( tempaddress, address );
if( strcmp( address, "?" ) == 0 )
{
line = 4;
}
}
else if( line = 4 )
{
fgets( yearofbirth, 5, infile );
}
else if( line = 5 )
{
fgets( telno, 15, infile );
}

line++;
printf( "%s%s%s%s", name, address, yearofbirth, telno );
addRecord( rptrp , name, address, atoi(yearofbirth), telno
);

}
</code>

I wonder if someone can help me out. For some reason, this while loop
doesn't update. line is always set to 1. i'm trying to get each line
and store it in each array.
Posted at: http://www.groupsrv.com

First... When you are reading consecutive lines from a sequential file, you
don't need to count them. As the file pointer moves along you just grab the
next line.

As for the question of why the line counts are not updating... You enter the
original loop with line set to 1, but nothing ever sets it to anything but 1
until the end where you have line++. The loop will actually spin the first
time reading nothing, the second time reading whatever is at the current
file position into the name, the third time reading the next line into the
address and the next time through the loop it will read into the phone
number... after that it will spin infinitely reading nothing.

From the above, I'm guessing you have a structured text file like this...

name \n
address \n
yearofbirth \n
telno \n


If so, try this...

while( !feof( infile ) )
{ fgets( name, 25, infile );
fgets( address, 80, infile );
fgets( yearofbirth, 5, infile );
fgets( telno, 15, infile );
printf( "%s%s%s%s", name, address, yearofbirth, telno );
addRecord( rptrp , name, address, atoi(yearofbirth), telno); }


Rule of thumb...
Your thumb should always be more complicated than your code.
 
P

Peteris Krumins

CBFalconer said:
Which you can easily avoid at all times by simply cultivating the
habit of writing:

if (2 == line) ...

i.e. put the constant first.

Which you can as easily avoid at all times without any cultivation
by letting the compiler warn you.


P.Krumins
 
N

Nils Weller

Which you can easily avoid at all times by simply cultivating the
habit of writing:

if (2 == line) ...

i.e. put the constant first.

I don't like this habit for various reasons:

1) Though the reversed version is semantically equivalent, it is harder
to read unless you are already quite used to reversing the test. The
vast majority of programmers always puts the variable they want to test
first, i.e. they write

if (foo == 0) {

The few who write

if (0 == foo) {

.... are extremely likely to do so only because they want to avoid the
comparison vs. assignment problem. (If any of the c.l.c regulars started
to use the latter version for reasons other than the mixed up operators
thing, please stand up.)

This is evidence enough that the former version is more natural, and it
follows that the latter is harder to read and understand, regardless of
the fact that it means the same thing. The fact that writing ``0 ==
foo'' is generally considered to be a programming trick is additional
evidence that it is NOT the natural way to code this.

2) If you can remember to reverse the check every time, you also ought
to be able to remember simply to use ``=='' whenever you mean ``=='',
which would save you the trouble of making your code less readable.
The reversal also only makes any sense for C beginners; Sooner or
later you *will* get used to its equality operator, and the reversed
test only serves the purpose of decreasing code readability anymore.

3) Quality compilers warn about the ``if (foo = 0)'' construct. I know
for a fact only that gcc and HP's compilers do this (and not because the
bug ever occured to me, but because I explictly tested these compilers),
but it is very likely that the offerings of vendors such as Comeau,
Compaq, Intel, SGI, IBM, Sun and a host of others are also capable of
doing this (I don't have these compilers handy right now and will let
others fill in the blanks.)

4) It is not even a reliable way to avoid the problem because it works
well only for constants!

if (foo = bar) {

and

if (bar = foo) {

.... both silently produce (probably) incorrect results (modulo corner
cases like the operand on the left-hand side being ``const''-qualified.)

(It will probably take me a couple of days to reply to any followups -
should I consider them interesting enough to reply - because the free
access to my newsserver is being terminated and I haven't yet registered
a commercial account.)
 
C

CBFalconer

Nils said:
CBFalconer wrote:
.... snip ...

I don't like this habit for various reasons:

1) Though the reversed version is semantically equivalent, it is harder
to read unless you are already quite used to reversing the test. The
vast majority of programmers always puts the variable they want to test
first, i.e. they write

if (foo == 0) {

The few who write

if (0 == foo) {
.... snip ...

3) Quality compilers warn about the ``if (foo = 0)'' construct. I know
for a fact only that gcc and HP's compilers do this (and not because the
bug ever occured to me, but because I explictly tested these compilers),
but it is very likely that the offerings of vendors such as Comeau,
Compaq, Intel, SGI, IBM, Sun and a host of others are also capable of
doing this (I don't have these compilers handy right now and will let
others fill in the blanks.)

And I dislike that warning. I often want to write something like:

if (!(p = malloc(sizeof *p))) getoutahere("no memory");
else if (!(p->ptr = malloc(sizeof *p->ptr))) {
free(p); getoutahere("no memory");
}
else {
/* all seems well, go for it */
}
/* Unless getoutahere does something, we always get here */

and similar things to do with opening files, getting parameters,
etc.
 
D

dot

I don't like this habit for various reasons:

1) Though the reversed version is semantically equivalent, it is harder
to read unless you are already quite used to reversing the test. The
vast majority of programmers always puts the variable they want to test
first, i.e. they write

if (foo == 0) {

The few who write

if (0 == foo) {

... are extremely likely to do so only because they want to avoid the
comparison vs. assignment problem. (If any of the c.l.c regulars started
to use the latter version for reasons other than the mixed up operators
thing, please stand up.)

Easy solution...

#define is ==

int x = 10;

if (x is 10)
puts("it worked");


3) Quality compilers warn about the ``if (foo = 0)'' construct.

It should be a syntax error.
 
C

Chris Croughton

And I dislike that warning. I often want to write something like:

if (!(p = malloc(sizeof *p))) getoutahere("no memory");
else if (!(p->ptr = malloc(sizeof *p->ptr))) {
free(p); getoutahere("no memory");
}
else {
/* all seems well, go for it */
}
/* Unless getoutahere does something, we always get here */

and similar things to do with opening files, getting parameters,
etc.

Quality compilers (GCC derived ones, for example) note the extra
parentheses around the assignment and don't produce the warning:

if (p = q) ... /* warning */
if ((p = q)) ... /* no warning */
if (!(p = q)) ... /* no warning */

The first could be a mistake, the second and third are likely to be
intentional.

Although I prefer the clearer:

p = q;
if (p) ...

in most cases (idioms with for and while loops and inputting data are
about the only times I use the contraction, I don't do it in an if
test).

Chris C
 
K

Keith Thompson

Easy solution...

#define is ==

int x = 10;

if (x is 10)
puts("it worked");

That will make your code difficult to read. Do you actually do this
yourself?
It should be a syntax error.

In a different language, sure. In C, an assignment is an expression
that yields the value assigned; changing that would break too much
existing code.
 
D

dot

In a different language, sure. In C, an assignment is an expression
that yields the value assigned; changing that would break too much
existing code.

If the compiler can detect it sufficiently to warn, it can hand out an
error, stop compilation and force you to fix it. And how many perfectly
good programs have come crashing down over this one simple error? Even
worse when comparisons ( < and > ) are single characters... it's confusing.

Frankly, it would have made more sense to have the testing done on a single
=, & or | marks and use the doubles for assignment along with >> and <<
which are used for bit shifts.

Think about it... 1 letter: compare, 2 letters: perform an operation. (or
visa versa) It would be totally consistent. As it is now the rule is 1
letter does an operation EXCEPT for bit shifts, 2 letters does a test EXCEPT
for less and greater. It's inconsistent and when learning I found it
confusing as all get out.

So I have a little header I use with a bunch of defines...

#define is ==
#define lt <
#define gt >
#define ne !=
#define or ||
#define and &&
#define shiftl <<
#define shiftr >>
etc.

Gives me syntax like this:

if (x and (y lt 7))

if ((x lt y) or (y is 7))

No more silly mistakes.

Errors are what happens when you start reusing the same characters for
different functions. But I guess it's a couple of decades too late for
that...
 
C

CBFalconer

If the compiler can detect it sufficiently to warn, it can hand
out an error, stop compilation and force you to fix it. And how
many perfectly good programs have come crashing down over this
one simple error? Even worse when comparisons ( < and > ) are
single characters... it's confusing.

Except now you are using 'not C'. The value of an assignment is
often useful, as in:

if (err = setupphase(1)) bitchabout(1, err);
else if (err = setupphase(2)) bitchabout(2, err);
else if (err = setupphase(3)) bitchabout(3, err);
else {
/* The sun is out and the birds are singing */
}
/* And we always get here, possibly with err set */

--
Some useful references about C:
<http://www.ungerhu.com/jxh/clc.welcome.txt>
<http://www.eskimo.com/~scs/C-faq/top.html>
<http://benpfaff.org/writings/clc/off-topic.html>
<http://anubis.dkuug.dk/jtc1/sc22/wg14/www/docs/n869/> (C99)
<http://www.dinkumware.com/refxc.html> (C-library}
<http://gcc.gnu.org/onlinedocs/> (GNU docs)
 
D

dot

Except now you are using 'not C'. The value of an assignment is
often useful, as in:

if (err = setupphase(1)) bitchabout(1, err);
else if (err = setupphase(2)) bitchabout(2, err);
else if (err = setupphase(3)) bitchabout(3, err);
else {

In which case I use assignment, not tests to get the job done.

So, exactly what's the problem?
 
C

Christopher Benson-Manica

CBFalconer said:
Except now you are using 'not C'. The value of an assignment is
often useful, as in:
if (err = setupphase(1)) bitchabout(1, err);

Yes, that's very convenient, although my implementation at least will
generate a warning. I don't know if gcc does, and I wonder whether
lint and friends will complain.
 
K

Keith Thompson

Please don't snip nested attributions.
If the compiler can detect it sufficiently to warn, it can hand out an
error, stop compilation and force you to fix it. And how many perfectly
good programs have come crashing down over this one simple error? Even
worse when comparisons ( < and > ) are single characters... it's confusing.

You can't make "=" not yield a value without breaking existing
programs. Making an assignment invalid in a condition but valid
elsewhere would be an ugly wart.

Frankly, it would have made more sense to have the testing done on a single
=, & or | marks and use the doubles for assignment along with >> and <<
which are used for bit shifts.

Think about it... 1 letter: compare, 2 letters: perform an operation. (or
visa versa) It would be totally consistent. As it is now the rule is 1
letter does an operation EXCEPT for bit shifts, 2 letters does a test EXCEPT
for less and greater. It's inconsistent and when learning I found it
confusing as all get out.

I've never assumed that the number of characters in an operator has
any significance. I just learned what each one means.
So I have a little header I use with a bunch of defines...

#define is ==
#define lt <
#define gt >
#define ne !=
#define or ||
#define and &&
#define shiftl <<
#define shiftr >>
etc.

Gives me syntax like this:

if (x and (y lt 7))

if ((x lt y) or (y is 7))

No more silly mistakes.

If I were going to do something like that, I'd use "eq" rather than
"is" for equality. (Some languages distinguish between equality and
identity, and use "is" for the latter.) I'd also use the symbols in
<iso646.h> whenever possible, and try to be consistent with them
otherwise.

But I'd much rather just learn the language and use it. If I'm going
to read your code, I have to undertand the language *and* the macros
you've chosen. For this:

if (x && (y < 7))

if ((x < y) || (y == 7))

I just have to know the language.

You can use your macros if you like, but I guarantee they'll make it
more difficult for anyone else to read or maintain your code.
 
K

Keith Thompson

In which case I use assignment, not tests to get the job done.

So, exactly what's the problem?

The problem is that you would make the above valid code illegal. The
alternative would be significantly more verbose. I suppose you could
do this:

if (err = setupphase(1), err) bitchabout(1, err);
else if (err = setupphase(2), err) bitchabout(2, err);
else if (err = setupphase(3), err) bitchabout(3, err);
else {

but frankly I find the first form clearer.
 
L

Lew Pitcher

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

If the compiler can detect it sufficiently to warn, it can hand out an
error, stop compilation and force you to fix it.

Sorry, but while it might warrant a "suspicious construct" type warning from
the compiler, that code model certainly isn't /broken/, and doesn't warrant an
error that stops compilation.

Consider this fragment...

if (c = Get_Users_Choice()) printf("The user chose %c\n",c);

If, for instance, while developing or debugging this fragment, the programmer
decided to 'stub' the Get_Users_Choice() function with
#define Get_Users_Choice() 'N'
then the compilation would generate (after macro expansion)

if (c = 'N') printf("The user chose %c\n",c);

While this is not a /usefull/ code construct (from the point of view of
offering the intended variety of values to c), it is a /necessary/ and /legal/
construct.
And how many perfectly
good programs have come crashing down over this one simple error?

Probably fewer than those that come crashing down on off-by-one errors or
subscript_out_of_bounds errors.
Even
worse when comparisons ( < and > ) are single characters... it's confusing.

To you, perhaps, but not to a professional (or even an experienced amateur)
programmer.
Frankly, it would have made more sense to have the testing done on a single
=, & or | marks and use the doubles for assignment along with >> and <<
which are used for bit shifts.

That's your opinion. You are welcome to move to that language, what ever it
is. It isn't C, though.
Think about it... 1 letter: compare, 2 letters: perform an operation. (or
visa versa) It would be totally consistent. As it is now the rule is 1
letter does an operation EXCEPT for bit shifts, 2 letters does a test EXCEPT
for less and greater. It's inconsistent and when learning I found it
confusing as all get out.

You get confused easily, I see.
So I have a little header I use with a bunch of defines...

#define is ==
#define lt <
#define gt >
#define ne !=
#define or ||
#define and &&
#define shiftl <<
#define shiftr >>

Reminds me of the poster a decade back or so who posted macros that made C
look "pascal-like". Macros of the sort of
#define BEGIN {
#define END }

Just as useless, too.

- --
Lew Pitcher

Master Codewright & JOAT-in-training | GPG public key available on request
Registered Linux User #112576 (http://counter.li.org/)
Slackware - Because I know what I'm doing.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFCTzVBagVFX4UWr64RApm9AKCnGeb8ZsGsPEIWskwzmzvvY19JHQCg6ibw
rtB1GuiKvbYFKei8WlKQUZI=
=OYZX
-----END PGP SIGNATURE-----
 

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

No members online now.

Forum statistics

Threads
474,161
Messages
2,570,892
Members
47,428
Latest member
RosalieQui

Latest Threads

Top