2016-08-24 2 views
-5
char string = "default"; 
printf("The default String is: %s", &string); 
scanf("%s", &string); 
printf("You entered: %s", &string); 

Первый вывод printf выдает & строку как X(?_?. Второй printf после инструкции scanf выводит строку, введенную мной.Почему оператор & используется после использования scanf?

Поскольку оператор & var означает «адрес памяти для var», то почему & строка распечатывает введенную строку? Почему возникает ошибка сегментации, когда я пытаюсь использовать только «строку»?

+7

Ваш код абсолютно пронизана * непредсказуемое поведение *: это работает случайно. Хороший ответ будет довольно длинным. Подождем. – Bathsheba

+4

Строка с очень сильной строкой недействительна C. Из-за этого трудно рассуждать о последующих строках. –

+4

Голосование, чтобы закрыть, так как внимание к предупреждениям компилятора полностью устранило необходимость этого вопроса. –

ответ

3

Вы объявили string как отдельный символ, но заполните его строкой. Это вызывает неопределенное поведение. Вы должны изменить свой код:

char string [20] = "default"; //20 is random, you should use the maximum length of the input you may have 
printf("The default String is: %19s", string); 
scanf("%s", string); 
printf("You entered: %s", string); 

В общем, scanf нужно взять адреса памяти в качестве аргумента, и в приведенном выше коде, string является адресом памяти. Вы можете узнать больше о scanf в this link.

+0

'char * string =" default ";' будет вернее. Назначение изменяет указатель, а выделенные 20 символов становятся недоступными. Однако программа работает в обоих случаях. – AhmadWabbi

+3

@AhmadWabbi Вы пробовали? –

+1

Ваш синтаксис для объявления массива символов неверен. Вы также должны использовать формат ''% 19s'' для 'scanf', чтобы не выходить за пределы массива. –

0

Это было бы решение:

char string[20]; 
strcpy(string, "default"); 
printf("The default String is: %s", string); 
scanf("%19s", string); 
printf("You entered: %s", string); 
+1

'strcpy (строка," default ");' не требуется; 'char string [20] =" default ";' будет работать так же хорошо. – user694733

+0

@ user694733 Нет. Пожалуйста, прочитайте мои комментарии с Marievi – AhmadWabbi

+1

Я видел ваш комментарий. Это неверно. 'char string [20]' - это массив, а '=" default "' для него является допустимым инициализатором. N1570 6.7.9 p14: * «Массив типа символа может быть инициализирован литералом строковой буквы или строкой UTF -8 литералом, необязательно заключенным в фигурные скобки. Последовательные байты строкового литерала (включая завершающий нулевой символ 10, если есть или если массив неизвестного размера) инициализируют элементы массива . "* – user694733

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

char chomp(char* s, char c){ 
    size_t l = strlen(s); 
    if (!l) return 0; 
    return s[l-1] = s[l-1]==c ? '\0' : s[l-1]; 
} 

int main(){ 
    char string[] = "default"; /* sizeof(string) == strlen("default")+1 */ 
    printf("The default String is: %s\n", string); 
    //^ you want the array to decay to a char* here 
    /*scanf("%s", &string); -- DANGEROUS 
    -- scanf doesn't know how much space you have in string*/ 

    fgets(string /*decay again*/, sizeof(string), stdin); 
    /* fgets does know because you've told it with sizeof(string)*/ 

    chomp(string, '\n'); 
    printf("You entered: %s", string); 
    return 0; 
} 
+0

Хотя редко, после 'fgets()', 'string [0]' может быть 0 и 'l = strlen (s); s [l-1] 'является проблемой. Оборонительное кодирование гарантирует первый символ после того, как 'fgets()' не был введен пользователем нулевым символом. – chux

+0

@chux Спасибо! – PSkocik

Смежные вопросы