Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
753 views
in Technique[技术] by (71.8m points)

file io - C - Working with fopen, fclose, fputc etc

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 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("
");
    printf("The following arguments were passed to main(): ");
                for(i=1; i<argc; i++) printf("%s ", argv[i]);
    printf("
");

    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 = '
';
                fputc(c, fpOut );
            }
            j++;
        }
    }
    return 0;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 = '
';
    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 c before testing it (so the loop might break early).
  • Your code didn't test c immediately after reading EOF (so it might print a garbage character, often ?, LATIN SMALL LETTER Y WITH DIAERESIS, U+00FF).
  • If your char type is unsigned, you'd never see EOF.
  • If your char type 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...