c - 为什么从控制台读取字符串时,scanf 中的 %n 返回 0
问题描述
我试图编写一个程序,该程序从用户(控制台)获取一行,直到遇到逗号、句号或换行符,并告诉按照特定模式读取了多少个字符。
字符串被正确读取,但计数不准确。
#include <stdio.h>
int main()
{
int n;
char s[100];
// The following line should read a string until (. or , or new-line in encountered)
// and %n should tell me the no of characters it read until that point
scanf("%[^.,\n]s%n", s, &n);
// The String in okay
printf("%s\n", s);
// But count of characters read is 0
printf("%d\n",n);
return 0;
}
解决方案
5个问题:
"s"
in停止扫描,"%[^.,\n]s%n"
因为之后无法's'
读取%[^.,\n]
。 %[^.,\n]
会读完所有的's'
。因此,后者"%n"
从未发生过n
,而后来打印的 a0
是错误的代码-打印未初始化的代码n
-这可能是任何代码int
或陷阱。
扫描缺少宽度限制。在第 99 个字符之后发生了不好的事情。
使用,如果第一个字符是scanf("%[^.,\n]s%n", s, &n);
,扫描将不保存任何内容。后来的打印很糟糕,因为未初始化。s
.,\n
s
s[]
代码无法检查 的返回值scanf()
。
scanf()
肯定不会按照“编写一个从用户那里获取一行的程序”的指示读取一行scanf()
- 它使用.
C Std Lib 定义如下一行,因此代码应尝试读取整行。
文本流是组成行的有序字符序列,每行由零个或多个字符加上一个终止换行符组成。
scanf()
选择
int n = 0;
char s[100];
s[0] = '\0';
int cnt == scanf("%99[^.,\n]%n", s, &n);
if (cnt == EOF) puts("Nothing was read");
else printf("%s\n", s);
更好的选择
我建议使用fgets()
而不是scanf()
:从 user 取一行。
char s[100];
if (fgets(s, sizeof s, stdin)) {
size_t n = strcspn(s, ".,\n"); // offset of string that does not have .,\n
s[n] = '\0';
printf("%s\n", s);
printf("%zu\n", n);
}
注意:超过 100 行的行需要额外的代码。
推荐阅读
- html - ios mobile 上不显示滑块背景图像?
- html - 如何垂直堆叠居中的div
- git - 修改了第一次提交添加了更多提交
- machine-learning - 为什么学习率已经很小(1e-05)而模型收敛速度太快?
- c# - 运行时优化 C# -> MySQL
- node.js - 将子子项添加到文档中的猫鼬问题
- azure - AADLoginForWindows 的 Terraform Azure VM 扩展类型和 type_handler_version 参数值
- docker - Google Cloud Container Registry 使用 gcloud 命令列出子目录中的图像
- python - 使用 `with` 语句命名列表元素
- api - 直接进入地址栏时,您必须使用 API 密钥来验证对 Google Maps Platform API 的每个请求错误