2014-01-27 2 views
1

Я написал следующий код в программировании на языке C (используя Turbo C++).Неожиданное поведение структуры в C

#include<stdio.h> 

struct test 
{ 
    char fname[10]; 
    char age[2]; 
    char lname[10]; 
}s1[10]; 

int main() 
{ 
    int i; 
    for(i=0;i<3;i++) 
    { 
    printf("enter the first name : "); 
    scanf("%s",s1[i].fname); 
    printf("enter the last name : "); 
    scanf("%s",s1[i].lname); 
    printf("enter the age : "); 
    scanf("%s",s1[i].age); 
    } 
    for(i=0;i<3;i++) 
    { 
    printf("\n %s %s age= %s",s1[i].fname,s1[i].lname,s1[i].age); 
    } 
getch(); 
return 0; 
} 

Я ввел входы, как и требовалось. Но последнее имя (lname) было обнаружено отсутствующим при печати результата.

Можете ли вы помочь мне решить это неожиданное поведение структуры. (Пожалуйста, безнадзорности значение [10], возраст объявлен как строка и т.д., как я сделал это для моей цели)

Пожалуйста, обратите внимание: когда я объявил возраст как «int» и используется %d отображалось ФАМИЛИЯ, но когда все были объявлены персонажем, он не работает.

+0

надежду, что вы код не написано на самом деле именно так ... Нет отступов :( – DonCallisto

+0

@DonCallisto рассматривать вышеуказанную программу для ввода имени 3-х человек (первое имя, фамилию) и их возраст. – MELWIN

+0

это хороший образец интервью :) – UmNyobe

ответ

3

char age[2]; слишком маленький. Если вы вводите ровно 2 символа, scanf будет записывать строку окончания в lname[0], потому что в этом конкретном случае память между обоими массивами смежна.

Таким образом printf будет видеть пустой массив и результат будет один вы наблюдаете

+0

:) спасибо. Я изменил возраст [2] до возраста [3]. – MELWIN

+0

Лучше использовать большее количество, например 8, для обеспечения безопасности. Вы по-прежнему сталкиваетесь с этой проблемой для вредоносного ввода. Если вам нужен надежный код, добавьте поля между буферами для обнаружения переполнения. – UmNyobe

+1

@UmNyobe Имейте в виду, что в любом случае следует избегать 'scanf'. Он не имеет понятия о размере буфера, который он может использовать. Вместо этого используйте 'fgets'. Большее число не является безопасным. Это сложнее получить ошибку, когда вы вводите длинную строку и нажмите^H^H ... после этого. – harper

1

Изменение

char age[2]; 

к

char age[4]; 

Строки необходимо дополнительное пространство для завершающего нулевого символа.

+1

спасибо. Я изменился до возраста [3] Никто, кого я знаю, не старше 100 :) спасибо – MELWIN

+0

У меня есть ответ на ур. принимая вышеуказанное, когда он ответил 1-го, Thaank u – MELWIN

1

Проблема в том, что у вас есть переполнение буфера на scanf.

Как исправить:

Решение является не только увеличить размер буфера. Решение состоит в том, чтобы полностью предотвратить переполнение.

Увеличение буферные размеры:

char age[3+1]; /* 3 for digits, +1 for NUL char */ 

Укажите максимальные символы следующим образом:

scanf("%3s", s1[i].age); 

Но так как вы читаете только строки, я бы рекомендовал использовать fgets вместо:

fgets(s1[i].age, 4, stdin); 

Do это для всех полей. И еще лучше: используйте константы для размеров буфера.

0

новый символ линии будет вставлен как второй вход для scanf(); то есть: ваш вход для s1 и s2 являются: test1 test2 то s1 = "test1" и s2 = "\ п" функция

поэтому в вашем случае вы должны использовать получает() вместо зсапЕ(). и ваш размер строки будет состоять из числа символов, которые вы хотите ввести плюс 1, потому что каждая строка добавит в конец дополнительный завершающий символ ('\ 0'). i.e: если вы хотите ввести 5 символов в char s1 [SIZE]; то РАЗМЕР должен быть 6. следуйте этим инструкциям. надеюсь, что это поможет решить эту проблему.или вы можете запустить:

#include<stdio.h> 

struct test 
{ 
    char fname[10]; 
    char age[3]; // for maximum 2 digits 
    char lname[10]; 
} s1[10]; 

int main() 
{ 
    int i; 
    for(i=0; i<3; i++) 
    { 
     printf("enter the first name : "); 
     gets(s1[i].fname); 
     printf("enter the last name : "); 
     gets(s1[i].lname); 
     printf("enter the age : "); 
     gets(s1[i].age); 
    } 
    for(i=0; i<3; i++) 
    { 
     printf("\n %s %s age= %s",s1[i].fname,s1[i].lname,s1[i].age); 
    } 
    getch(); 
    return 0; 
} 
+0

с использованием gets() не очень хорошо. говорит эксперт – MELWIN

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