Невозможно ввести 2 ввода от пользователя с неизвестной длиной указателя на символ - PullRequest
0 голосов
/ 02 мая 2020

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

          char *str1;
          char ch;
          printf("Enter a sentence:(Ex: Computer Engineer)");
          str1 = (char*)malloc(sizeof(char*));
          scanf(" %s", str1);
          printf("Enter a character to search(Ex: g):");
          scanf(" %c", &ch);
          char *result;
          result=mystrchr(str1,ch);
          if(result!=NULL)
            printf("%s",result);
          else
            printf("NULL");

Ответы [ 2 ]

1 голос
/ 02 мая 2020

Второе точно такое же утверждение

str1 = (char*) malloc(sizeof(char*));

является излишним, неуместным и бесполезным. Тем самым вы выделяете другое пространство памяти, на которое указывает str1; оставляя предыдущее выделенное пространство из-за отсутствия free() заброшенного, но существующего в памяти.


char *str1;
str1 = (char*) malloc(sizeof(char*));

При этом вызове malloc() вы выделяете память размера указателя на char обычно 4 байта в большинстве современных систем, а не место, необходимое для хранения строки типа "Computer Engineer". С этим определением можно хранить только строку 3 символов плюс автоматически добавляемый завершающий строку нулевой символ (4 символа на 4 байта).

Путем ввода строки длиной более 3 символов при вызове scanf():

scanf(" %s", str1);

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


Вам нужно выделить достаточно места для хранения предоставленных строк - в случае fe "Computer Engineer" это должно иметь не менее 18 байт (обратите внимание, что sizeof(char) == 1):

char *str1 = malloc((sizeof(char) * 18);

или альтернативно:

char *str1 = malloc((sizeof(*str1) * 18);

Обратите внимание, что вы не можете вставить слово, разделенное пробелами, используя %s спецификатор формата. Для этого используйте %[ вместо:

scanf("%[^\n]", str1);

Или еще лучше используйте более надежный и безопасный fgets():

fgets(str1,18,stdin);

Если вы хотите выделить память в зависимости от ввода пользователя, вам нужно добавить еще один запрос ввода и переменную перед распределением:

int len;

printf("How many characters the string should have?");
scanf("%d",&len);

char *str1 = malloc((sizeof(*str1) * (len + 1));     // +1 element for null character.

printf("Enter a sentence:(Ex: Computer Engineer)");
fgets(str1,len,stdin);

Примечание:

Вам не нужно приводить возвращенный указатель из malloc -> Я разыграю результат Малло c?

0 голосов
/ 02 мая 2020

Программирование - это не просто выравнивание строк кода. Распределение памяти в C не очень сложно, но с ним очень легко написать ошибочный код (вы сделали ...).

Это просто ошибка ... плохой код:

  str1 = (char*)malloc(sizeof(char*));  // Wrong: you allocate a char array with
                                        //  the size of a char pointer: nonsense
  printf("Enter a sentence:(Ex: Computer Engineer)");  // no error here :-)
  str1 = (char*)malloc(sizeof(char*));  // Wrong: the previously allocated array is
                                        //  now leaked: you can no longer free it
  scanf(" %s", str1);                   // What if input is larger than sizeof(char*)?

Теперь на ваш вопрос: scanf читает пустые токены с разделителями. Это функция . Если вы хотите линейно-ориентированный ввод, вы должны использовать fgets.

Код может быть:

#define SIZE 16
size_t size = SIZE;         // initial size of the allocated array
char *str1 = malloc(size);  // sizeof(char) is by definition 1
char ch[2];                 // a trick to read next non blank character

printf("Enter a sentence:(Ex: Computer Engineer)");
char *str = str1;
for(;;) {                                // loop to accept arbitrary length input
    if (NULL == fgets(str, size, stdin)) {
        perror("Input error or end of file");
        return 1;
    }
    if (strchr(str, '\n') != -1) break;   // ok we have a full line
    str1 = realloc(str1, size * 2);
    if (NULL == str1) {
        perror("Could not allocate memory");
        return 1;
    str = str1 + size - 1;                // point after currently got data
    size = size * 2;
}
printf("Enter a character to search(Ex: g):");
scanf("%1s", ch);
char *result = mystrchr(str1,ch[0]);
...

Осторожно: код не проверен и может содержать опечатки ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...