【问题标题】:Scanf and pointers misunderstandingscanf和指针的误区
【发布时间】:2018-06-20 14:40:13
【问题描述】:

看看这个:

char* s;
scanf("%s", s);

一般来说,s 是一个“内存盒”,其中包含指向另一个地址的地址,在这种情况下,它将是许多“内存盒”中的第一个,其中包含标记结束的“\0”之前的字符字符串。
*s 可以让我们访问“内存盒”,即字符串。

现在回到代码,准确地说是 scanf,我是这样读的:获取用户输入,这是一个字符串,因此是“%s”,并将其分配给 s。但这怎么可能呢? s 是参考,所以不应该是scanf("%s", *s) 吗?

【问题讨论】:

  • documentation for scanf 清楚地说明了应该为哪种格式说明符传递哪些类型。同样*s 会返回一个单数char,而不是一个字符串。
  • char * s 不会创建“内存盒”。我想你的意思是像char * s = malloc(80); 这样的东西创建了一个能够容纳 80 个字节的“内存盒”,以后必须释放它。
  • 最好使用“指针”这个短语。这是一个技术词,描述了它的作用。它不是事物本身,它指向事物。您应该寻找一些 scanf() 的示例。您在撰写本文时的示例不正确。您需要一些内存来存放字符串。该字符串是许多“char”。您需要一个指向该内存的指针。指针只能指向第一个。然后将指针传递给scanf(),它将查找字符串并将其放入指针指向的内存中。
  • @archaic 将许多字符读入一个小缓冲区是缓冲区溢出。缓冲区溢出会导致未定义的行为。未定义的行为正是如此。

标签: c pointers scanf


【解决方案1】:

让我们举一个更简单的例子:

char c;
scanf("%c", &c);

在这个例子中,如果你想读取一个字符,那么你必须传递那个字符的地址(c),这样方法就知道把结果字符放在哪里。

让我们展开成一个字符串:

char *str;
scanf("%s", str);

在这种情况下 str 是字符串开头的地址,因此您可以将其传递给 scanf 并期望读取该字符串。

但是,这里有一个问题:str 指向字符串的开头,但该字符串实际上并不存在,您必须创建它。像这样:

char str[80];
scanf("%s", &str[0]);

正如您在此处看到的,str 现在是一个 80 个字符的字符串,您可以将这个字符串开头的位置(地址)传递给 scanf。但是,您必须祈祷读取的字符串不大于 80 个字符,否则该方法将尝试在字符串范围之外写入。您可以通过告诉 scanf 要读取多少个字符来纠正此问题:

char str[80];
scanf("%79s", &str[0]);

【讨论】:

  • 谢谢,一开始我以为scanf中的参数不是“想读”变量的地址,而是变量本身。
  • 最后一个例子应该是这样做的,我现在更新了它
  • @archaic C 是按值传递的。你不能以任何方式将“变量本身”传递给任何函数,你得到的只是变量值的副本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-09
  • 2019-03-11
  • 1970-01-01
  • 2011-09-22
  • 1970-01-01
  • 1970-01-01
  • 2016-11-03
相关资源
最近更新 更多