Почему этот причудливый вывод в c? - PullRequest
1 голос
/ 20 сентября 2011

У меня есть следующая программа

#include <stdio.h>

main()
{

    char ch[10];

    gets(ch);

    printf("\nTyped: %s\n\n", ch);

    int i = 0;
    while ( ch[i] != '\0' )
    {
        printf("Letter: %c\n", ch[i]);
        i++;
    }

    printf("\nTyped: %s\n\n", ch);


}

и вот вывод, когда я набрал "Hello world is good"

hello world is good

Typed: hello world is good

Letter: h
Letter: e
Letter: l
Letter: l
Letter: o
Letter:
Letter: w
Letter: o
Letter: r
Letter: l
Letter:


Typed: hello worl♂

Почему я получаю два разных вывода для одной и той же команды после цикла while? делает цикл while как-то связано с этим .. пожалуйста, помогите ..

Ответы [ 3 ]

8 голосов
/ 20 сентября 2011

Вы знаете, что "Hello world is good" больше 10 байтов?Поведение в этом случае undefined .Может произойти что угодно, что угодно, от работы, которую вы хотели , до полного сбоя вашей системы с переформатированием жесткого диска и записью ненужных файлов в ПЗУ.

Вы должны выделить достаточно места дляgets, чтобы вставить строку, и в этом случае вы не делаете.Это основная причина, по которой следует избегать gets, используйте fgets.

5 голосов
/ 20 сентября 2011

Ваш массив символов ch имеет место только для 10 символов. Вы набрали что-то длиннее 10 символов и попытались сохранить его в этом массиве, фактически записав за пределы массива пространство, которое ни для чего не зарезервировано (или, по крайней мере, не зарезервировано для ваших символов). В этом случае вам повезло, и вы не переписали ничего важного (ваша программа не аварийно завершилась), но появляется следующий код (printf(), ваш int i и т. Д.) И изменяет эту память (это стек) В конце концов, так оно и используется в порядке FIFO).

Измените char ch[10] на char ch[2048], чтобы увеличить размер буфера для ввода. Вы также можете использовать fgets() вместо gets(), чтобы ограничить размер входных данных размером буфера. Если вы используете gets(), обратите внимание на предупреждение на странице руководства:

Вызывающая сторона должна убедиться, что строка ввода, если любой, достаточно короткий, чтобы поместиться в строку.

2 голосов
/ 20 сентября 2011

Ну, вы выделяете только 10 символов (char ch[10]), что соответствует "hello worl". После этого в памяти остается только мусор, который вы пытаетесь распечатать.

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