为什么fgets将光标移到下一行?

时间:2015-02-11 00:52:04

标签: c string cursor scanf fgets

我使用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$

为什么即使我没有在\n中添加printf(),光标也会转到下一行?

但是,我注意到如果我使用scanf()读取字符串,然后使用printf()打印它(不使用\n),则光标不会转到下一行。

fgets()是否在字符串中追加\n?如果有,它会先\0追加\n,先\n再追\0吗?

2 个答案:

答案 0 :(得分:4)

printf输出换行符的原因是你的字符串中有一个。

fgets不是&#34;添加&#34;换行符 - 它只是从输入中读取它。阅读fgets只需在换行符后停止(如果有的话)。

摘自the manpage,强调我的:

  

fgets()函数最多读取一个小于给定流中size指定的字符数,并将它们存储在字符串str中。 在找到换行符时,在文件结尾或错误时停止读取。保留换行符(如果有)。如果读取任何字符且没有错误,则为“\ 0&#39;附加字符以结束字符串。

检查是否有新行的简单方法是使用我最喜欢的一个鲜为人知的函数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;

答案 1 :(得分:2)

因为如果阅读文本中有'\n',则fgets()将采用'\n',以下内容摘自1570草案§7.21.7.2 ¶2

  

fgets函数最多读取一个小于n指定的字符数   从流指向的流进入s指向的数组。没有额外的   在新行字符(保留)之后或文件结束后读取字符。一个   在读入数组的最后一个字符后立即写入空字符。

我通过粗略表示fgets()保留{{1}}的部分来突出显示。