我正在尝试读取C中的一些用户输入(因此接收用户的名字和姓氏,出发和到达位置)但我收到此错误,我所做的声明类型不一致。我对C有点新,所以请耐心等待,因为这可能是一件微不足道的事情。为什么会出错?
#include <stdio.h>
int main (void) {
char lastName, firstName, depart, arrive;
printf("Please enter passenger's last name: ");
scanf("%s", &lastName);
printf("Please enter passenger's first name: ");
scanf("%s", &firstName);
printf("Which airport are you departing from? ");
scanf("%s", &depart);
printf("Which airport will you be heading to? ");
scanf("%s", &arrive);
printf("LAST NAME: %s FIRST NAME: %s FROM: %s TO: %s", lastName,
firstName, depart, arrive);
return 0;
}
答案 0 :(得分:2)
%s
格式说明符需要目标缓冲区中第一个字符的地址。该缓冲区将填充下一个字。您传递了char
的地址,但该字符没有足够的空间来存储整个字符串!编写更正确的代码的一种方法是:
char buf[32];
scanf("%s", buf);
buf
衰减成指向其第一个元素的指针,以便buf
可以填充下一个单词。
但是,建议不要使用scanf
。更好的方法是使用fgets
。
char *fgets(char *s, int size, FILE *stream);
它从size-1
读取下一行(不超过stream
个字符)到s
指向的缓冲区。超出size
的任何字符都不会添加。如果有空格,它包括字符串中的换行符。这个函数是优越的,因为它可以避免缓冲区溢出,也可以读取整行 - 而不仅仅是下一个单词。
char buf[80];
fgets(buf, sizeof buf, stdin);
这是您应该用来阅读文本的内容。您的程序可以重写为:
#define MAXLNAME 80
#define MAXFNAME 80
#define MAXAIRPORT 3
int main()
{
char lname[MAXLNAME + 1], fname[MAXFNAME + 1],
srcAirport[MAXAIRPORT + 1], destAirport[MAXAIRPORT + 1];
printf("Last name\n");
fgets(lname, sizeof lname, stdin);
printf("First name\n");
fgets(fname, sizeof fname, stdin);
printf("Source airport\n");
fgets(srcAirport, sizeof srcAirport, stdin);
printf("Destination airport\n");
fgets(destAirport, sizeof destAirport, stdin);
return 0;
}
然而,fgets有问题。它将尾随换行符存储在目标缓冲区中。我们可以很容易地解决这个问题。
/* remnl: Overwrite trailing newline from fgets with zero-terminator */
void remnl(char *buf)
{
size_t n = strlen(buf);
if (n > 0 && buf[n - 1] == '\n')
buf[n - 1] = '\0';
}
然后,在打印缓冲区之前,您可以在每个缓冲区上调用remnl
remnl(lname);
remnl(fname);
remnl(srcAirport);
remnl(destAirport);
答案 1 :(得分:1)
正如其他人在评论中指出的那样,你没有为你的字符串分配足够的空格。这是一个可能的解决方案:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
char *lastName, *firstName, *depart, *arrive;
printf("Please enter passenger's last name: ");
scanf("%ms", &lastName);
printf("Please enter passenger's first name: ");
scanf("%ms", &firstName);
printf("Which airport are you departing from? ");
scanf("%ms", &depart);
printf("Which airport will you be heading to? ");
scanf("%ms", &arrive);
printf("LAST NAME: %s FIRST NAME: %s FROM: %s TO: %s\n", lastName,
firstName, depart, arrive);
free(lastName);
free(firstName);
free(depart);
free(arrive);
return 0;
}
如果您使用m
修饰符作为%s
的长度修饰符,那么scanf
将为您的输入分配必要的空间,您可能事先不知道它的长度,以及你需要自己释放这些空间。顺便说一下,这个功能是POSIX的一部分,但还没有C标准。
有关m
修饰符的详细说明,请参阅scanf(3)。