Scanf () работает, когда я объявляю строку как char string [], но не когда я объявляю ее как char * [duplicate]

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

int  main()

{
char t1string[20];
scanf("%s", t1string);
printf("%s\n", t1string);
printf("%c\n", t1string[4]);

char * t2string;
scanf("%s", t2string);
printf("%s\n", t2string);
printf("%c", t2string[4]);
}

Почему scanf () не работает во втором случае (где строка объявлена как char *)?

# scanf
Источник
  • 1
    Это не строка char * t2string;
  • 2
    Отвечает ли это на ваш вопрос? В чем разница между указателем и строками?
  • 0
    Заменить char *t2string; либо с char *t2string = malloc(20); или char *t2string = t1string; . Прочтите, чтобы понять, что делает каждый из них.
  • 0
    "где строка объявлена как char *" -> char * - указатель. Строка не указатель. Массив символов может содержать строку .
Codelisting
за 5 против

Потому что перед вызовом функции scanf соответствующее пространство не выделяется для't2string, то есть указатель t2string не указывает на определенный адрес

 t2string = (char*)malloc(20 * sizeof(char));
 // or
 char t1string[20];
 t2string = t1string;
  • 0
    Хорошее понимание, но что, если я сделаю это: char * t2string = "testagain"; scanf ("% s", t2string); printf ("% s \ n", t2string); printf ("% c", t2string [5]); } Я бы подумал, что первое объявление и присвоение "testagain" t2string предварительно выделит память, но scanf () по-прежнему не работает. Мне все еще нужно немного больше объяснений.
  • 0
    "testagain" - это константная строка. Вы можете изменить этот указатель, но не можете изменить константу, на которую указывает этот указатель.
  • 0
    Я пробовал, он может работать в msvc 2019, а в gcc 8.3 - нет. Я тоже немного запутался.
за 2 против

Потому чтоchar[] а такжеchar* разные.

Массив символов илиchar[] - это блок данных, выделенный компилятором в стеке. Память выделяется при инициализации и выполняется компилятором автоматически. Его положение или размер нельзя изменить после выделения, так как он управляется компиляторами.

Так

scanf("%s", t1string);

работает так, как компилятор дает ему место для выделения.

С другой стороны,char* это всего лишь одна переменная, которая используется для хранения адреса памяти в другом блоке. Все, что он делает, это инициализирует память для хранения адреса. Фактический блок памяти необходимо инициализировать вручную. Из-за этого он может быть изменен, освобожден и повторно использован пользователем. Компилятор не управляет этими воспоминаниями.

Так,

scanf("%s", t2string);

не работает, поскольку вы не выделили ему память. Вы должны выделить блок памяти с помощью malloc (), calloc () и т. Д.

  • 0
    Хорошее понимание, но что, если я сделаю это: char * t2string = "testagain"; scanf ("% s", t2string); printf ("% s \ n", t2string); printf ("% c", t2string [5]); } Я бы подумал, что первое объявление и присвоение "testagain" t2string предварительно выделит память, но scanf () по-прежнему не работает. Мне все еще нужно немного больше объяснений. - blessedk 2 часа назад
  • 0
    "testagain" выделит память и printf будет работать. Но scanf() не работает, потому что память, выделенная для постоянных строк, доступна только для чтения.
за 0 против

char * и char [] сохраняет реальную строку (а не просто получить адрес литерала)

это означает, что вы можете изменить его значение, например

char[i] = 'a';

Итак, вы должны выделить место для '% s'

Более того, вы можете увидеть, в чем разница между String a = '...' и char [] a = '...';

char [] a = 'abc' будет изменен на char [] a = {'a', 'b', 'c'} во время компиляции (изменяемый)

Codelisting
Популярные категории
На заметку программисту