Silly newbie question: Stop all processing on condition

P

philbo30

Newbie here, just need a little general C direction:

I've a function that counts text lines in a file. If the file contains
less than 1000 lines of text, I know my input is garbage and I need
the app to completely stop all further processing. Currently, the
counting and evaluation works fine, but my app keeps on processing.
Here's the code I have so far:

int inputcheck()
{
file *fp;
int linecounter = 0;
int ch;
fp = fopen("hooligans.txt","r");
if (fp==NULL)
{
perror("fopen");
return EXIT_FAILURE;
}
while ((ch= getc(fp)) !=EOF)
{
if (ch == '\n') linecounter++;
}
fclose(fp);
if (linecounter < 1000)
{
printf("Garbage In, Don't Continue Processing\n"); //NEED TO STOP
ALL PROCESSING IF HERE
return -1;
}
else
return 0;
}
}
 
U

user923005

If you want to stop processing on the spot using the C language, then
use:
exit(EXIT_FAILURE);

you will need to include stdlib.h as this contains the prototype for
exit() and the macro definition for EXIT_FAILURE.

When you want to get a solution to a problem, the best way to do it is
to provide a small, compilable program that reproduces the problem.

Your code snippet is not in compilable shape.

The reason that it is a good idea is that often by simplification you
will solve the problem yourself and not even have to ask anyone.
 
K

Keith Thompson

CBFalconer said:
It is possible that EXIT_FAILURE on your machine evaluates to -1 or
0, when the treatment of the return value will depend on the order
of tests.

It's unlikely that EXIT_FAILURE evaluates to 0, unless the system is
incapable of indicating failure.
 
O

osmium

philbo30 said:
Newbie here, just need a little general C direction:

I've a function that counts text lines in a file. If the file contains
less than 1000 lines of text, I know my input is garbage and I need
the app to completely stop all further processing. Currently, the
counting and evaluation works fine, but my app keeps on processing.
Here's the code I have so far:

int inputcheck()
{
file *fp;
int linecounter = 0;
int ch;
fp = fopen("hooligans.txt","r");
if (fp==NULL)
{
perror("fopen");
return EXIT_FAILURE;
}
while ((ch= getc(fp)) !=EOF)
{
if (ch == '\n') linecounter++;
}
fclose(fp);
if (linecounter < 1000)
{
printf("Garbage In, Don't Continue Processing\n"); //NEED TO STOP
ALL PROCESSING IF HERE
return -1;
}
else
return 0;
}
}

Your code seems to count characters rather than lines. Did you mean,
perhaps, to use fgets instead of fgetc?
 
F

Fred Kleinschmidt

osmium said:
Your code seems to count characters rather than lines. Did you mean,
perhaps, to use fgets instead of fgetc?

Seems to me that linecounter is only incremented when the character read
is \n, so it indeed does count lines, not characters. However, it will
miscount
by one if the final character is not a newline

I do not understand the OP's claim that this program "keeps on processing".
To the OP: What do you mean by that statement? How do you call
inputcheck? What do you do with its return value?
 
O

osmium

CBFalconer said:
You didn't read the condition controlling "linecounter++". That
code can be quite efficient, and avoids the need for buffers of
unknown length.

I have already said that I didn't look at the code closely enough. (Most
Americans knows what "darn" means) As far as efficiency, I would rate it as
about as bad as it can get. The code says that one function call is
replaced by something like 30-80 function calls. Some compilers may avoid
that by some machinations, but there are no assurances. (Guarantees are
something you get with Die Hard batteries at Sears.)

I would use a buffer of length 256, fgets, and hope for the best.
 
D

Dave Vandervies

... snip and code slightly edited ...
[/QUOTE]
As far as efficiency, I would rate it as
about as bad as it can get. The code says that one function call is
replaced by something like 30-80 function calls. Some compilers may avoid
that by some machinations, but there are no assurances. (Guarantees are
something you get with Die Hard batteries at Sears.)

getc is specifically permitted to be a macro that can be expanded inline
with no function call for the general case, and any self-respecting
implementation that cares about execution speed[1] will implement it
that way.

So the code with getc will make one function call every time the stdio's
internal buffer needs to be re-filled (plus any calls needed by the
buffer-filling code), while the code with fgets will make one function
call per buffer fill (in fgets's internals), plus one call per block
(to fgets from your code), plus the code you need to check whether the
fgets actually read a '\n'.

In any case, you could run a horribly inefficient seven-buffer version
that checks for newlines with "atan(ch)==atan('\n')", compiled with a
non-optimizing compiler, and the extra overhead that gets introduced by
doing it that way will probably still be less than the time it takes to
pull a character through the I/O system.

Efficiency only matters when it matters, which is Not Very Often.


dave

[1] There may be self-respecting implementations that don't care about
execution speed; for example, an implementation that aggressively
checks for bad code would probably insert checks for side effects
in the expansion of the argument to getc and then call a function
that would do the same checking as fgetc.
 
O

osmium

Dave Vandervies said:
Efficiency only matters when it matters, which is Not Very Often.

But that is the subject here! Efficiency. CBFalconer said the code "can be
quite efficient", and I didn't disagree. The point is that it can also be
quite inefficient. The *code* says n function calls per line instead of one
call per line. I am well aware of the macro permission. Which is why I
said things the way I said them. Did you see the word "machinations"? Did
you see the thing about "assurances"?
 
D

Dave Vandervies

But that is the subject here! Efficiency. CBFalconer said the code "can be
quite efficient", and I didn't disagree. The point is that it can also be
quite inefficient.

This code can also be quite inefficient:
--------
int main(void)
{
return 0;
}
--------
But it won't be. And neither will code that uses getc to read characters
and look at them one at a time.
The *code* says n function calls per line instead of one
call per line.

No. The *code* says "get a character; if it's a newline increment a
counter, otherwise do nothing". Whether or not a syntactic construct
called a "function call" exists in the source code has no bearing on
what the generated code on the other side of an optimizing compiler does,
and anybody who cares about efficiency should already know that.


And if you're reading the characters from an I/O stream, pulling them
through the I/O system is going to be the bottleneck anyways, so how
efficiently you look at them isn't going to matter.


If you don't believe me, time it. With a huge file. If you can show
me numbers that prove you're right, I'd be interested in seeing them.



dave
 
T

Tor Rustad

philbo30 said:
Newbie here, just need a little general C direction:

I've a function that counts text lines in a file. If the file contains
less than 1000 lines of text, I know my input is garbage and I need
the app to completely stop all further processing. Currently, the
counting and evaluation works fine, but my app keeps on processing.
Here's the code I have so far:

int inputcheck()
{
file *fp;

FILE *fp;
int linecounter = 0;
int ch;
fp = fopen("hooligans.txt","r");
if (fp==NULL)
{
perror("fopen");
return EXIT_FAILURE;
perror("hooligans.txt");
exit(EXIT_FAILURE);

}
while ((ch= getc(fp)) !=EOF)
{
if (ch == '\n') linecounter++;
}
fclose(fp);
if (linecounter < 1000)
{
printf("Garbage In, Don't Continue Processing\n"); //NEED TO STOP
ALL PROCESSING IF HERE
return -1;

exit(EXIT_FAILURE);
 
K

Keith Thompson

CBFalconer said:
Fred Kleinschmidt wrote:
... snip ...

Then, in C terms, the final "line" is not a line.

Maybe.

C99 7.19.2p2:

A text stream is an ordered sequence of characters composed into
_lines_, each line consisting of zero or more characters plus a
terminating new-line character. Whether the last line requires a
terminating new-line character is implementation-defined.
 

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,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top