C читать строку из ошибки STD - PullRequest
0 голосов
/ 15 мая 2011

Я хочу прочитать строку из стандартного ввода и вывести ее на консоль. Я использую этот способ:

char* cmdline;

do{
    scanf("%s\n", &cmdline);
    printf("%s\n", cmdline);
}while(cmdline != "quit");

Но это не работает. У меня есть эта ошибка Segmentation fault (core dumped)

Ответы [ 4 ]

4 голосов
/ 15 мая 2011
char* cmdline

- указатель.Вы не выделяете место для хранения строки.Вы должны сделать:

cmdline = malloc(size_of_string);

для выделения динамической памяти для хранения строки.В противном случае вместо указателя используйте массив char:

char cmdline[size_of_string];
3 голосов
/ 15 мая 2011
char cmdline[80];

do {
    scanf("%79s\n", cmdline);
    printf("%s\n", cmdline);
} while(strcmp(cmdline, "quit"));

Я заметил три ошибки с вашим кодом:

  1. Не выделяется память для буфера ввода
  2. Не передает буфер в scanf
  3. Не использовать strcmp для сравнения строк
3 голосов
/ 15 мая 2011

cmdline - это просто указатель - вам нужно выделить для него место, используя malloc или массив фиксированного размера.

3 голосов
/ 15 мая 2011

Вы определили char *cmdline, но не присвоили указатель cmdline

сделать

cmdline = malloc (sizeof (char) * n);

первый

Отрегулируйте длину строки n в соответствии с вашими потребностями.

EDIT1: В вашей версии, когда вы используете cmdline без выделения, тогда на самом деле cmdline содержит значение, которое может быть любым, и использование этого для доступа к памяти является попыткой получить доступ к некоторой области памяти, которую вы не знаете, где и которая не разрешена. в ОС с защитой памяти (все ОС в настоящее время). Поэтому, когда вы сохраняете что-то в cmdline, оно будет находиться в недопустимом месте, что недопустимо, и ОС выдаст ошибку сегментации для несанкционированного доступа к памяти.

После того как вы выделите память из ОС (куча) с помощью вызова malloc, cmdline будет содержать значение, которое будет иметь адрес ячейки памяти, который был выдан ОС для вашего кода и зарезервирован для вас. , в котором у вас есть разрешение на запись. Так что ссылка на местоположение с помощью переменной дает правильную ссылку на память, и вы можете сделать это как обычно. Также обратите внимание, что если вы попытаетесь выйти за пределы выделенного блока памяти, т. Е. Получить доступ за n -ым местоположением (если вы выделили n байт), то вы также можете получить segfault, поскольку места памяти за этим пределом не зарегистрирован / выделен для вас. Несмотря на то, что в этом случае вы можете не получить сигфо, но запись в таком месте может быть непредсказуемой.

Единственная причина попытки прояснить это состоит в том, что это очень распространенная халатность для определения char * и без выделения его используйте его в кодах, потому что старый Turbo C ++ 3.1 не жалуется, который используется Множество людей там. Затем они звонят мне и говорят, что компилятор GCC не работает, так как код в нем не работает и прекрасно работает в TC ++ 3.1.

EDIT2: Или просто используйте статический массив

char cmdline[MAX_SIZE];

где MAX_SIZE установлено в соответствии с вашими потребностями

РЕДАКТИРОВАТЬ3: OMG

Вы сделали cmdline != "quit", это никогда не сработает. Решение

while (strcmp (cmdline, "quit") != 0);

в вашем коде. Это будет совпадать cmdline строка за символом со статической строкой "quit"

Ваше решение никогда не будет работать, потому что когда вы делаете cmdline != "quit", тогда сравниваются просто два адреса. Во-первых, cmdline представляет адрес, который вы выделили при вызове malloc, Во-вторых, адрес строки «quit», которая находится внутри раздела данных исполняемого файла, или просто в некоторой области памяти, где находится ваша программа. загружен, о котором вы понятия не имеете. Сравнение этих двух значений не будет сравнивать содержимое этих адресов, т.е. не будет сравнивать строки внутри него.

EDIT4: Также scanf ("%s", &cmdline); является неправильным, так как cmdline сам по себе представляет адрес места, где вы хотите сохранить строку. Правильный код:

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

int main (void)
{
  char *cmdline;
  cmdline = malloc (sizeof (char) * 128);       /* or whatever size */
  do
    {
      scanf ("%s", cmdline);
      printf ("%s\n", cmdline);
    }
  while (strcmp (cmdline, "quit") != 0);
  return 0;
}
...