为什么从控制台读取字符串时scanf中的%n返回0

问题描述 投票:0回答:1

我试图编写一个程序,该程序要从用户(控制台)开始一行,直到遇到逗号,句号或换行符,并告诉按照特定模式读取了多少个字符。

正确读取字符串,但计数不正确。

#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;
}
c string scanf
1个回答
1
投票
"s"中的"%[^.,\n]s%n"停止扫描,因为在's'之后无法读取%[^.,\n]%[^.,\n]应该已全部读入's'。因此,以后的"%n"永远不会出现,后来打印的n,即0是错误的代码-打印未初始化的n-可能是任何int或陷阱。

扫描没有宽度限制。第99个字符后发生坏事。

使用scanf("%[^.,\n]s%n", s, &n);,如果第一个字符是s,则扫描将不会在.,\n中保存任何内容。 s的后续打印不好,因为s[]未初始化。

代码无法检查scanf()的返回值。

scanf()不一定会按照“编写需要用户输入一行的程序”的指示来读取

line-使用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()

从用户那里接一行。

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行的行需要附加代码。
© www.soinside.com 2019 - 2024. All rights reserved.