【问题标题】:C - printf output varies depending on subsequent code [duplicate]C - printf输出取决于后续代码[重复]
【发布时间】:2018-01-05 00:06:59
【问题描述】:

前言:我只是在搞C,请原谅我的无能。这个问题的原因可能是基本的。

问题:我正在尝试读取文件并使用套接字通过 http 提供它。出于某种原因,先前读取的文件的printf 输出会根据包含的后续代码量而有所不同。

这是我的代码。

#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#include <netinet/in.h>


int main()
{

    // open a file to serve
    FILE *file;
    file = fopen("index.html", "r");
    if (file == NULL)
    {
        printf("Failed to open file.");
        exit(EXIT_FAILURE);
    }

    // Get file content
    char file_content[1024];
    if (fgets(file_content, 1024, file) != NULL)
    {

        fclose(file);

        // Add header to file content
        char http_header[2048] = "HTTP/1.1 200 OK\r\n\n";    
        strncat(http_header, file_content, 1028);

        // This output varies depending on inclusion of proceeding code.
        printf("%s", http_header);

        // create a socket
        int server_socket;
        server_socket = socket(AF_INET, SOCK_STREAM, 0);        

        // define the address
        struct sockaddr_in server_address;
        server_address.sin_family = AF_INET;
        server_address.sin_port = htons(8001);
        server_address.sin_addr.s_addr = INADDR_ANY;

        bind(server_socket, (struct sockaddr *) &server_address, sizeof(server_address));        
        listen(server_socket, 1);

        int client_socket;        
        while (1)
        {
            client_socket = accept(server_socket, NULL, NULL);
            send(client_socket, http_header, sizeof(http_header), 0);
            close(client_socket);
        }
        return 0;
    }

}

如果我注释掉 printf 语句之后的所有内容,我会得到这个预期的输出..

HTTP/1.1 200 OK

<html><body>Hi</body></html>

但是如果我运行所有代码,我会得到这个。..

HTTP/1.1 200 OK

如果我可以改进我的问题,请告诉我如何。谢谢。

【问题讨论】:

  • O/T 移动 fclose(file);return 0;if(fgets(..)) 检查之外。无论fgets 是否返回 NULL,这些事情都应该发生。
  • 我怀疑您的文件内容不包含结尾的 \n 字符,并且您的程序不会因为无限循环而终止,因此输出缓冲区永远不会被刷新。退出无限循环,或在输出中添加尾随换行符。
  • ... 或在printf 之后尝试fflush(stdout);printf 是行缓冲的,fflush(stdout); 将手动刷新 stdout
  • 你的字符串"HTTP/1.1 200 OK\r\n\n" 应该是"HTTP/1.1 200 OK\r\n\r\n"——每一行都需要以\r\n 结尾。但是,这不太可能是您的直接问题。
  • header应该在循环之前生成;文件的内容应该在循环内回显。侦听/接受代码的位置很奇怪;那不应该在循环之外并且只在收到连接时发送文件吗?

标签: c file sockets while-loop strcat


【解决方案1】:

Mark Benningfield 和 Yano 帮助我理解了这个问题,非常感谢你们俩。

当你执行printf() 时,字符串不是直接进入终端窗口,而是每一行进入一个buffer

缓冲区中的每一行都必须刷新才能在终端中显示。 these events

可以自动刷新缓冲区

\n 结尾的字符串会自动刷新,这就是第一行HTTP/1.1 200 OK \r\n\n 显示正常的原因。第二行&lt;html&gt;&lt;body&gt;hi&lt;/body&gt;&lt;/html&gt; 不以\n 结尾,或触发任何其他自动刷新事件,因此不会显示。

通常这不是问题,因为当程序终止时,缓冲区会自动刷新,所有通过printf 进入缓冲区的行都会显示在终端中。由于我在底部的程序进入了一个无限的while循环,所以程序永远不会终止,缓冲区也永远不会被刷新。

printf 之后调用fflush(stdout) 会强制写入stdout 的整个缓冲区。

More info on fflush

【讨论】:

猜你喜欢
  • 2019-03-25
  • 1970-01-01
  • 2011-06-19
  • 1970-01-01
  • 2014-08-30
  • 2020-05-08
  • 2016-11-14
  • 1970-01-01
  • 2017-05-21
相关资源
最近更新 更多