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

I'm pretty sure I have some out of control Undefined Behavior

P: n/a
The input file is:
Params
1
2
3
4
5
6,7
Data
1,1
2,2
3,2
4,4
5,6

The output should be
1
2
3
4
5
6,7
1,1
2,2
3,2
4,4
5,6

Okay, with that, here is what I attempted, and what my computer
produced.

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

#define MAXLINE 10

int main(void)
{

char buff[MAXLINE];

char temp1[] = "Params\n";
char temp2[] = "Data\n";

FILE *inFile;

inFile = fopen("LAND2.txt", "r");
if (inFile != NULL)
{
while (fgets(buff, sizeof(buff), inFile) != NULL) {
if(strncmp(buff,temp1,sizeof(buff)) != 0)
fputs(buff, stdout);

if(strncmp(buff,temp2,sizeof(buff)) != 0)
fputs(buff, stdout);
}
}

if(feof) {
return 0;
}

fclose (inFile);

return 0;
}

Output

$gcc -Wall lunar.c -o lunar
$./lunar
Params
1
1
2
2
3
3
4
4
5
5
6,7
6,7
Data
1,1
1,1
2,2
2,2
3,2
3,2
4,4
4,4
5,6
5,6
$

Can someone enlighten me on where I'm screwing this up.

Chad

Apr 5 '06 #1
Share this Question
Share on Google+
9 Replies


P: n/a
Chad wrote:
The input file is:
Params
1
2
3
4
5
6,7
Data
1,1
2,2
3,2
4,4
5,6

The output should be
1
2
3
4
5
6,7
1,1
2,2
3,2
4,4
5,6

Okay, with that, here is what I attempted, and what my computer
produced.

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

#define MAXLINE 10

int main(void)
{

char buff[MAXLINE];

char temp1[] = "Params\n";
char temp2[] = "Data\n";

FILE *inFile;

inFile = fopen("LAND2.txt", "r");
if (inFile != NULL)
{
while (fgets(buff, sizeof(buff), inFile) != NULL) {
if(strncmp(buff,temp1,sizeof(buff)) != 0)
fputs(buff, stdout);
strcmp and strncmp return 0 if the strings being tested compare equal.
This may seem a little backwards until you realize that strcmp stands
for "string compare" not "string equal". The strcmp functions don't
just compare strings for equality, they also let you know which string
is "greater".
In this instance you are printing the input string when it *doesn't*
match "Params\n".
if(strncmp(buff,temp2,sizeof(buff)) != 0)
fputs(buff, stdout);
The string will be printed again (or for the first time if it was
"Params\n") if it doesn't match "Data\n".

To do what you seem to be trying to accomplish, one if statement will
suffice:
if (strncmp(buff, temp1, sizeof(buff)) && strncmp(buff, temp2,
sizeof(buff)))
fputs(buff, stdout);
This will print buff once when it doesn't match either strings, i.e.
when both strncmp calls return non-zero.
}
}

if(feof) {
return 0;
}
What are you trying to accomplish here? Since feof will evaluate to
the address of the feof() function which is not a null pointer, you
will always return here. I assume you meant to actually call the
function but I don't know what the point of that would be in your
example.
fclose (inFile);

return 0;
}

Output

$gcc -Wall lunar.c -o lunar
Did you really? If you had, gcc would have complained about the "if
(feof)" incident. Did you ignore the warning or did you not copy/paste
your code correctly?
$./lunar
Params
1
1
2
2
3
3
4
4
5
5
6,7
6,7
Data
1,1
1,1
2,2
2,2
3,2
3,2
4,4
4,4
5,6
5,6


Robert Gamble

Apr 5 '06 #2

P: n/a

Robert Gamble wrote:
Chad wrote:
The input file is:
Params
1
2
3
4
5
6,7
Data
1,1
2,2
3,2
4,4
5,6

The output should be
1
2
3
4
5
6,7
1,1
2,2
3,2
4,4
5,6

Okay, with that, here is what I attempted, and what my computer
produced.

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

#define MAXLINE 10

int main(void)
{

char buff[MAXLINE];

char temp1[] = "Params\n";
char temp2[] = "Data\n";

FILE *inFile;

inFile = fopen("LAND2.txt", "r");
if (inFile != NULL)
{
while (fgets(buff, sizeof(buff), inFile) != NULL) {
if(strncmp(buff,temp1,sizeof(buff)) != 0)
fputs(buff, stdout);


strcmp and strncmp return 0 if the strings being tested compare equal.
This may seem a little backwards until you realize that strcmp stands
for "string compare" not "string equal". The strcmp functions don't
just compare strings for equality, they also let you know which string
is "greater".
In this instance you are printing the input string when it *doesn't*
match "Params\n".
if(strncmp(buff,temp2,sizeof(buff)) != 0)
fputs(buff, stdout);


The string will be printed again (or for the first time if it was
"Params\n") if it doesn't match "Data\n".

To do what you seem to be trying to accomplish, one if statement will
suffice:
if (strncmp(buff, temp1, sizeof(buff)) && strncmp(buff, temp2,
sizeof(buff)))
fputs(buff, stdout);
This will print buff once when it doesn't match either strings, i.e.
when both strncmp calls return non-zero.
}
}

if(feof) {
return 0;
}


What are you trying to accomplish here? Since feof will evaluate to
the address of the feof() function which is not a null pointer, you
will always return here. I assume you meant to actually call the
function but I don't know what the point of that would be in your
example.
fclose (inFile);

return 0;
}

Output

$gcc -Wall lunar.c -o lunar


Did you really? If you had, gcc would have complained about the "if
(feof)" incident. Did you ignore the warning or did you not copy/paste
your code correctly?
$./lunar
Params
1
1
2
2
3
3
4
4
5
5
6,7
6,7
Data
1,1
1,1
2,2
2,2
3,2
3,2
4,4
4,4
5,6
5,6


Robert Gamble


gcc didn't complain. And I quote the ENTIRE output

$gcc --version
gcc (GCC) 3.3.3 (SuSE Linux)
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is
NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.

$gcc -Wall lunar.c -o lunar

Chad

Apr 5 '06 #3

P: n/a

Chad wrote:
Robert Gamble wrote:
Chad wrote:
The input file is:
Params
1
2
3
4
5
6,7
Data
1,1
2,2
3,2
4,4
5,6

The output should be
1
2
3
4
5
6,7
1,1
2,2
3,2
4,4
5,6

Okay, with that, here is what I attempted, and what my computer
produced.

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

#define MAXLINE 10

int main(void)
{

char buff[MAXLINE];

char temp1[] = "Params\n";
char temp2[] = "Data\n";

FILE *inFile;

inFile = fopen("LAND2.txt", "r");
if (inFile != NULL)
{
while (fgets(buff, sizeof(buff), inFile) != NULL) {
if(strncmp(buff,temp1,sizeof(buff)) != 0)
fputs(buff, stdout);


strcmp and strncmp return 0 if the strings being tested compare equal.
This may seem a little backwards until you realize that strcmp stands
for "string compare" not "string equal". The strcmp functions don't
just compare strings for equality, they also let you know which string
is "greater".
In this instance you are printing the input string when it *doesn't*
match "Params\n".
if(strncmp(buff,temp2,sizeof(buff)) != 0)
fputs(buff, stdout);


The string will be printed again (or for the first time if it was
"Params\n") if it doesn't match "Data\n".

To do what you seem to be trying to accomplish, one if statement will
suffice:
if (strncmp(buff, temp1, sizeof(buff)) && strncmp(buff, temp2,
sizeof(buff)))
fputs(buff, stdout);
This will print buff once when it doesn't match either strings, i.e.
when both strncmp calls return non-zero.
}
}

if(feof) {
return 0;
}


What are you trying to accomplish here? Since feof will evaluate to
the address of the feof() function which is not a null pointer, you
will always return here. I assume you meant to actually call the
function but I don't know what the point of that would be in your
example.
fclose (inFile);

return 0;
}

Output

$gcc -Wall lunar.c -o lunar


Did you really? If you had, gcc would have complained about the "if
(feof)" incident. Did you ignore the warning or did you not copy/paste
your code correctly?
$./lunar
Params
1
1
2
2
3
3
4
4
5
5
6,7
6,7
Data
1,1
1,1
2,2
2,2
3,2
3,2
4,4
4,4
5,6
5,6


Robert Gamble


gcc didn't complain. And I quote the ENTIRE output

$gcc --version
gcc (GCC) 3.3.3 (SuSE Linux)
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is
NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.

$gcc -Wall lunar.c -o lunar

Chad


I probably shouldn't have put in feof(). The problem is that I still
have no REAL understanding of the function. I would ask more about it,
but I need to figure out EXACTLY the part of feof() I'm not fully
grasping posting questions about it.

Chad

Apr 5 '06 #4

P: n/a

Chad wrote:
Robert Gamble wrote:
Chad wrote:
The input file is:
Params
1
2
3
4
5
6,7
Data
1,1
2,2
3,2
4,4
5,6

The output should be
1
2
3
4
5
6,7
1,1
2,2
3,2
4,4
5,6

Okay, with that, here is what I attempted, and what my computer
produced.

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

#define MAXLINE 10

int main(void)
{

char buff[MAXLINE];

char temp1[] = "Params\n";
char temp2[] = "Data\n";

FILE *inFile;

inFile = fopen("LAND2.txt", "r");
if (inFile != NULL)
{
while (fgets(buff, sizeof(buff), inFile) != NULL) {
if(strncmp(buff,temp1,sizeof(buff)) != 0)
fputs(buff, stdout);


strcmp and strncmp return 0 if the strings being tested compare equal.
This may seem a little backwards until you realize that strcmp stands
for "string compare" not "string equal". The strcmp functions don't
just compare strings for equality, they also let you know which string
is "greater".
In this instance you are printing the input string when it *doesn't*
match "Params\n".
if(strncmp(buff,temp2,sizeof(buff)) != 0)
fputs(buff, stdout);


The string will be printed again (or for the first time if it was
"Params\n") if it doesn't match "Data\n".

To do what you seem to be trying to accomplish, one if statement will
suffice:
if (strncmp(buff, temp1, sizeof(buff)) && strncmp(buff, temp2,
sizeof(buff)))
fputs(buff, stdout);
This will print buff once when it doesn't match either strings, i.e.
when both strncmp calls return non-zero.
}
}

if(feof) {
return 0;
}


What are you trying to accomplish here? Since feof will evaluate to
the address of the feof() function which is not a null pointer, you
will always return here. I assume you meant to actually call the
function but I don't know what the point of that would be in your
example.
fclose (inFile);

return 0;
}

Output

$gcc -Wall lunar.c -o lunar


Did you really? If you had, gcc would have complained about the "if
(feof)" incident. Did you ignore the warning or did you not copy/paste
your code correctly?
$./lunar
Params
1
1
2
2
3
3
4
4
5
5
6,7
6,7
Data
1,1
1,1
2,2
2,2
3,2
3,2
4,4
4,4
5,6
5,6


Robert Gamble


gcc didn't complain. And I quote the ENTIRE output

$gcc --version
gcc (GCC) 3.3.3 (SuSE Linux)
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is
NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.

$gcc -Wall lunar.c -o lunar

Chad


I probably shouldn't have put in feof(). The problem is that I still
have no REAL understanding of the function. I would ask more about it,
but I need to figure out EXACTLY the part of feof() I'm not fully
grasping posting before questions about it.

Chad

Apr 5 '06 #5

P: n/a
Chad wrote:
Robert Gamble wrote:
Chad wrote:
<snip>
if(feof) {
return 0;
}
What are you trying to accomplish here? Since feof will evaluate to
the address of the feof() function which is not a null pointer, you
will always return here. I assume you meant to actually call the
function but I don't know what the point of that would be in your
example.
fclose (inFile);

return 0;
}

Output

$gcc -Wall lunar.c -o lunar


Did you really? If you had, gcc would have complained about the "if
(feof)" incident. Did you ignore the warning or did you not copy/paste
your code correctly?


<snip>
gcc didn't complain. And I quote the ENTIRE output

$gcc --version
gcc (GCC) 3.3.3 (SuSE Linux)
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is
NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.

$gcc -Wall lunar.c -o lunar

Chad


2003? That's ancient ;)
The newer versions (4.0.x) will complain.

Robert Gamble

Apr 5 '06 #6

P: n/a
"Chad" <cd*****@gmail.com> writes:
The input file is: [snip]
Okay, with that, here is what I attempted, and what my computer
produced.

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

#define MAXLINE 10

int main(void)
{

char buff[MAXLINE];

char temp1[] = "Params\n";
char temp2[] = "Data\n";

FILE *inFile;

inFile = fopen("LAND2.txt", "r");
if (inFile != NULL)
{
while (fgets(buff, sizeof(buff), inFile) != NULL) {
if(strncmp(buff,temp1,sizeof(buff)) != 0)
fputs(buff, stdout);

if(strncmp(buff,temp2,sizeof(buff)) != 0)
fputs(buff, stdout);
I'm not sure why you're using strncmp() here rather than strcmp().
Both arguments are strings (i.e., character arrays properly terminated
by '\0').

Your logic here is:

For each line
Print the line if it's not equal to "Params\n".
Print the line if it's not equal to "Data\n".

That's your problem.
}
}

if(feof) {
return 0;
}


What is the purpose of the above test?

The feof function expects a single argument of type FILE*. The only
thing in your program it would make sense to pass to it is inFile,
i.e., "feof(inFile)". With no parentheses, you don't even have a
function call; the name of a function is converted to a pointer to the
function, which you then evaluate as a condition; any non-null pointer
evaluates as true.

But even if you corrected it to "if (feof(inFile)", I'm not sure what
the purpose is -- unless you're using it to check whether the fopen()
call succeeded. (I'm actually not sure what feof() does on a closed
file.)

It would be better to associate any error handling directly with the
result of fopen(), such as:

inFile = fopen("LAND2.txt", "r");
if (inFile == NULL) {
fprintf(stderr, "fopen failed for LAND2.txt\n");
exit(EXIT_FAILURE);
}

[snip]

--
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.
Apr 5 '06 #7

P: n/a
Keith Thompson wrote:
"Chad" <cd*****@gmail.com> writes:
The input file is:

[snip]

Okay, with that, here is what I attempted, and what my computer
produced.

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

#define MAXLINE 10

int main(void)
{

char buff[MAXLINE];

char temp1[] = "Params\n";
char temp2[] = "Data\n";

FILE *inFile;

inFile = fopen("LAND2.txt", "r");
if (inFile != NULL)
{
while (fgets(buff, sizeof(buff), inFile) != NULL) {
if(strncmp(buff,temp1,sizeof(buff)) != 0)
fputs(buff, stdout);

if(strncmp(buff,temp2,sizeof(buff)) != 0)
fputs(buff, stdout);


I'm not sure why you're using strncmp() here rather than strcmp().
Both arguments are strings (i.e., character arrays properly terminated
by '\0').

Your logic here is:

For each line
Print the line if it's not equal to "Params\n".
Print the line if it's not equal to "Data\n".

That's your problem.
}
}

if(feof) {
return 0;
}


What is the purpose of the above test?

The feof function expects a single argument of type FILE*. The only
thing in your program it would make sense to pass to it is inFile,
i.e., "feof(inFile)". With no parentheses, you don't even have a
function call; the name of a function is converted to a pointer to the
function, which you then evaluate as a condition; any non-null pointer
evaluates as true.

But even if you corrected it to "if (feof(inFile)", I'm not sure what
the purpose is -- unless you're using it to check whether the fopen()
call succeeded. (I'm actually not sure what feof() does on a closed
file.)

It would be better to associate any error handling directly with the
result of fopen(), such as:

inFile = fopen("LAND2.txt", "r");
if (inFile == NULL) {
fprintf(stderr, "fopen failed for LAND2.txt\n");
exit(EXIT_FAILURE);
}

[snip]

--
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.


Why wouldn't something like

if feof(inFile)

not make sense to check if fopen() call succeeded in this case?

Chad

Apr 5 '06 #8

P: n/a
"Chad" <cd*****@gmail.com> writes:
[...]
I probably shouldn't have put in feof(). The problem is that I still
have no REAL understanding of the function. I would ask more about it,
but I need to figure out EXACTLY the part of feof() I'm not fully
grasping posting questions about it.


The first thing to understand about feof() is that it's rarely
necessary to use it. Each input function returns a result that tells
you whether it succeeded or not. An input function can fail either
because of an error or because you've reached the end of the input
file (or, in some cases, because the input doesn't match the expected
format). (Once you've detected the failure, you can *then* use feof()
and/or ferror() to distinguish between an error condition and an
end-of-file condition.)

Read section 12 of the comp.lang.c FAQ, <http://www.c-faq.com/>.

--
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.
Apr 5 '06 #9

P: n/a
"Chad" <cd*****@gmail.com> writes:
[...]
Why wouldn't something like

if feof(inFile)

not make sense to check if fopen() call succeeded in this case?


When you post a followup, please trim the parts of the previous
article that aren't relevant (as I've done here).

Why *would* feof(inFile) make sense as a way to check whether fopen()
succeeded? Was that really what you had in mind?

The feof() function tells you whether the end-of-file indicator is set
for the specified stream. If fopen() fails, it returns NULL;
feof(NULL) invokes undefined behavior (i.e., it's likely to blow up in
your face).

fopen() tells you whether it succeeded or failed. All you have to do
is remember what it told you.

--
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.
Apr 5 '06 #10

This discussion thread is closed

Replies have been disabled for this discussion.