为什么 fgets 将光标移到下一行?
Why fgets takes cursor to next line?
我使用 fgets()
函数从键盘上获取了一个字符串。但是,当我使用 printf()
打印字符串时,光标会换行。
下面是代码。
#include<stdio.h>
int main()
{
char name[25];
printf("Enter your name: ");
fgets(name, 24, stdin);
printf("%s",name);
return 0;
}
下面是输出。
-bash-4.1$ ./a.out
Enter your name: NJACK1 HERO
NJACK1 HERO
-bash-4.1$
为什么我没有在 printf()
中添加 \n
,但光标会转到下一行?
但是,我注意到如果我使用 scanf()
读取一个字符串,然后使用 printf()
打印它(不使用 \n
),光标不会转到下一个行。
fgets()
是否在字符串中附加了 \n
?如果是,它会先附加 [=21=]
然后 \n
,还是先附加 \n
再附加 [=21=]
?
因为阅读文中如果有'\n'
会被fgets()
取走,下面摘自1570稿§7.21.7.2 ¶ 2
The fgets function reads at most one less than the number of characters specified by n
from the stream pointed to by stream into the array pointed to by s. No additional
characters are read after a new-line character (which is retained) or after end-of-file. A
null character is written immediately after the last character read into the array.
我用粗体突出显示 '\n'
由 fgets()
保留的部分。
printf
输出换行符的原因是您的字符串中有换行符。
fgets
不是 "adding" 换行符 --- 它也只是从输入中读取它。 fgets
的阅读在 换行符(如果有)之后 停止。
摘自 the manpage,强调我的:
The fgets() function reads at most one less than the number of characters specified by size from the given stream and stores them in the string str. Reading stops when a newline character is found, at end-of-file or error. The newline, if any, is retained. If any characters are read and there is no error, a `[=16=]' character is appended to end the string.
检查是否有换行符的一种简单方法是使用我最喜欢的鲜为人知的函数之一的帮助 --- strcspn()
:
size_t newline_pos = strcspn(name, "\r\n");
if(name[newline_pos])
{
/* we had a newline, so name is complete; do whatever you want here */
//...
/* if this is the only thing you do
you do *not* need the `if` statement above (just this line) */
name[newline_pos] = 0;
}
else
{
/* `name` was truncated (the line was longer than 24 characters) */
}
或者,作为单行:
// WARNING: This means you have no way of knowing if the name was truncated!
name[strcspn(name, "\r\n")] = 0;
我使用 fgets()
函数从键盘上获取了一个字符串。但是,当我使用 printf()
打印字符串时,光标会换行。
下面是代码。
#include<stdio.h>
int main()
{
char name[25];
printf("Enter your name: ");
fgets(name, 24, stdin);
printf("%s",name);
return 0;
}
下面是输出。
-bash-4.1$ ./a.out
Enter your name: NJACK1 HERO
NJACK1 HERO
-bash-4.1$
为什么我没有在 printf()
中添加 \n
,但光标会转到下一行?
但是,我注意到如果我使用 scanf()
读取一个字符串,然后使用 printf()
打印它(不使用 \n
),光标不会转到下一个行。
fgets()
是否在字符串中附加了 \n
?如果是,它会先附加 [=21=]
然后 \n
,还是先附加 \n
再附加 [=21=]
?
因为阅读文中如果有'\n'
会被fgets()
取走,下面摘自1570稿§7.21.7.2 ¶ 2
The fgets function reads at most one less than the number of characters specified by n from the stream pointed to by stream into the array pointed to by s. No additional characters are read after a new-line character (which is retained) or after end-of-file. A null character is written immediately after the last character read into the array.
我用粗体突出显示 '\n'
由 fgets()
保留的部分。
printf
输出换行符的原因是您的字符串中有换行符。
fgets
不是 "adding" 换行符 --- 它也只是从输入中读取它。 fgets
的阅读在 换行符(如果有)之后 停止。
摘自 the manpage,强调我的:
The fgets() function reads at most one less than the number of characters specified by size from the given stream and stores them in the string str. Reading stops when a newline character is found, at end-of-file or error. The newline, if any, is retained. If any characters are read and there is no error, a `[=16=]' character is appended to end the string.
检查是否有换行符的一种简单方法是使用我最喜欢的鲜为人知的函数之一的帮助 --- strcspn()
:
size_t newline_pos = strcspn(name, "\r\n");
if(name[newline_pos])
{
/* we had a newline, so name is complete; do whatever you want here */
//...
/* if this is the only thing you do
you do *not* need the `if` statement above (just this line) */
name[newline_pos] = 0;
}
else
{
/* `name` was truncated (the line was longer than 24 characters) */
}
或者,作为单行:
// WARNING: This means you have no way of knowing if the name was truncated!
name[strcspn(name, "\r\n")] = 0;