C - Работа с fopen, fclose, fputc и т. Д. - PullRequest
1 голос
/ 28 декабря 2011

Этот код наконец-то работает с одним аргументом в моей командной строке, то есть с одним файлом для работы с ним, хотя я разработал код с концепцией, работающей с неограниченным количеством файлов.Что он делает, это берет некоторое количество X текстовых файлов, содержащих слова, разделенные пробелами, и заменяет пробелы на \n, создавая таким образом список слов.Хотя он успешно завершает первый аргумент, он просто игнорирует второй.

Другая незначительная проблема, кажется, в том, что она также печатает какую-то мусорную букву в конце, Y с двумя точками над ней;Я предполагаю некоторый символ EOF, но я не могу остановить это!

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 Ответ

4 голосов
/ 28 декабря 2011

Функции (или макросы) getchar(), getc() и fgetc() возвращают int, а не char.

Вы должны использовать:

int c;

while ((c = fgetc(fpIn)) != EOF)
{
    if (isspace(c))
        c = '\n';
    fputc(c, fpOut);
}

Думаю об этом;функции должны иметь возможность возвращать любые действительные значения char и EOF (которые отличаются от любого действительного значения char. Поэтому, по определению, возвращаемое значение не может быть char ...

Что произойдет, если вы используете char?

  • Ваш исходный код не инициализировал c перед его тестированием (поэтому цикл может прерваться раньше).
  • Ваш код не проверял c сразу после чтения EOF (поэтому он может печатать символ мусора, часто ÿ, МАЛЕНЬКОЕ ПИСЬМО Y С ДИАРЕЗОМ, U + 00FF).
  • Если ваш char тип без знака, вы никогда не увидите EOF.
  • Если ваш тип char подписан, некоторые действительные символы (часто снова ÿ) будут неверно истолкованы как EOF.

Я все еще не могу заставить его работать с несколькими аргументами.

Проблема в том, что у вас есть двойной цикл:

int i, j;
j = 1;

while (argc--)
{
    for (i = 1; i < argc; i++)
    {
        fpIn = fopen(argv[j], "rb");
        ...process fpIn...
        j++;
    }
}

Допустим, вы вызываете команду с двумя именами файлов;затем argc == 3.

После первого раза после цикла while, argc == 2.Затем вы делаете for цикл с i, принимающим значение 1;вы открываете argv[1] (потому что j == 1).Вы обрабатываете этот файл;затем увеличиваем j до 2, а затем также увеличиваем i, также до 2. Во второй раз вокруг цикла for, i == 2, как и argc, поэтому цикл for завершается.Цикл while снова уменьшается на argc до 1, но проверяет, что 2 != 0.Однако цикл for устанавливает i = 1 и затем завершается, поскольку i == argc.Цикл while уменьшает argc до 1 и повторяет.

Вы можете использовать цикл while или for, но вам не нужны оба.

Итак, либо:

for (i = i; i < argc; i++)
{
    ...process argv[i]...
}

Или:

while (--argc > 0)
{
    ...process *++argv...
}

Я бы использовал цикл for.

...