在xCode错误中读取C语言

时间:2016-09-18 14:28:45

标签: c

我正在尝试读取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;
}

2 个答案:

答案 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)