Путать с массивом символов при сканировании - PullRequest
4 голосов
/ 02 сентября 2011

Я запутался с одной крошечной программой.

#include <stdio.h>

#define LEN 10

int main()
{
    char str1[LEN] = "\0";
    char str2[LEN] = "\0";

    scanf("%s", str1);
    scanf("%s", str2);

    printf("%s\n", str1);
    printf("%s\n", str2);

    return 0;
}

Если мой ввод:

mangobatao
mangobatao123456

Почемувывод будет:

123456
mangobatao123456

А не:

mangobatao
mangobatao123456

Каким образом массив char был размещен в памяти?

Ответы [ 2 ]

6 голосов
/ 02 сентября 2011

Ну, массив из 10 символов char не будет соответствовать "mangobatao", так как в нем 10 символов - места для нулевого терминатора нет. Это означает, что вы вызвали неопределенное поведение, поэтому может произойти все, что угодно.

В этом случае выглядит, как будто ваш компилятор выложил str2 перед str1 в памяти, поэтому, когда вы вызываете scanf для заполнения str2, более длинная строка перезаписывает начало str1. Вот почему вы видите конец того, что, по вашему мнению, должно быть в str2 при попытке напечатать str1. Ваш пример будет работать нормально, если вы используете длину 100.

0 голосов
/ 16 сентября 2013

Я думаю, ваш компилятор выделил место для str2 [10] всего за 10 символов до указателя str1.

Теперь, когда вы сканируете строку длиной 16 в строке str2, терминатор строки «\ 0» добавляется в позиции str2 + 17, что фактически означает str1 + 7.

Теперь, когда вы вызываете printf в str1, считанные символы на самом деле являются str2 + 11, str2 + 12, ..., str2 + 16, пока не встретится нулевой терминатор в str2 + 17 (или str1 + 7). Printf на str2 должен быть очевидным.

...