user-0 提问: PAT1028人口普查，求大佬看看BUG

回复:
user: user-1
content: 引用 5 楼 Martin Morning 的回复:[quote=引用 4 楼 自信男孩的回复:]#include <stdio.h> #include <stdlib.h>  typedef struct man {     //char name[1000];     char name[64];     int y;     int m;     int d; }M; int main() {     int n,y,m,d;     int num=0;     //M p[100000];     M *p;     M old, young;     int i=0;     scanf("%d",&n);     p = (M *)malloc(sizeof(M));     if (!p)         exit(0);      //getchar();     for(;i<n;i++)     {         //gets(p[i].name);         scanf("%s", p[i].name);         scanf("%d/%d/%d", &p[i].y, &p[i].m, &p[i].d);         //printf("%d/%d/%d\n", p[i].y, p[i].m, p[i].d);         //if(p[i].y >2014 || p[i].y==2014 && p[i].m>9 ||p[i].y==2014&&p[i].m==9&&p[i].d>6 ||p[i].y<1814 ||p[i]. y==1814&&p[i].m<9 || p[i].y==1814&&p[i].m==9&& p[i].d<6)         if (p[i].y > 2014)             continue;         if (p[i].y == 2014 && p[i].m > 9)             continue;         if (p[i].y == 2014 && p[i].m == 9 && p[i].d > 6)             continue;          if (p[i].y < 1814)             continue;         if (p[i].y == 1814 && p[i].m < 9)             continue;         if (p[i].y == 1814 && p[i].m == 9 && p[i].d < 6)             continue;         //printf("i = %d\n", i);         //printf("%d/%d/%d\n", p[i].y, p[i].m, p[i].d);         //if(p[i].y >=2014 || p[i].y==2014 && p[i].m>9 ||p[i].y==2014&&p[i].m==9&&p[i].d>6 ||p[i].y<1814 ||p[i]. y==1814&&p[i].m<9 || p[i].y==1814&&p[i].m==9&& p[i].d<6)         //   continue;         //else         //{         num++;         if(i==0)         {             old = p[i];             young = p[i];         }         else         {             //if((p[i].y > young.y) || (p[i].y==young.y && p[i].m>young.m)              //       || (p[i].y==young.y && p[i].m == young.m && p[i].d>young.d))             if((p[i].y > young.y) || (p[i].y==young.y && p[i].m > young.m)                     || (p[i].y==young.y && p[i].m == young.m && p[i].d > young.d))                 young = p[i];             //if( (p[i].y < old.y) || p[i].y==old.y&&p[i].m<old.m  ||  p[i].y==old.y&&p[i].m==old.m&&p[i].d<old.d)             if( (p[i].y < old.y) || (p[i].y==old.y&&p[i].m < old.m)                 ||  (p[i].y==old.y&&p[i].m==old.m&&p[i].d  < old.d))                 old = p[i];          }          //}      }     printf("%d %s %s\n", num,old.name,young.name);     return 0; }  供参考～ 感谢大佬的回复，看见你很多次了。你改的代码除了name 和*p我能理解外，其他的好像和我的一样呀。是否在gets前才用getchar[/quote]  代码除了要实现功能，还要考虑代码的可读性。一行代码太长，不感觉看着不舒服吗？  如果用gets，一方面不安全，当然scanf %s也不安全，另外，gets可能没等你输入任何东西就直接返回了，因为上次输入放在输入缓存里还有一个'\n'，gets遇到它就直接返回了，就是没有任何东西进入name里。

user: user-0
content: 引用 4 楼 自信男孩的回复:#include <stdio.h> #include <stdlib.h>  typedef struct man {     //char name[1000];     char name[64];     int y;     int m;     int d; }M; int main() {     int n,y,m,d;     int num=0;     //M p[100000];     M *p;     M old, young;     int i=0;     scanf("%d",&n);     p = (M *)malloc(sizeof(M));     if (!p)         exit(0);      //getchar();     for(;i<n;i++)     {         //gets(p[i].name);         scanf("%s", p[i].name);         scanf("%d/%d/%d", &p[i].y, &p[i].m, &p[i].d);         //printf("%d/%d/%d\n", p[i].y, p[i].m, p[i].d);         //if(p[i].y >2014 || p[i].y==2014 && p[i].m>9 ||p[i].y==2014&&p[i].m==9&&p[i].d>6 ||p[i].y<1814 ||p[i]. y==1814&&p[i].m<9 || p[i].y==1814&&p[i].m==9&& p[i].d<6)         if (p[i].y > 2014)             continue;         if (p[i].y == 2014 && p[i].m > 9)             continue;         if (p[i].y == 2014 && p[i].m == 9 && p[i].d > 6)             continue;          if (p[i].y < 1814)             continue;         if (p[i].y == 1814 && p[i].m < 9)             continue;         if (p[i].y == 1814 && p[i].m == 9 && p[i].d < 6)             continue;         //printf("i = %d\n", i);         //printf("%d/%d/%d\n", p[i].y, p[i].m, p[i].d);         //if(p[i].y >=2014 || p[i].y==2014 && p[i].m>9 ||p[i].y==2014&&p[i].m==9&&p[i].d>6 ||p[i].y<1814 ||p[i]. y==1814&&p[i].m<9 || p[i].y==1814&&p[i].m==9&& p[i].d<6)         //   continue;         //else         //{         num++;         if(i==0)         {             old = p[i];             young = p[i];         }         else         {             //if((p[i].y > young.y) || (p[i].y==young.y && p[i].m>young.m)              //       || (p[i].y==young.y && p[i].m == young.m && p[i].d>young.d))             if((p[i].y > young.y) || (p[i].y==young.y && p[i].m > young.m)                     || (p[i].y==young.y && p[i].m == young.m && p[i].d > young.d))                 young = p[i];             //if( (p[i].y < old.y) || p[i].y==old.y&&p[i].m<old.m  ||  p[i].y==old.y&&p[i].m==old.m&&p[i].d<old.d)             if( (p[i].y < old.y) || (p[i].y==old.y&&p[i].m < old.m)                 ||  (p[i].y==old.y&&p[i].m==old.m&&p[i].d  < old.d))                 old = p[i];          }          //}      }     printf("%d %s %s\n", num,old.name,young.name);     return 0; }  供参考～ 感谢大佬的回复，看见你很多次了。你改的代码除了name 和*p我能理解外，其他的好像和我的一样呀。是否在gets前才用getchar

user: user-2
content: gets用作读取一行字符，改用scanf，另外，结构体name空间不要太大，逻辑也有错误  scanf("%s %d/%d/%d", &p[i].name, &p[i].y, &p[i].m, &p[i].d);

user: user-1
content: #include <stdio.h> #include <stdlib.h>  typedef struct man {     //char name[1000];     char name[64];     int y;     int m;     int d; }M; int main() {     int n,y,m,d;     int num=0;     //M p[100000];     M *p;     M old, young;     int i=0;     scanf("%d",&n);     p = (M *)malloc(sizeof(M));     if (!p)         exit(0);      //getchar();     for(;i<n;i++)     {         //gets(p[i].name);         scanf("%s", p[i].name);         scanf("%d/%d/%d", &p[i].y, &p[i].m, &p[i].d);         //printf("%d/%d/%d\n", p[i].y, p[i].m, p[i].d);         //if(p[i].y >2014 || p[i].y==2014 && p[i].m>9 ||p[i].y==2014&&p[i].m==9&&p[i].d>6 ||p[i].y<1814 ||p[i]. y==1814&&p[i].m<9 || p[i].y==1814&&p[i].m==9&& p[i].d<6)         if (p[i].y > 2014)             continue;         if (p[i].y == 2014 && p[i].m > 9)             continue;         if (p[i].y == 2014 && p[i].m == 9 && p[i].d > 6)             continue;          if (p[i].y < 1814)             continue;         if (p[i].y == 1814 && p[i].m < 9)             continue;         if (p[i].y == 1814 && p[i].m == 9 && p[i].d < 6)             continue;         //printf("i = %d\n", i);         //printf("%d/%d/%d\n", p[i].y, p[i].m, p[i].d);         //if(p[i].y >=2014 || p[i].y==2014 && p[i].m>9 ||p[i].y==2014&&p[i].m==9&&p[i].d>6 ||p[i].y<1814 ||p[i]. y==1814&&p[i].m<9 || p[i].y==1814&&p[i].m==9&& p[i].d<6)         //   continue;         //else         //{         num++;         if(i==0)         {             old = p[i];             young = p[i];         }         else         {             //if((p[i].y > young.y) || (p[i].y==young.y && p[i].m>young.m)              //       || (p[i].y==young.y && p[i].m == young.m && p[i].d>young.d))             if((p[i].y > young.y) || (p[i].y==young.y && p[i].m > young.m)                     || (p[i].y==young.y && p[i].m == young.m && p[i].d > young.d))                 young = p[i];             //if( (p[i].y < old.y) || p[i].y==old.y&&p[i].m<old.m  ||  p[i].y==old.y&&p[i].m==old.m&&p[i].d<old.d)             if( (p[i].y < old.y) || (p[i].y==old.y&&p[i].m < old.m)                 ||  (p[i].y==old.y&&p[i].m==old.m&&p[i].d  < old.d))                 old = p[i];          }          //}      }     printf("%d %s %s\n", num,old.name,young.name);     return 0; }  供参考～

user: user-1
content: 引用 2 楼 Martin Morning 的回复:[quote=引用 1 楼 user-2的回复:]gets用作读取一行字符，改用scanf，另外，结构体name空间不要太大，逻辑也有错误  scanf("%s %d/%d/%d", &p[i].name, &p[i].y, &p[i].m, &p[i].d);  确实是gets的原因。为什么数组过大也会产生段错误，我一直以为只有数组越界了才会出错[/quote]  因为定义的是局部数组，是在栈上申请空间，栈上的空间是很少的，所以申请很大可能会栈溢出呢，再说你的PC上还有很多程序也是在栈上运行，留给你的程序用的栈空间就更少。

user: user-0
content: 引用 1 楼 user-2的回复:gets用作读取一行字符，改用scanf，另外，结构体name空间不要太大，逻辑也有错误  scanf("%s %d/%d/%d", &p[i].name, &p[i].y, &p[i].m, &p[i].d);  确实是gets的原因。为什么数组过大也会产生段错误，我一直以为只有数组越界了才会出错