Строки, взятые у пользователя в C, зашифрованы

Я написал следующий код C, чтобы получить список строк от пользователя. Но сохраненные строки выдают странные значения.

#include <stdio.h>
#include <stdlib.h>


#define MAX_STRING_LENGTH 50


void readInStrings(char* arr[],int n)
{
  int i=0;
  char line[MAX_STRING_LENGTH];

  for(i=0;i<n;i++){
    arr[i]=malloc(MAX_STRING_LENGTH);
    printf("Enter another string : ");
    scanf("%s",&arr[i]);
    //fgets(&arr[i],MAX_STRING_LENGTH,stdin);
  }



  printf("Strings read in correctly.... \n");

  printf("Displaying out all the strings:   \n");
  for(i=0;i<n;i++){
    printf("%s\n",&arr[i]);
  }
}



void testStringInputs()
{
  printf("Enter the number of entries : ");
  int n;
  scanf("%d",&n);

  char* strings[n];
  readInStrings(strings,n);
}

Входной образец:

Введите количество записей : 3
Введите другую строку : Alladin
Введите другую строку : Barack Obama
Введите другую строку : Строки прочитаны правильно....
Отображение всех строк:
АллаБараОбама
БараОбама
Обама

Проблемы: 1) Почему одна строка вообще не принимается на вход?
2) Почему отображаемые строки так зашифрованы?

Проблема та же, если я использую gets() или fgets() вместо scanf().


person Arjun J Rao    schedule 19.03.2011    source источник
comment
fgets - гораздо более безопасный вариант, если вы сделаете исправление, указанное в ответе. Вы можете легко переполнить буфер с помощью scanf(и %s) или gets.   -  person jonsca    schedule 19.03.2011
comment
Если я не использую &arr[i] в ​​операторе printf, программа падает. И проблема остается той же даже с fgets(), строки выходят зашифрованными. Также пропускается одна итерация цикла ввода for.   -  person Arjun J Rao    schedule 19.03.2011


Ответы (3)


Удаление & (как заметил первый ответивший) в scanf("%s",&arr[i]); и в printf("%s\n",&arr[i]); помогло мне. Кроме того, обратите внимание, что если вы скомпилировали с предупреждениями на самом высоком уровне, ваш компилятор сразу сказал бы вам, что & был неуместен.

person jonsca    schedule 19.03.2011
comment
Не могли бы вы сказать мне, почему одна итерация fgets() пропускается, когда я ее использую? Сканф() работает нормально. - person Arjun J Rao; 19.03.2011
comment
Вставьте getchar(); сразу после scanf("%d",&n); в testStringInputs(). Когда вы набираете 3 ‹enter› 3 сохраняется в n, но во входном потоке есть лишний '\n'. Первый fgets в функции принимал это как строку ввода. - person jonsca; 19.03.2011
comment
Да. Это сработало. Спасибо. Есть ли место, где я могу научиться избегать большего количества этих ловушек при вводе/выводе в C? Книга или сайт? - person Arjun J Rao; 19.03.2011
comment
Для этой конкретной проблемы это хорошая ссылка, но в целом это хороший справочник. Есть книга Эндрю Кенига о подводных камнях C, но я никогда ее не читал. Я получаю много информации из таких мест, как S.O. также. - person jonsca; 19.03.2011

arr[i] уже является указателем, вам не нужен &

person Martin Beckett    schedule 19.03.2011

Лучше использовать массив массивов (двумерный) вместо массива указателей. Мне было трудно исправить ваш код. Поэтому я изменил код на этот

#include <stdio.h>
#include <stdlib.h>
#define MAX_STRING_LENGTH 50
void readInStrings(char (*arr)[MAX_STRING_LENGTH],int n)
{
  int i;
  for(i = 0 ; i< n+1; ++i)
   fgets(*(arr+i),MAX_STRING_LENGTH,stdin);
  printf("Strings read in correctly.... \n");
  printf("Displaying out all the strings:   \n");
  for(i=0;i< n+1;i++){
    printf("%s",arr[i]);
  }
}
int main()
{
  printf("Enter the number of entries : ");
  int n;
  scanf("%d",&n);
  char strings[n][MAX_STRING_LENGTH];
  readInStrings(strings,n);
  return 0;
}
person Prasoon Saurav    schedule 19.03.2011
comment
Но массив строк ЯВЛЯЕТСЯ массивом указателей, не так ли? Я знал, что ваше решение было одним из способов сделать это, но я хотел быть... концептуально чистым, если позволите. - person Arjun J Rao; 19.03.2011