Ugh! Please learn more about basic input. Your program has various flaws:
fgetc
reads single characters. This can be useful at times, but obviously you want to read whole lines. fgets
does this. You use it once, but it is not advisable to mix these. Decide up front which input paradigm you want to use: char-wise (fgetc
), line-wise (fgets
) or token-wise (fscanf
).
- Please don't make the user enter the number of characters in the filename. Quick, how many characters are there in
MySpiffyDocument.txt
? That's work that the computer should do.
- Don't use
feof
to control yopur input. All input functions have special return values toat indicate that either the end of the file was read or that an error occurred. For fgets
, this return value is NULL
, for fgetc
, this return value is the special constant EOF
. The functions feof
and ferror
are useful after you have encountered the special return values for a post mortem analysis of the two end conditions.
- Your inner loop, which is responsible for the core program logic, doesn't make sense at all. For example, for an odd
l
, increment l
and then test for an even l
– which will be true, because you have just incrremented an odd l
. Use else
in such cases. And don't place things that happen anyway in conditional blocks: Increment l
once after the if
/else
blocks.
Here's an example implementation:
#include <stdlib.h>
#include <stdio.h>
int process(const char *filename)
{
char line[80];
char name[80];
int size;
int count = 0;
FILE *f = fopen(filename, "r");
if (f == NULL) return -1;
while (fgets(line, sizeof(line), f)) {
if (count % 2 == 0) {
if (sscanf(line, "%s", name) < 1) continue;
} else {
if (sscanf(line, "%d", &size) < 1) continue;
printf("%12d %s\n", size, name);
}
count++;
}
fclose(f);
return 0;
}
int main()
{
char line[80];
char name[80];
puts("Please enter filename:");
while (fgets(line, sizeof(line), stdin)) {
if (sscanf(line, "%s", name) == 1) {
process(name);
break;
}
}
return 0;
}
Things to note:
- The program uses 80 characters a max. buffer size; that means your lines can be up to 78 characters long – line content plus new-line
'\n'
plus null terminator '\0'
. That should be okay for many cases, but eventually the line may overflow. (So your file-name letter count has some merit, but the real solution here is to allocate memory dynamically. I won't open that can of worms now.)
- The code uses a double strategy: Read lines first, then scan into these lines with
sscanf
, so that only the first word on each line is read.
- Empty lines are skipped. Even lines that don't hold a valid number are skipped, too. This is sloppy error handling and may trip the odd/even count.
- Reading stuff interactively from the keyboard isn't very easy in C. The awkward
fgets
/sscanf
construct in main
tries to handle the case when the user enters an empty line or evokes an end-of-file signal via Ctrl-D/Z. A better and easier way is to provide arguments to the command line via argc
and argv
.
- I've moved the file reading into a separate function.