【问题标题】:C - printf() not working correctly?C - printf() 不能正常工作?
【发布时间】:2013-06-09 16:52:50
【问题描述】:

我正在编写一个简单的程序,它以这种格式获取有关人员的数据: 姓名、年龄、性别、信息

它会像这样显示它们 [姓名:,年龄:,性别:,信息:]

到目前为止,这是我的代码:

#include <stdio.h>

int main() {
char name[10];
int age;
char gender[2];
char info[50];

while(scanf("%9[^,],%i,%c,%49[^\n]", name, &age, gender, info) == 4) {
    printf("[name: %s, age: %i, gender: %c, info: %s]\n", name, age, gender, info);
}

return 0;

}

所以我决定使用 > 将我的输出写入另一个文本文件。并且它不会正确显示,] 括号显示在新行上,而 [name: 本身显示。

这是我的输入:

 eliza,7,F,likes animals
 bob,9,M,fast at running
 sue,6,F,likes painting

输出是:

 [name: eliza, age: 7, gender: J, info: likes animals
 ]
 [name: 
 bob, age: 9, gender: J, info: fast at running
 ]
 [name: 
 sue, age: 6, gender: J, info: likes painting
 ]

有人可以帮忙吗?我不知道为什么它会这样打印数据,我尝试使用 strstr() 检查我的任何变量是否包含换行符。

【问题讨论】:

  • 我猜这是Windows?
  • 是的,这有什么影响吗?
  • 是的; Windows 中的行尾是 \r\n 而不仅仅是 \n
  • @Dave ,你是对的.....正在开发solaris。为答案 +1。
  • 我在 Windows 上测试了 thsi,但在 info 末尾没有得到新行。致 OP:您使用的是什么编译器,如何输入?

标签: c printf


【解决方案1】:

你有两个问题。首先,我相信这是 Windows(或者至少您正在阅读的文件是在 Windows 中创建的),这意味着您在行尾有 \r\n 而不仅仅是 \n。您可以通过以文本模式打开文件来解决此问题,但这并不可靠;最好手动过滤掉多余的\r。

这就是在每个“信息”字段后添加换行符的原因。

第二个问题是您从 info 字段中拒绝了 \n,因此它仍然作为以后的“name”字段的第一个字符存在,这就是您在那里有额外换行符的原因。要修复它,只需在您的 scanf 字符串的开头放置一个空格(它会吞下所有空格)

Inspired 指出了您的第三个问题(我没有注意到);您需要将性别视为字符而不是字符串。 “正确”的阅读方式是这样的:

char gender; // no need to have an array of characters
scanf( "blah %c blah", &gender );

并像这样打印:

printf( "blah %c blah", gender );

【讨论】:

  • 对不起,我有点困惑。现在我有这样的scanf: scanf(" %9[^,],%i,%c,%49[^\r\n]", name, &age, &gender, info) 你说我可以选择只是过滤掉\r,但我决定过滤掉两个\r\n。但是如果在 BOTH 过滤,我似乎在第一个字符串之后需要一个空格,为什么?既然我都在过滤,换行符不应该消失吗?
  • @miniJavaLearner 不,它们是单独的问题;因为您的信息字段 rejects 换行符,它们被保存在流中以供下次调用读取。这就是为什么你也需要在字符串的开头或结尾有一个空格来明确地吞下它。
  • 代码从标准输入读取。这立即意味着即使在 Windows 下也没有 \r\n 这样的东西。在这方面没有任何操作系统敏感性。所有输入行将以\n 结尾。此外,通过文本模式读取文本文件绝对没有“不可靠”的地方。正确指出\n 未读的问题。而%c 和 char 数组的问题确实是另一个问题。
  • @AndreyT 好点。在那种情况下,你能解释一下“信息”末尾的换行符吗? (我猜我会说它实际上是从其他地方读取的;如果输入是从另一个进程通过管道传输的,\r\n 转换是否适用?)
  • @Dave:我无法解释。在 Windows 上进行的快速测试不会在 info 的末尾重现该换行符。可能是 OP 使用了一个文件作为输入,该文件在每个输入行的末尾包含了两个换行符?
【解决方案2】:
#include <stdio.h>

int main(void) {
    char name[10];
    int age;
    char gender;//change
    char info[50];

    while(scanf("%9[^,],%i,%c,%49[^\n]%*c", name, &age, &gender, info) == 4) {
        printf("[name: %s, age: %i, gender: %c, info: %s]\n", name, age, gender, info);
    }

    return 0;
}

【讨论】:

  • 这将在信息末尾留下换行符,因为\r 仍然存在。
  • @Dukeling at windows \r\n convert(I/O:in \r\n ->\n, out \n -> \r\n) 到\n。 (模式不是二进制)
  • @BLUEPIXY 非二进制模式不是进行过滤的可靠方法。例如,在 linux 上运行但在 windows 上生成文件时。
  • @Dukeling:那里没有\r,除非 OP 使用了损坏的库实现。 C 中的所有文本流输入保证纯 \n 行结尾。
  • @Dave:嗯,这仅仅是因为 POSIX 根本没有非二进制模式。确实,Linux 上的 Windows 文件无法正常工作。但在这种情况下,这肯定不是问题。此外,您可能知道,\r 不会产生新行。它确实回车而不跳到下一行。
猜你喜欢
  • 1970-01-01
  • 2010-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多