【问题标题】:Printf having unusual behavior in C programPrintf 在 C 程序中具有异常行为
【发布时间】:2014-10-07 15:25:48
【问题描述】:

我正在 Ubuntu 上用 C 语言创建服务器,但是我遇到了一个 printf 函数不起作用的问题。这是代码。我希望终端在程序启动后立即打印“dd”,但它什么也不做。有什么建议吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>

void main(){
printf("dd");
int ds_sock;
struct sockaddr_in my_addr;
ds_sock=socket(AF_INET,SOCK_STREAM,0);

memset(&my_addr,0,sizeof(my_addr));
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(25000);
my_addr.sin_addr.s_addr=INADDR_ANY;

bind(ds_sock,(struct sockaddr *)&my_addr,sizeof(my_addr));

listen(ds_sock,3);
printf("dd");
int ds_sock_acc;
struct sockaddr_in addr;
size_t sin_size = sizeof(struct sockaddr_in);
ds_sock_acc = accept(ds_sock,(struct sockaddr *)&addr,&sin_size);
while(ds_sock_acc==-1) {
    printf("connessione non riuscita");
    ds_sock_acc = accept(ds_sock,(struct sockaddr *)&addr,&sin_size);
}
printf("connessione riuscita");
close(ds_sock);
close(ds_sock_acc);
}

此(客户端)按预期工作:

void main(){
printf("dd");
int ds_sock;
ds_sock = socket(AF_INET, SOCK_STREAM,0);

int ret;
struct sockaddr_in Eaddr;
Eaddr.sin_family = AF_INET;
Eaddr.sin_port = htons(25000);
Eaddr.sin_addr.s_addr=inet_addr("127.0.0.1");
ret = connect(ds_sock,(struct sockaddr *)&Eaddr,sizeof(Eaddr));
while(ret==-1){ 
    printf("Errore nel connect");
    ret = connect(ds_sock,(struct sockaddr *)&Eaddr,sizeof(Eaddr));
}
printf("connect OK");
close(ds_sock);

}

【问题讨论】:

  • dd 之后添加换行符'\n',或者改为fprintf(stderr, "dd");
  • 第二个例子产生输出可能只是因为程序是短暂的并且当程序退出时输出缓冲区被刷新。否则,它将具有相同的行为(尝试在最后一个 close 之后添加 sleep(30) 语句以亲自查看)。
  • 您可能希望通过选择一个有效的入口点来构建一个不会表现出未定义行为的程序。 void main() 不是其中之一。
  • 如果你 1) 注意listen() 的返回值,你会发现它更容易,2) 让每个 printf("dd") 输出唯一的值,这样你就知道在哪里他们是起源。 3)没有数据正在通信,所以没有迹象表明套接字工作。 4)跳过接受和连接的while循环,因为如果失败一次,它总是会失败。

标签: c printf


【解决方案1】:

printf 的输出将被缓冲。

要立即获得输出,您有两种选择:

  • 在字符串 (printf("dd\n");) 的末尾添加一个换行符 (\n)。这会隐式刷新输出流(即写出缓冲的内容)。

  • 在 printf 语句后显式刷新标准输出流 (fflush(stdout);)。

至于问题的第二部分,第二个示例产生输出可能只是因为程序是短暂的,并且在程序退出时会刷新输出缓冲区。否则,它将具有相同的行为(尝试在最后一次关闭后添加sleep(30) 语句以亲自查看)。

【讨论】:

  • 感谢您的回复。你能解释一下我在第一条消息中发布的第一段代码和第二段代码之间的区别吗?为什么第二个没有问题?
  • 查看对问题的评论。
【解决方案2】:

你需要刷新你的输出。

最简单的方法:

printf("dd\n");

更好的方法:

printf("dd");
fflush(stdout);

【讨论】:

  • 为什么说使用fflush 更好?在我看来,如果您想在输出中添加换行符,换行方式会很好。
  • @FredLarson:据我所知,在您的输出中添加\n 并不能保证刷新输出,但通常会刷新它。如果您想要保证行为,请使用fflush。如果您想要可能有效的东西,请使用\n
  • 我明白了。谢谢你。我在这里找到了更多信息:stackoverflow.com/q/5229096/10077
【解决方案3】:

您需要刷新输出流。使用fflush(stdout)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多