2012-01-05 3 views
4

Я делаю упражнения в K & R:fgetc нуль-терминатор

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

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

#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 не нужна на конец. Мне просто повезло?

ответ

5

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

fwrite(buffer, 1, n, stdout); 
+0

Спасибо! Имеет смысл. – mwlow

2

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

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

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

+1

В этом случае он не будет перегружать буфер - позиция в буфере ('n') проверяется как« MAX_LENGTH ». В его коде 'MAX_LENGTH' - максимальная длина вывода, а не вход. –

+0

Хороший момент, по какой-то причине я «видел», что использовал другую переменную для. –

1

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

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

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

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

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

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

+0

Спасибо за подсказку. Я никогда не замечал, что {0} установил все элементы равными нулю только потому, что неуказанные записи будут инициализированы до нуля. – mwlow

4

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

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

printf(3) См, раздел "The точность":

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

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

Смежные вопросы