gets() 和 scanf() 的问题

问题是:
为什么初始化信息的段落一定要用
gets(num);

p->price = atoi(num);

这样的格式进行输入,而直接用
scanf("%d", &p->price); 就会输入错误呢?
新手真心求教,代码如下:

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

int main()
{
    struct booktype                         //这里定义一个结构体, 
    {                                       //用来记录书的名字和价格 。 
        char name[20];
        int price;
    }a[5];
    struct booktype *p;
    char num[20];

    for (p=a; p<a+5; p++){                  //这段是初始化信息 (问题段!!) 
        printf("输入书的信息:\n");         //如果是: 
        gets(p->name);                      //scanf("%d", &p->price); 则会输入错误, 
        gets(num);                          //原本输入5组数据,结果输入3组就结束了?! 
        p->price = atoi(num);               
    } 

    p=a;                                    //这段是用来找价格最大值, 
    int i;                                  //并输出最大的价格和书的名字。 
    int max_price;
    char max_name[20];
    max_price = p->price;
    strcpy(max_name,p->name);
    for (p=a+1; p<a+5; p++){
        if (p->price>max_price){
            max_price = p->price;
            strcpy(max_name,p->name);
        }
    }

    printf("%d %s", max_price, max_name);

    return 0;

}

多次用scanf, 要配合getchar(); 接收回车,大概就是这个原因吧

  22     for (p=a; p<a+5*24; p+=24){                  //这段是初始化信息 (问题段!!) 
 23         printf("输入书的信息:\n");         //如果是: 
 24         scanf("%s", &p->name);
 25         scanf("%d", &p->price);                     //原本输入5组数据,结果输入3组就结束了?! 
 26     }   
 27     for (p=a+24; p<a+5*24; p+=24){          
 28         //printf("%d", p->price);
 29         if (p->price>max_price){
 30             max_price = p->price;
 31             strcpy(max_name,p->name);
 32         }   
 33     }   

我试了没有问题啊

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

int main()
{
    struct booktype                         //这里定义一个结构体,
    {                                       //用来记录书的名字和价格 。
        char name[20];
        int price;
    }a[5];
    struct booktype *p;
    char num[20];

    for (p=a; p<a+5; p++){                  //这段是初始化信息 (问题段!!)
        printf("输入书的信息:\n");         //如果是:
        gets(p->name);                      //scanf("%d", &p->price); 则会输入错误,
        scanf("%d", &p->price);
//        gets(num);                          //原本输入5组数据,结果输入3组就结束了?!
//        p->price = atoi(num);
    }

    p=a;                                    //这段是用来找价格最大值,
    int i;                                  //并输出最大的价格和书的名字。
    int max_price;
    char max_name[20];
    max_price = p->price;
    strcpy(max_name,p->name);
    for (p=a+1; p<a+5; p++){
        if (p->price>max_price){
            max_price = p->price;
            strcpy(max_name,p->name);
        }
    }

    printf("%d %s", max_price, max_name);

    return 0;

}

用gets和scanf都有字符串超界问题
加两个函数:gainint 和 gainchar 每输入完一项内容就回车

include

define N 20

define MAXprice 100

struct booktype //这里定义一个结构体,
{ //用来记录书的名字和价格 。
char name[N+1];
int price;
} a[5];
int gainchar(char A[],int min,int max);//长度在[min,max] <闭区间> 之间时 函数结束 返回字符串A的长度
int gainint(int *p,int a,int b);//输入int *p直至满足[a,b]输入结束,并返回*p的值
int main()
{
struct booktype *p;
char num[N+1],*Q;
int i; //并输出最大的价格和书的名字。
int max_price;
char max_name[N+1];
for (p=a; p {
printf("输入书的信息:\n"); //如果是:
gainchar(p->name,1,N);
gainint(&p->price,1,MAXprice);
}
p=a; //这段是用来找价格最大值,
max_price = p->price;
Q=p->name;//让Q指向书名
for (p=a+1; p
{
if (p->price>max_price)
{
max_price = p->price;
Q=(p->name);//让Q指向书名
}
}

printf("%d %s", max_price, Q);
return 0;

}
int gainchar(char A[],int min,int max)//长度在[min,max] <闭区间> 之间时 函数结束 返回字符串A的长度
{
int B,C;
do
{
A[max]=B=C=0;
while((A[B++]=getchar())!='\n'&&B if(A[B-1]!='\n')while(getchar()!='\n'&&++C);
else A[--B]=0;
if(C||B&&B printf("您录入的字符串长度:%d字节\n只录入(%d--%d)个字节!\n",B+C,min,max);
}
while(C||B return B;
}
int gainint(int *p,int a,int b)//输入int *p直至满足[a,b]输入结束,并返回*p的值
{
do
{
*p=a-1; //此处是为了减少意外情况的发生 虽然那种意外情况不常见
scanf("%d",p);
while(getchar()!='\n');
if(*p>b||*p printf("输入有误,请重新输入[%d--%d]:",a,b);
}
while(*p>b||*p<a);
return *p;
}


include

define N 20

define MAXprice 100

struct booktype //这里定义一个结构体,
{ //用来记录书的名字和价格 。
char name[N+1];
int price;
} a[5];
int gainchar(char A[],int min,int max);//长度在[min,max] <闭区间> 之间时 函数结束 返回字符串A的长度
int gainint(int *p,int a,int b);//输入int *p直至满足[a,b]输入结束,并返回*p的值
int main()
{
struct booktype *p;
char num[N+1],*Q;
int i; //并输出最大的价格和书的名字。
int max_price;
char max_name[N+1];
for (p=a; p {
printf("输入书的信息:\n"); //如果是:
gainchar(p->name,1,N);
gainint(&p->price,1,MAXprice);
}
p=a; //这段是用来找价格最大值,
max_price = p->price;
Q=p->name;//让Q指向书名
for (p=a+1; p
{
if (p->price>max_price)
{
max_price = p->price;
Q=(p->name);//让Q指向书名
}
}

printf("%d %s", max_price, Q);
return 0;

}
int gainchar(char A[],int min,int max)//长度在[min,max] <闭区间> 之间时 函数结束 返回字符串A的长度
{
int B,C;
do
{
A[max]=B=C=0;
while((A[B++]=getchar())!='\n'&&B if(A[B-1]!='\n')while(getchar()!='\n'&&++C);
else A[--B]=0;
if(C||B&&B printf("您录入的字符串长度:%d字节\n只录入(%d--%d)个字节!\n",B+C,min,max);
}
while(C||B return B;
}
int gainint(int *p,int a,int b)//输入int *p直至满足[a,b]输入结束,并返回*p的值
{
do
{
*p=a-1; //此处是为了减少意外情况的发生 虽然那种意外情况不常见
scanf("%d",p);
while(getchar()!='\n');
if(*p>b||*p printf("输入有误,请重新输入[%d--%d]:",a,b);
}
while(*p>b||*p<a);
return *p;
}