fgetc нулевой терминатор - PullRequest
       29

fgetc нулевой терминатор

4 голосов
/ 05 января 2012

Я делаю упражнение в K & R:

Напишите отсоединение программы, которое заменяет вкладки на входе соответствующим количеством пробелов для пробела до следующей остановки табуляции.

И это то, что у меня до сих пор (без проверки ошибок в файле):

#include <stdio.h>
#define tab 2
#define MAX_LENGTH 1000
int main(int argc, char **argv)
{
    FILE *fp = fopen(argv[1], "r+");    
    int c, n;
    char buffer[MAX_LENGTH + 1];
    for (n = 0; n < MAX_LENGTH && (c = fgetc(fp)) != EOF; ++n) {
        if (c == '\t') {
            for (int x = 0; x < tab; ++x)
                buffer[n++] = ' ';
            --n;
        }
        else
            buffer[n] = c;
    }
    //buffer[n] = '\0';
    //rewind(fp);
    //fputs(buffer, fp);
    printf("%s\n", buffer);
    fclose(fp);
    return 0;
}

Кажется, это работает, но мне интересно, почему \0 не был необходимв конце.Мне просто повезло?

Ответы [ 4 ]

5 голосов
/ 05 января 2012

Да, тебе повезло.Чтобы избежать этой проблемы, вы могли бы использовать fwrite, который не требует нулевого терминатора (поскольку вы точно указываете, сколько байтов должно быть записано):

fwrite(buffer, 1, n, stdout);
4 голосов
/ 05 января 2012

Вы можете указать printf(...) (максимальное) количество символов для печати для данной строки.

printf("%.*s\n", n, buffer);

См. printf (3) ,раздел «Точность»:

Необязательная точность в виде точки ('.'), за которой следует необязательная строка десятичных цифр.Вместо строки десятичной цифры можно написать «*» [...], чтобы указать, что точность указана в следующем аргументе [...], который должен иметь тип int.[...] Это дает [...] максимальное количество символов, которое будет напечатано из строки для s [...] преобразований.

Демонстрационная версия printf ("%.*s\n", 5, "Hello, world!"): http://ideone.com/KHKLl.

2 голосов
/ 05 января 2012

Вы можете инициализировать ваш буфер с помощью:

memset(buffer, '\0', MAX_LENGTH + 1);

И вам не придется беспокоиться о нулевом завершении.

1 голос
/ 05 января 2012

Как указывалось в других ответах, вам повезло, что массив содержал нули в нужных местах.

Вы можете инициализировать его при создании с использованием этого сокращения:

char buffer[MAX_LENGTH + 1] = { 0 }; // all elements will be zero

Обратите внимание, что это потому, что компилятор инициализирует неопределенные записи с нулями - так что если вы сказали

char buffer[MAX_LENGTH + 1] = { 'a' };

тогда массив будет {'a',0,0,0....}

...