Redirecting input from file

K

Keith Thompson

The above was written by Richard Heathfield. Please leave attribution
lines in place; they make it substantially easier to follow the
conversation (and quoting someone else's words without attribution is
considered rude).

The line above:
is an attribution line. There should have been a similar one
crediting RH for what he wrote.
I don't think we are; we're using g++, which I am told is the only
thing we have. I tried to use cc, but it doesn't seem to be on the
system.

The following is slightly off-topic, since it deals with specific
implemntations rather than with the language.

"gcc" originally stood for "GNU C Compiler"; it was later changed to
"GNU Compiler Collection". The name "gcc" refers to a collection of
compilers for various languages. It's also the command name used to
invoke the C compiler portion of the gcc system (yes, it's a bit
confusing). "g++" is the command used to invoke the C++ compiler.

If you're compiling C code, use the "gcc" command, *not* the "g++"
command. (If you really want to program in C++, that's fine; use the
"g++" command, but ask about it in comp.lang.c++.)

Richard's advices is very good. Remove *all* the casts, use "gcc"
rather than "g++" to compile your sources, and try to correct any
problems *without* adding casts. There are cases where casts are
appropriate, but I don't think any of them occur in your program.

If you end up with something that you just can't get to compile, post
it here along with the *exact* copy-and-pasted error messages, and we
can help. If you end up with something that compiles but doesn't
work, post it here and tell us *exactly* how it doesn't work.
 
K

Keith Thompson

Default User said:
William said:
Others have pointed out that you need to verify that
argv[1] and argv[2] are not NULL before you call fopen,
and that's important but not the point I'm addressing.

If fopen() fails, you shouldn't make up your own error
message. The system provides you with a text string
describing why fopen failed.

This is not required by the standard, and in fact some implementations
do not set errno in this case.

As William acknowledged later in the same article.
 
C

CBFalconer

William said:
.... snip ...

If fopen() fails, you shouldn't make up your own error
message. The system provides you with a text string
describing why fopen failed. eg:

I believe that should read "_may_ provide you with a text string
describing ..."
 
J

J. J. Farrell

I don't think we are; we're using g++, which I am told is the only
thing we have. I tried to use cc, but it doesn't seem to be on the
system.

If you've got g++ then you've also got gcc (unless you have a very
strange environment).

g++ is a C++ compiler suite, use it to build C++ programs.

gcc is a C compiler suite, use it to build C programs.

If you're trying to write C yet build it as if it were C++, you're
heading into a world of confusion and complication.
 
W

William Pursell

William said:
Others have pointed out that you need to verify that
argv[1] and argv[2] are not NULL before you call fopen,
and that's important but not the point I'm addressing.
If fopen() fails, you shouldn't make up your own error
message. The system provides you with a text string
describing why fopen failed.

This is not required by the standard, and in fact some implementations
do not set errno in this case.

A point which I addressed later in my post.
I believe that properly describing the error encountered with
as much detail as possible is extremely important, and the
response that it is not 100% portable is often used as
an excuse to avoid even attempting to print reasonable
error messages. I won't even dare estimate how many hours
have been wasted in the history of computing simply because
of error messages that didn't provide adequate information.
POSIX guarantees that errno will be set
by fopen, and often that's portable enough.
IMO, an implementation that fails to provide
a reason for an fopen failure is brain dead. I acknowledge
the existence of such systems, and hope I never have
to deal with one.
 
D

dmoran21

I'd have to look tomorrow when I get to the office.


Here's the code; it now compiles, but seg faults when I run it. (Error
proofing will be done later)

int main(int argc, char *argv[])
{
/* Variable Declarations */
const int arraylength = 5;
const int errorcode = -1;
float sum = 0;
int count = 0;
int condition = 1;
float* precipvals = (float*)NULL;
float* precip3hrs = (float*)NULL;
char date[12];
FILE *fpin;
FILE *fpout;

fpin = fopen(argv[1],"r");
fpout = fopen(argv[2],"w");

/* Calculation Section */
while(condition != EOF) {
condition = fscanf(fpin,"%ld,%f", &date, &precipvals[count]);
if(count == 0) {
precip3hrs[count] = precipvals[count];
}
if(count == 1) {
precip3hrs[count] = precipvals[count] + precip3hrs[count-1];
}
if(count > 1) {
precip3hrs[count] = precipvals[count] + precipvals[count-1] +
precipvals[count-2];
}
if(condition != EOF) {
printf("Date: %s, One hour precipitation: %2.2f Three hour
precipitation: %2.2f\n",date,precipvals[count],precip3hrs[count]);
fprintf(fpout, "Date: %s, One hour precipitation: %2.2f Three
hour precipitation: %2.2f\n",date, precipvals[count],
precip3hrs[count]);
}
count++;
}

/* Write to file */
fclose(fpin);
fclose(fpout);

/* Deallocation */
free(precipvals);
free(precip3hrs);
free(date);

return 0;
}
 
A

Army1987

I'd have to look tomorrow when I get to the office.


Here's the code; it now compiles, but seg faults when I run it. (Error
proofing will be done later)

int main(int argc, char *argv[])
{
/* Variable Declarations */
const int arraylength = 5;
const int errorcode = -1;
float sum = 0;
int count = 0;
int condition = 1;
float* precipvals = (float*)NULL;
float* precip3hrs = (float*)NULL;
char date[12];
FILE *fpin;
FILE *fpout;

fpin = fopen(argv[1],"r");
fpout = fopen(argv[2],"w");
I have already told you several ways this could segfault, but you
didn't hear... Why should I waste more time?
/* Calculation Section */
while(condition != EOF) {
condition = fscanf(fpin,"%ld,%f", &date, &precipvals[count]);
I'll answer this one because it is *really* obvious. What did you
expect writing at the place pointed by a null pointer? (And that
same statement has other errors, too. Finding them is left as an
exercise.)
[snip]
 
D

dmoran21

Here's the code; it now compiles, but seg faults when I run it. (Error
proofing will be done later)
int main(int argc, char *argv[])
{
/* Variable Declarations */
const int arraylength = 5;
const int errorcode = -1;
float sum = 0;
int count = 0;
int condition = 1;
float* precipvals = (float*)NULL;
float* precip3hrs = (float*)NULL;
char date[12];
FILE *fpin;
FILE *fpout;
fpin = fopen(argv[1],"r");
fpout = fopen(argv[2],"w");

I have already told you several ways this could segfault, but you
didn't hear... Why should I waste more time?
/* Calculation Section */
while(condition != EOF) {
condition = fscanf(fpin,"%ld,%f", &date, &precipvals[count]);

I'll answer this one because it is *really* obvious. What did you
expect writing at the place pointed by a null pointer? (And that
same statement has other errors, too. Finding them is left as an
exercise.)
[snip]
return 0;
}


Hey, I'm trying my best here.

Dave
 
R

Richard Heathfield

(e-mail address removed) said:

Here's the code; it now compiles, but seg faults when I run it. (Error
proofing will be done later)

Let us know when it's ready. In the meantime, remove all the casts.
 
K

Keith Thompson

I'd have to look tomorrow when I get to the office.

Here's the code; it now compiles, but seg faults when I run it. (Error
proofing will be done later)

int main(int argc, char *argv[])
{ [snip]
float* precipvals = (float*)NULL;
float* precip3hrs = (float*)NULL;

Lose the casts.

What does your input file look like?
 
R

Richard Heathfield

(e-mail address removed) said:
I thought I did.

Well, there are still two casts in there. You'll want to lose those.

Once you've restored the error-checking that everyone has been urging
you to add for several days now, and which I took some time to add
myself in code that I posted right here in clc but which you appear to
have ignored, you will have demonstrated that you're interested in
getting the program to work by design, rather than by chance. At that
point, you are much more likely to get help with what you seem to think
is your main problem. In fact, the segfault is trivial to fix, but
fixing it is pointless if it just means that you watch your creation
lurch to the next segfault. The real problem, the one that urgently
needs to be fixed, is this lackadaisical attitude towards robustness.
 
D

dmoran21

What does your input file look like?

200701010000,3.58
200701010100,2.33
200701010200,4.55
200701010300,.29
200701010400,5.18
200701010500,0
200701010600,0
200701010700,0
200701010800,0
200701010900,.34
 
D

dmoran21

(e-mail address removed) said:



Well, there are still two casts in there. You'll want to lose those.

Once you've restored the error-checking that everyone has been urging
you to add for several days now, and which I took some time to add
myself in code that I posted right here in clc but which you appear to
have ignored, you will have demonstrated that you're interested in
getting the program to work by design, rather than by chance. At that
point, you are much more likely to get help with what you seem to think
is your main problem. In fact, the segfault is trivial to fix, but
fixing it is pointless if it just means that you watch your creation
lurch to the next segfault. The real problem, the one that urgently
needs to be fixed, is this lackadaisical attitude towards robustness.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999


Look, I'm doing the best I can. Not only am I working on this, but
I've got other projects I'm working on and I'm REALLY TRYING to learn.
The insinuation that I'm not is insulting.

Dave
 
A

Army1987

What was the actual error message? I don't recall seeing it
mentioned in this thread.
I'd have to look tomorrow when I get to the office.
Here's the code; it now compiles, but seg faults when I run it. (Error
proofing will be done later)
int main(int argc, char *argv[])
{
/* Variable Declarations */
const int arraylength = 5;
const int errorcode = -1;
float sum = 0;
int count = 0;
int condition = 1;
float* precipvals = (float*)NULL;
float* precip3hrs = (float*)NULL;
char date[12];
FILE *fpin;
FILE *fpout;
fpin = fopen(argv[1],"r");
fpout = fopen(argv[2],"w");

I have already told you several ways this could segfault, but you
didn't hear... Why should I waste more time?
/* Calculation Section */
while(condition != EOF) {
condition = fscanf(fpin,"%ld,%f", &date, &precipvals[count]);

I'll answer this one because it is *really* obvious. What did you
expect writing at the place pointed by a null pointer? (And that
same statement has other errors, too. Finding them is left as an
exercise.)
[snip]
return 0;
}
[Signature snipped. Do not quote signatures unless you're
commenting about them.]
Hey, I'm trying my best here.
If so, why did you remove all the checks we suggested to you?
 
R

Richard Heathfield

(e-mail address removed) said:

Look, I'm doing the best I can. Not only am I working on this, but
I've got other projects I'm working on

So have we all.
and I'm REALLY TRYING to learn.

Good. If you ask for advice, learn to take notice of the advice you are
given.
The insinuation that I'm not is insulting.

The evidence that you are not is overwhelming.

When I compile the code you posted (after fixing it for Usenet linewrap,
which we'll overlook), I get the following diagnostic messages:

foo.c: In function `main':
foo.c:9: `NULL' undeclared (first use in this function)
foo.c:9: (Each undeclared identifier is reported only once
foo.c:9: for each function it appears in.)
foo.c:12: `FILE' undeclared (first use in this function)
foo.c:12: `fpin' undeclared (first use in this function)
foo.c:12: warning: statement with no effect
foo.c:13: `fpout' undeclared (first use in this function)
foo.c:13: warning: statement with no effect
foo.c:15: warning: implicit declaration of function `fopen'
foo.c:19: `EOF' undeclared (first use in this function)
foo.c:20: warning: implicit declaration of function `fscanf'
foo.c:20: warning: long int format, different type arg (arg 3)
foo.c:32: warning: implicit declaration of function `printf'
foo.c:33: warning: implicit declaration of function `fprintf'
foo.c:40: warning: implicit declaration of function `fclose'
foo.c:44: warning: implicit declaration of function `free'
foo.c:6: warning: unused variable `sum'
foo.c:5: warning: unused variable `errorcode'
foo.c:4: warning: unused variable `arraylength'
foo.c:1: warning: unused parameter `argc'
make: *** [foo.o] Error 1

It's tricky to see how you can get a segfault from something that
doesn't compile.

So okay, I add the missing header, and now I only get:

foo.c: In function `main':
foo.c:22: warning: long int format, different type arg (arg 3)
foo.c:46: warning: implicit declaration of function `free'
foo.c:8: warning: unused variable `sum'
foo.c:7: warning: unused variable `errorcode'
foo.c:6: warning: unused variable `arraylength'
foo.c:3: warning: unused parameter `argc'

The first of these diagnostic messages refers to this line:

condition = fscanf(fpin,"%ld,%f", &date, &precipvals[count]);

Since date has type char[12], it's not going to match to %ld any time
soon. (There's your segfault right there.) Based on your subsequent
usage of date, I chose to change the format specifier rather than the
type.

The next message related to free() - indicating a missing header. But no
such warning occurs for malloc or calloc or realloc, which it would, if
you'd used them. So you're freeing memory you never allocated. (There's
your segfault right there.)

You don't use sum, errorcode, or arraylength, so I removed them.

You don't use argc, so you're not checking that your filenames exist
before you try to use them as filenames. (There's your segfault right
there.)

You don't check whether the files were opened successfully before you
try to read from and write to them. (There's your segfault right
there.)

You attempt to write through a null pointer several times during your
loop. (There's your segfault right there.)

So there you are - I've identified many of the places where your program
could be segfaulting. Many of these are places that have already been
identified to you as trouble spots, and it has already been recommended
to you that you fix them.

You can misread excellent advice as an insult if you like, but that's
your problem, not mine.
 
C

CBFalconer

.... snip ...

Here's the code; it now compiles, but seg faults when I run it.
(Error proofing will be done later)

int main(int argc, char *argv[])
{
/* Variable Declarations */
const int arraylength = 5;
const int errorcode = -1;
float sum = 0;
int count = 0;
int condition = 1;
float* precipvals = (float*)NULL;
float* precip3hrs = (float*)NULL;

get rid of the casts. Useless, and just hide errors. NULL is
undefined.
char date[12];
FILE *fpin;
FILE *fpout;

Without #including stdin, these can't work.
fpin = fopen(argv[1],"r");
fpout = fopen(argv[2],"w");

Failed to check for success and exit on failure. Bad.
/* Calculation Section */
while(condition != EOF) {
condition = fscanf(fpin,"%ld,%f", &date, &precipvals[count]);

Thus ignoring errors. fscanf failed if it didn't return 2.
if(count == 0) {
precip3hrs[count] = precipvals[count];
}
if(count == 1) {
precip3hrs[count] = precipvals[count] + precip3hrs[count-1];
}
if(count > 1) {
precip3hrs[count] = precipvals[count] + precipvals[count-1] +
precipvals[count-2];
}
if(condition != EOF) {
printf("Date: %s, One hour precipitation: %2.2f Three hour
precipitation: %2.2f\n",date,precipvals[count],precip3hrs[count]);

You can break up overly long strings. For example:
printf("Date: %s, One hour precipitation: %2.2f"
" Three hour precipitation: .2f\n",
date, precipvals[count], precip3hrs[count]);

Note the lack of commas, etc. between the broken-up strings.
fprintf(fpout, "Date: %s, One hour precipitation: %2.2f Three
hour precipitation: %2.2f\n",date, precipvals[count],
precip3hrs[count]);
}
count++;
}

/* Write to file */
fclose(fpin);
fclose(fpout);

/* Deallocation */
free(precipvals);
free(precip3hrs);
free(date);

return 0;
}

Only post COMPLETE compilable extracts. The reader should be able
to cut, paste into an editor, save, and compile.
 
C

CBFalconer

.... snip ...

Look, I'm doing the best I can. Not only am I working on this, but
I've got other projects I'm working on and I'm REALLY TRYING to
learn. The insinuation that I'm not is insulting.

Live with it. Also learn to snip irrelevant quoted material.
 
D

dmoran21

On Fri, 06 Jul 2007 07:30:46 -0700, (e-mail address removed) wrote:
What was the actual error message? I don't recall seeing it
mentioned in this thread.
I'd have to look tomorrow when I get to the office.
Here's the code; it now compiles, but seg faults when I run it. (Error
proofing will be done later)
int main(int argc, char *argv[])
{
/* Variable Declarations */
const int arraylength = 5;
const int errorcode = -1;
float sum = 0;
int count = 0;
int condition = 1;
float* precipvals = (float*)NULL;
float* precip3hrs = (float*)NULL;
char date[12];
FILE *fpin;
FILE *fpout;
fpin = fopen(argv[1],"r");
fpout = fopen(argv[2],"w");
I have already told you several ways this could segfault, but you
didn't hear... Why should I waste more time?
/* Calculation Section */
while(condition != EOF) {
condition = fscanf(fpin,"%ld,%f", &date, &precipvals[count]);
I'll answer this one because it is *really* obvious. What did you
expect writing at the place pointed by a null pointer? (And that
same statement has other errors, too. Finding them is left as an
exercise.)
[snip]
return 0;
}

[Signature snipped. Do not quote signatures unless you're
commenting about them.]
Hey, I'm trying my best here.

If so, why did you remove all the checks we suggested to you?


Ok I found the version with the checks. I thought it'd be easier to
deal with getting it to run and then going back to put in the checks.
 

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,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top