我正在使用Eclipse IDE的C/C ++。
我写了一个简单的C程序来查找字符串长度。扫描后,我在控制台屏幕上按下Enter键,但它作为输入,并在字符串中添加一个额外的字节。这只发生在Eclipse IDE中,在其他编译器中,如在线gdb,我得到了接受的输出。
示例:
#include <stdio.h>
#include <string.h>
#define MAX_LIMIT 127
int main()
{
char str[MAX_LIMIT];
int length;
printf("Enter the string\n");
fflush(stdout); // flush the output buffer
scanf("%[^\n]",str);
length = strlen(str);
printf("Length of the string is = %d\n",length);
return 0;
}
Eclipse控制台屏幕中的输出:
Enter the string
hello
Length of the string is = 6
其他编译器中的输出:
Enter the string
hello
Length of the string is = 5
我试图解决我的自我,但没有得到输出
编辑:
在注解中,我被告知通过添加以下行来打印字符串的各个字符代码
printf("%02x %02x %02x %02x %02x %02x %02x %02x\n", str[0], str[1], str[2], str[3], str[4], str[5], str[6], str[7]);
在我的程序的结尾。当我这样做的时候,我得到了如下的输出:
Enter the string
hello
Length of the string is = 6
68 65 6c 6c 6f 0d 00 00
2条答案
按热度按时间juud5qan1#
看起来您的Eclipse IDE的行为方式不符合ISO C标准。
根据ISO C11标准§7.21.3 ¶7,标准输入必须是文本流,而根据§7.21.2 ¶2,文本流必须有
\n
行结尾,但是根据您提供的信息,它表现为一个有\r\n
行结尾的二进制流。因此,如果您想补偿Eclipse的这种不兼容行为,就必须更改行
致:
qlzsbp2j2#
流中的
'\r'
这是一个Eclipse界面、编译器和键盘的问题。键盘Enter注入Ctrl R和Ctrl N,而 *gcc的 *
stdin
盲目地将其作为一个公共字符-Ctrl R后跟一个行尾。如果您将"123\n"
之类的序列从其他源剪切/粘贴到控制台窗口(或从命令行导入数据),代码将按预期工作。这不是文本与二进制流问题。注意:
stdout
打印时不使用'\r'
。问题:缓冲区溢出
编码
scanf("%[^\n]",str);
(或scanf("%[^\r\n]",str);
(忽略'\r'
)时不要使用 width。不要在未检查返回值的情况下使用
str
afterword。候补
使用
fgets()
读取输入的 * 行 *。请注意,这个第二个版本很好地读取了
"\n"
的一个 * 行 *,而scanf("%[^\n]", ...)
没有。此外,
scanf("%[^\r\n]",str)
仍然让那些讨厌的"\r\n"
被 * 某个东西 * 读取。更深
在某种程度上,
"\r\n"
或"\n"
在stdin
上的传入允许人们考虑如何使可执行文件在不同的环境中运行。我发现,来自文件的一组重定向输入可能起源于"\r\n"
或"\n"
,并努力使代码处理其中之一。步骤包括:scanf()
来读取一行输入,它不是正确的工具,fgets()
更好。str[strcspn(str, "\r\n")] = '\0';
以任意方式结束文本行。str[]
的大小增加1。