2014-12-14 4 views
-2
#include<stdio.h> 
#include<conio.h> 
int main() 
{ 
char test [7]; 
for(int i=0;i<10;i++) 
scanf("%c",&test[i]); 
puts(test); 
getch(); 
return 0; 
} 

Я использую DevC++ (университетские правила), и я знаю, что gets() не имеет проверки границ, поэтому я намеренно использовал цикл() для ввода строки. Когда я вхожу в строку, большую размера массива, puts печатает дополнительный символ. Почему так ??Почему puts() печатает дополнительный символ в конце?

Пример ввода: HelloWorld Выход: hellowos

Пример ввода: Hellopeople Выход: Hellopep

+0

Не существует 'gets', пожалуйста, забудьте, что эта функция когда-либо существовала. OTOH 'fgets' жив и здоров, и вы должны использовать его вместо своего рукописного цикла, который в принципе мог бы работать, если бы вы не закончили свою строку символом NUL. Также, что с намеренным переполнением 7-символьного длинного буфера с количеством символов до 10 символов? –

+1

UB multi-dupe. Не перебегайте границы массива и обратите внимание, что SO доступен для поиска. –

+0

@ н.м. Преднамеренное переполнение было просто для проверки поведения puts в случае переполнения. Можете ли вы объяснить мне, почему puts() печатает более 8 символов, когда он должен был печатать только 7. И почему печатный символ немедленно. –

ответ

2

Это потому, что вы переполнены памяти. Ваш массив только достаточно для семи символов, и вы пытаетесь заполнить его с десяти:

char test [7];    // Array indexes 0-6 allowed. 
for(int i=0;i<10;i++)  // Array indexes 0-9 used. 
    scanf("%c",&test[i]); 

Вы можете это исправить (в том числе позволяя струнный терминатора) что-то вроде:

char test [11];   // Array indexes 0-10 allowed. 
for(int i=0;i<10;i++)  // Array indexes 0-9 used. 
    scanf("%c",&test[i]); 
test[10] = '\0';   // And add string terminator before puts(). 

Если вы хотите упрощенная функция ввода пользователя с защитой переполнения буфера, что-то построенное от fgets(), как правило, является лучшим способом в стандарте C. Что-то вроде this, например.

0

ваш массив test имеет всего 7 символов, в то время как вы читаете 10 символов в нем через петлю for. Это может привести к сбою.

Также puts ожидает, что ваша строка будет 0-кратной. Вы явно не ставите 0 после ваших символов, поэтому на выходе будет содержаться всякий мусор после ваших символов, вплоть до первого 0-байтового.

1

У вас есть buffer overflow, как вы пытаетесь сохранить 10 символов в буфер, который может в-основном магазине 7 элементов

char test [7]; 
for(int i=0;i<10;i++) 
    scanf("%c",&test[i]); 

Вы можете исправить это, сделав элементы буфера 10 (так что он может хранить 9 символы плюс один для \0 в конце), и с помощью этого:

char test [10]; //10 elements long 
scanf("%9s",test); //Get at-most 9 chars 

или вы можете использовать fgets тоже.

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