问题
I've got this code finally working with a single argument on my command line, i.e. one file for it to work with, although I designed the code with the concept of it working with an unlimited number of files. What it does is take some X number of text files containing words separated by spaces, and replaces spaces with \n thus creating a list of words. Though, it successfully completes the first argument, it just ignores the 2nd.
Another minor problem seems that it also prints out some garbage letter at the end, a Y with two dots above it; I assume some EOF symbol, yet I can't seem to stop that happening!
int main(int argc, char** argv) {
FILE *fpIn, *fpOut;
int i, j;
j = 1;
char c;
char myString[256];
printf("%d", argc);
printf("\n");
printf("The following arguments were passed to main(): ");
for(i=1; i<argc; i++) printf("%s ", argv[i]);
printf("\n");
while(argc--) {
for(i = 1; i < argc; i++) {
fpIn = fopen(argv[j], "rb");
snprintf(myString, 256, "%s~[%d]", argv[j], i);
fpOut= fopen(myString, "wb");
while (c != EOF) {
c = fgetc(fpIn);
if (isspace(c))
c = '\n';
fputc(c, fpOut );
}
j++;
}
}
return 0;
}
回答1:
The getchar(), getc() and fgetc() functions (or macros) return an int, not a char.
You must use:
int c;
while ((c = fgetc(fpIn)) != EOF)
{
if (isspace(c))
c = '\n';
fputc(c, fpOut);
}
Think about it; the functions must be able to return any valid char and EOF (which is distinct from any valid char value. So, by definition, the return value can't be a char...
What happens if you use char?
- Your original code didn't initialize
cbefore testing it (so the loop might break early). - Your code didn't test
cimmediately after reading EOF (so it might print a garbage character, often ÿ, LATIN SMALL LETTER Y WITH DIAERESIS, U+00FF). - If your
chartype is unsigned, you'd never see EOF. - If your
chartype is signed, some valid characters (often ÿ again)) will be misinterpreted as EOF.
I still can't seem to get it working for multiple arguments though.
The problem there is the double loop you have running:
int i, j;
j = 1;
while (argc--)
{
for (i = 1; i < argc; i++)
{
fpIn = fopen(argv[j], "rb");
...process fpIn...
j++;
}
}
Let us suppose you invoke the command with two file names; then argc == 3.
After the first time past the while loop, argc == 2. You then do a for loop with i taking the value 1; you open argv[1] (because j == 1). You process that file; then increment j to 2, before also incrementing i, also to 2. The second time around the for loop, i == 2 as does argc, so the for loop terminates. The while loop decrements argc again to 1, but tests that 2 != 0. However, the for loop sets i = 1 and then terminates because i == argc. The while loop decrements argc to 1, and repeats.
You can use a while loop or a for loop, but you don't need both.
So, either:
for (i = i; i < argc; i++)
{
...process argv[i]...
}
Or:
while (--argc > 0)
{
...process *++argv...
}
I'd use the for loop.
来源:https://stackoverflow.com/questions/8650491/c-working-with-fopen-fclose-fputc-etc