2011-08-31 4 views
0

이것은 숙제 문제입니다. 내 컴파일러는 CodeBlocks입니다. 여기 for 루프에서 구조체를 사용하는 데 문제가 있습니다.

내 코드입니다 :

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

struct Address{ 
    char number[5]; 
    char street[30]; 
    char city[30]; 
}; 

struct Employee{ 
    char ID[7]; 
    char name[31]; 
    struct Address *addr; 
}; 

int main(){ 
    int n,i; 
    char temp[7]; 
    printf("Enter number of Employee : "); 
    scanf("%d",&n); 
    struct Employee **p=(struct Employee **)malloc(n*sizeof(struct Employee *)); 

    for (i=0; i<n; i++) 
    { 
     p[i]=(struct Employee *)malloc(sizeof(struct Employee)); 
     p[i]->addr=(struct Address *)malloc(sizeof(struct Address)); 
    } 

    for(i=0; i<n; i++) 
    { 
     printf("Employee #%d\n",i+1); 
     printf("Enter ID : "); 
     gets(p[i]->ID); 
     printf("Enter Name : "); 
     gets(p[i]->name); 
     printf("Enter Home number : "); 
     gets(p[i]->addr->number); 
     printf("Enter Street : "); 
     gets(p[i]->addr->street); 
     printf("Enter City : "); 
     gets(p[i]->addr->city); 
    } 
} 

내 문제는 내가이 코드를 실행하면, 나는 # 1 직원의 ID를 입력 할 수 있다는 것입니다; 그러나 직원 # 2와 # 3의 ID를 입력 할 수 있습니다.

내 문제는 어디에 있습니까?

+2

왜냐하면'scanf'는 줄 바꿈 문자를 남기 때문입니다. 또한'gets'를 사용하지 마십시오. 당신의 코드는 끔찍합니다 (아무런 공격도 없지만, 모든 것 (매우 작습니다!) 체크가없는 고정 된 크기의 버퍼 ...) – user786653

+0

저는 이것을 두번째입니다. ['getline' (http://www.crasseux.com/books/ctutorial/getline.html#getline)에 대해 읽고,'strncpy'를 사용하여 line의 첫 번째'n' 문자를 구조 필드에 복사하십시오. –

+0

또한 'malloc'의 반환을 캐스팅 할 필요가 없습니다. –

답변

1

루프의 첫 번째 패스 전에 콘솔에서 무언가를 읽는 중 gets()에 문제가있는 것 같습니다.

루프를 수정하기 바로 전에 gets(temp);을 추가하면 문제를 해결하는 것처럼 보입니다. 더 좋은 해결책은 gets() 이외의 것을 사용하는 것입니다.

+1

Meh, 우리가 빠른 수정을 위해서라면, 나는 scanf ("% d [\ n]", &n);' – user786653

+0

을 좋아한다.이 코드는 너무 심해서 빠른 해킹을 할 수 없다. :-) 그가 일하면서 전반적인 결과를 평가하는 것은 강사에게 달려 있습니다. –

0

초기 scanf("%d", &n);은 후행 줄 바꿈을 사용하지 않으므로 gets() 호출에 사용할 수 있습니다.

부수적으로, 결코gets()을 사용하십시오. 안전하게 사용할 수 없습니다. 예를 들어, 6 바이트 배열로 읽고 사용자가 10자를 입력하면 버퍼 오버 플로우가 발생합니다. 대신 fgets()을 사용해보십시오 (단, gets()과 달리 버퍼에 '\n' 문자가 남음).

+0

fgets는 두 번째 매개 변수가 작 으면 버퍼에 '\ n'도 남겨 둡니다. – user411313

+0

@ user411313 : "buffer"란, 행을 저장하는 배열을 의미합니다. length 인수가 충분히 크거나 (또는 ​​입력 된 줄이 충분히 짧으면) 문자열의 끝에 "\ n"이 있습니다. 그렇지 않으면''\ n ''을 포함하지 않는 부분 행 만 읽히고, 다음 입력 조작을 위해 사용 가능하게됩니다. 매우 긴 입력 라인이있는 상태에서 100 % 견고성을 유지하려면 약간의 추가 작업이 필요하지만 이와 같은 간단한 연습을 위해서는 대상 배열을 충분히 크게 만들고 문제를 무시하는 것이 좋습니다. (확실히'gets()'보다 낫다.) –

0

사용자가 입력 한 후 입력 버퍼를 명시 적으로 지워야합니다. 크기 제한기로 입력 내용을 안전하게 만들어야합니다. 그리고 scanf의 반환 값을 사용해야합니다.

scanf("%d",&n);while(getchar()!='\n'); 
... 
scanf("%6[^\n]",p[i]->ID);while(getchar()!='\n'); 
... 
scanf("%30[^\n]",p[i]->name);while(getchar()!='\n'); 
... 
scanf("%4[^\n]",p[i]->addr->number);while(getchar()!='\n'); 
... 
scanf("%29[^\n]",p[i]->addr->street);while(getchar()!='\n'); 
... 
scanf("%29[^\n]",p[i]->addr->city);while(getchar()!='\n'); 
관련 문제