scanf仅读取第一个字段

时间:2018-11-19 15:34:14

标签: c scanf stdio

我想用scanf读入两个字符串并将它们存储在两个变量中。似乎只有第一个可以正确读取,而第二个只返回(null),但我不确定为什么。

int main(int argc, char **argv) {
  char *c, *p;

  printf("Enter a command with a parameter: ");
  scanf("%s%s", c, p);
  ...
}

有人知道,这是怎么回事?我没有发现任何错误,据我所知它应该可以工作。

3 个答案:

答案 0 :(得分:6)

char *c, *p;

这些只是指针,后面没有任何内存。而且,它们是未初始化的,因此读取或分配它们的值或读取或分配它们指向的内存将是未定义的行为,并且会产生nasal demons

为了读取用户的输入,您需要一个地方来保存内存。

char c[20], p[20];

将为c分配20个字符,为p分配20个字符。 cp不是指针,而是数组char[20]。但是,在大多数情况下,数组处理程序都会“衰减”(读取:神奇地改变)为指针。

scanf for "%s" scanf修饰符期望一个指向char char*的指针,该指针具有足够的内存来容纳输入的字符串。

我会做的:

int main(int argc, char **argv) {
  char c[20], p[20];

  printf("Enter a command with a parameter: ");
  scanf("%19s%19s", c, p);
}

19中的%19s限制了scanf,因此它不会将输入读入超出c和/或{{1} }指针,这也会导致未定义的行为。

答案 1 :(得分:4)

这是未定义的行为。您尚未初始化指针。您的编译器应将此告诉您。

CreatePathWithQueryStrings(...)

您需要做的是初始化指针。使用malloc是一种实现方法。

k.c:8:17: warning: variable 'c' is uninitialized when used here [-Wuninitialized]
  scanf("%s%s", c, p);

您希望避免以ALL COST的方式进行未定义的行为,因为这意味着该行为可以是任何事情,包括以所需方式工作。它会使调试成为噩梦。

但是正如Swordfish在评论中提到的那样,如果不指定字符串的最大长度就这样做是很自杀的,因为您无法控制是否要越过缓冲区,这也是未定义的行为。

答案 2 :(得分:0)

您还可以使用%ms代替%s,因为它本身分配内存,并且不需要程序员手动分配内存。

int main(int argc, char **argv) {
  char *c, *p;

  printf("Enter a command with a parameter: ");
  scanf("%ms%ms", &c, &p); //no need of allocating memory manually
  ... 
}