понимание fputc - PullRequest
       6

понимание fputc

0 голосов
/ 01 апреля 2012

Я пытаюсь получить общее представление о том, как использовать fputc в C. Я прочитал некоторую документацию, которая существует, и я считаю, что у меня все было правильно. Но каждый раз, когда я пытаюсь использовать сценарий, который я написал, выполните . / Fputc> test.txt , где text.txt - текстовый файл с одной строкой текста.

Это мой сценарий:

int
main(int argc, char **argv){
    int ch;
    FILE *input;
    input = fopen("text.txt", "w+");
    while ((ch = getchar()) != EOF){
        fputc(ch, input);
    }
    fclose(input);

    return 0;
}

Я не получаю ошибок при компиляции, и по какой-то причине скрипт не достигает EOF в конце текстового файла. Разве getchar не должен возвращать EOF, когда достигнет конца текстового файла? Текстовый файл (text.txt) не редактируется, хотя он и создан. Так что где-то в моем цикле while что-то идет не так.

Я новичок в программировании на C (если вы не могли сказать), и этот маленький скрипт меня озадачил.

Буду признателен за любую помощь, или любые ссылки на сайты с более подробной информацией также будут хороши.

Приветствия

S.

Ответы [ 3 ]

2 голосов
/ 01 апреля 2012

То, что вы в сущности говорите:

  • Консоль: Запустите my_program и запишите все, что он выводит в te s t.txt.

  • Программа: Откройте te x t.txt и запишите любой ввод в stdin этого файла.


У вашей консоли обычно есть три стандартных потока stdin, stdout и stderr. Эти потоки вы можете перенаправить . Если вы работаете в Windows, посмотрите, например, перенаправление .

Когда вы говорите ./my_prog > test.txt, то, что вы говорите своей консоли (не my_prog), это записать что-нибудь my_prog, записывающее stdout в файл test.txt.

Если вы в своем коде говорите, т. Е. printf("Hello");, тогда Hello будет записано в файл test.txt.

Если бы вы перевернули перенаправление, сказав вместо этого ./my_prog < test.txt, было бы; передать файл test.txt в my_prog . Что, в свою очередь, если бы в test.txt был какой-либо текст, привело бы к копированию test.txt в text.txt.

Теперь в своем коде вы говорите:

int main(void) 
{
    int ch;
    FILE *input;

    /* Here you open a handle to the file text.txt for reading and writing */
    input = fopen("text.txt", "w+");

    while ((ch = getchar()) != EOF) { /* get next char from stdin */
        fputc(ch, input); /* write that char to the handle input */
    }
    fclose(input); /* close the handle */

    return 0;
}

Итак, что произойдет, как вы запустите это:

В вашем коде:

  1. Открыть текст.txt
  2. Ожидание ввода (данные вводятся в стандартный ввод) - обычно пользователь вводит текст в консоль, передается в программу при нажатии Ввод .

В консоли:

  1. Перенаправить что-нибудь из my_prog в test.txt.

Вы говорите:

скрипт не достигает EOF

Ну, так как он читает из stdin, он только (не без исключения) получит EOF при двух условиях.

  1. Если вы перенаправите файл в вашу программу. То есть ./my_prog < foo.txt (уведомление <, а не >).
    - Что тогда произойдет, это то, что my_prog будет читать данные из файла foo.txt, и когда этот файл завершится, ваша программа получит EOF. И, следовательно, выйти.

  2. Если вы вручную введете EOF в stdin.
    - В Linux и OSX Ctrl - D , в Windows Ctrl - Z


Теперь, если вы проверите это, набрав текст на консоли, помните, что действия записи, такие как fputc(), буферизуются. Это означает, что данные не сразу записываются в файл, а только когда в буфере находится определенный объем данных, вызывается fflush(), поток закрывается, вы отключаете буферизацию и т. Д.

Также; если вы запустите свою программу. Введите текст, введите еще какой-нибудь текст, а затем нажмите Ctrl-C , чтобы прервать выполнение программы. Вероятность того, что вы закончите без данных в вашем text.txt.

, велика.

Причина этого в том, что программа убита и поэтому fclose() никогда не вызывается, и, следовательно, нет сброса в файл.


В ваших дальнейших усилиях в программировании было бы очень неплохо выработать привычку ничего не предполагать. То есть не предполагайте, что fopen() в порядке.

FILE *fh;
char *outfile = "foo.txt";

if ((fh = fopen(outfile, "w")) == NULL) {
    fprintf(stderr,
            "Unable to open file %s\n --",
            outfile);
    perror(" fopen() ");
    return 1;
}

У большинства функций есть способ проверить, была ли операция успешной. То есть:

if (fputc(ch, fh) != ch) { err ...

Это сделает ваш код намного безопаснее, даст подсказки о том, где он не работает и т. Д.


Некоторые ссылки:

0 голосов
/ 01 апреля 2012

ваша программа и оболочка пишут один и тот же файл. Вы должны удалить перенаправление вывода > test.txt из командной строки

0 голосов
/ 01 апреля 2012

getchar возвращает следующий символ из стандартного ввода (стандартный ввод).Это эквивалентно getc с stdin в качестве аргумента.

Следовательно, ваш код читает со стандартного ввода вместо ввода FILE *.

Используйте здесь fgetc.fgetc возвращает символ, указанный в данный момент внутренним индикатором положения файла указанного потока.Внутренний индикатор положения файла затем передвигается на один символ, чтобы указать на следующий символ.

Итак, используйте fgetc для чтения из файла:

while ((ch = fgetc(input)) != EOF)
...