fgets () и странные символы в конце строки, в C - PullRequest
0 голосов
/ 13 марта 2020

Я пытаюсь получить строку из стандартного ввода в C. Поэтому я попытался использовать самую глупую вещь:

int main(){
      int j;
      char name[20];

   printf("Who are you? ");
   fgets(name,20,stdin);
   printf("Glad to meet you, %s",name);

      for(j=0;j<20;j=j+1){
          printf(" %d = %c\n  ", j, name[j]);
      }   
}

И появляются все эти странные символы:

    Who are you? Hana
Glad to meet you, Hana
   0 = H
   1 = a
   2 = n
   3 = a
   4 =

   5 =
   6 =  
   7 =  
   8 = Ŕ
   9 = ■
   10 = `
   11 =
   12 = Ý
   13 = o
   14 = 
   15 = v
   16 = P
   17 = 
   18 = @
   19 =

Что происходит?

Ответы [ 4 ]

2 голосов
/ 13 марта 2020

Когда вы ввели символы Hana, то шесть элементов имени массива получили следующие значения

{ 'H', 'a', 'n', 'a', '\n', '\0' }

Примечание: fgets также помещает символ новой строки '\ n', который соответствует нажатая клавиша Enter, если в массиве символов назначения достаточно места для его хранения.

Все остальные элементы имени массива не получили значений.

Для вывода фактических значений массива, исключая новые символ строки и завершающий ноль вы можете написать

  for( j = 0; name[j] != '\n' && name[j] != '\0'; j++ ){
      printf(" %d = %c\n  ", j, name[j]);
  }  
1 голос
/ 13 марта 2020

Ничего необычного. Строка "Hana" была сохранена в переменной name. Строка заканчивается нулем, поэтому было написано 5 символов: 'H', 'a', 'n', 'a' и '\0'. Остальная часть буфера осталась нетронутой.

Вы не должны читать за пределами буфера, но внутри буфера все, что после завершающего '\0', остается нетронутым. Поскольку вы не инициализировали буфер, он может содержать произвольные данные.

0 голосов
/ 13 марта 2020

Обратите внимание, что строка не является массивом char. Правильная строка - это все, вплоть до первого нулевого символа, который завершает правильную строку.

Массив, здесь name, - это хранилище, в котором хранится строка. Строка может быть не такой длины, как размер массива, как в вашем примере, но массив должен быть способен содержать строку (включая завершающий \0) как минимум.

Ввод "hana" на fgets занимает только первые 6 символов name - h, a, n, a, \n и \0. Обратите внимание, что fgets также добавляет символ новой строки, созданный нажатием, для возврата к правильной строке.

Символьные элементы в name после элемента с \0 не назначаются с \0.

Все, что напечатано после \0, является просто мусором, поскольку name не было квалифицировано как extern или static, содержимое не инициализируется.

Обратите внимание, что \n и \0 не являются печатными символами
.

0 голосов
/ 13 марта 2020

Возможно, вы неправильно инициализировали массив. Кроме того, не следует ли передать указатель на массив, который вы собираетесь использовать?

...