在不换行的情况下使用C puts()函数

44

我目前有一个程序,它可以在控制台上打印文本文件,但每一行下面都会多一个空行。 如果文本为

hello world

它将输出 hello

world

代码如下:

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
    FILE* fp;
    char input[80], ch = 'a';
    char key[] = "exit\n";
    int q;

    fp = fopen("c:\\users\\kostas\\desktop\\original.txt", "r+");

    while (!feof(fp)) {
        fgets(input, 80, fp);
        puts(input);
    }
    fclose(fp);

    return 0;
}

1
“iostream”不是仅限于C++的库吗?而“using”不是C++专用的关键字吗? - markoj
4个回答

93

通常情况下,为了省略换行符,人们会使用fputs()而不是puts()。在您的代码中,

puts(input);

会变成:

fputs(input, stdout);

3
您也可以使用printf(),但会增加一定的开销 :-) - Alex North-Keys
13
很高兴我找到了这个答案,因为我不想使用printf带来的额外负担。 - David Callanan
3
printf("%s", s) 必须解析格式字符串,这肯定比系统调用的开销要小 - 但你看过解析格式字符串的代码吗?那肯定是一种开销。请参见 https://code.woboq.org/userspace/glibc/stdio-common/vfprintf-internal.c.html。 - Alex North-Keys
@AlexNorth-Keys 如果你使用printf并换行,gcc会将其转换为puts。https://godbolt.org/z/784dEvnjP - qwr
好的,等待足够长的时间,gcc可能会将其转换为更高效的量子计算。编译器的魔力不断前进,尽管这经常会妨碍调试。 - Alex North-Keys
显示剩余2条评论

16

puts()函数会按照库规范添加换行符。您可以使用printf函数,使用格式字符串控制所要打印的内容:

printf("%s", input);

11
使用"%s"来代替简单的 "printf(input);"非常重要,以免输入中的任何百分号导致程序崩溃。 - Alex North-Keys
8
使用 "%s" 调用 printf 比使用 fputs 效率低,但你可能不太关心。 - benathon
2
编译器在启用优化时会将printf("%s",string)更改为fputs(string,stdout),至少gcc是这样做的。有些编译器可能会将其更改为fwrite(),当您知道字符串长度时,它会更快。 - 12431234123412341234123
@DanM。你是正确的,我的例子是错误的,但是当你有"%s\n"作为格式字符串时,gcc会将其替换为puts()。尝试使用gcc <input file>编译main(){printf("%s\n","");} - 12431234123412341234123
@12431234123412341234123,但这个问题特别涉及到没有换行符;P - Dan M.
显示剩余2条评论

5

你也可以编写自定义的 puts 函数:

#include <stdio.h>

int my_puts(char const s[static 1]) {
    for (size_t i = 0; s[i]; ++i)
        if (putchar(s[i]) == EOF) return EOF;

    return 0;
}

int main() {
    my_puts("testing ");
    my_puts("C puts() without ");
    my_puts("newline");

    return 0;
}

输出:

testing C puts() without newline

0

这应该可以工作:

#include<stdio.h>
void put_s(char* s){
    while(*s) putchar(*s++);
}

为了举更多的例子,这里有另一个涉及递归的例子:

#include<stdio.h>
void put_s(char* s){
    if(!*s) return;
    putchar(*s);
    put_s(s+1);
}

注意:我注意到你的代码无法编译,因为有 #include<iostream>using namespace std;

1
如果stdout没有缓冲,它可以工作,但可能会相当低效。 - Björn Lindqvist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接