c语言printf和flush用法,C中printf 和write的区别

本文解析了printf在行缓冲下的延迟打印现象,与write的即时输出对比,通过代码实例展示了如何影响程序输出。重点讲解了缓冲机制在printf中的作用以及如何避免输出延迟。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

调试程序过程中遇到一个问题:遇到printf的语句时有时候能马上打印出字符串,有时候要程序退出时才一次性打印出字符串,但是write每次都能直接打印出字符串。

原来是因为printf是行缓冲函数,只有满了一行才马上打印, write在用户态没有缓冲,所以直接输出。

eg:

#include #include #include int main(void)

{

int fd;

char str[100];

//创建文件,并输入任意内容供测试

fd = open("test3.6.file", O_WRONLY | O_CREAT, 0660);

if(fd < 0)

err_quit("open test3.6.file failed");

write(fd, "Hello world!\n", 13);

write(fd, "1234567890\n", 11);

write(fd, "abcdefg\n", 8);

close(fd);

//测试读取从 文件开头,中间,结尾

fd = open("test3.6.file", O_RDWR | O_APPEND);

if(fd < 0)

err_quit("open test3.6.file rdwr failed");

printf("read from start: ");

//fflush(stdout);

lseek(fd, 0, SEEK_SET);

if( read(fd, str, 13) > 0)

write(STDOUT_FILENO, str, strlen(str));

printf("read from MID: ");

// fflush(stdout);

lseek(fd, 14, SEEK_SET);

if( read(fd, str, 11) > 0)

write(STDOUT_FILENO, str, strlen(str));

printf("read from END: ");

// fflush(stdout);

lseek(fd, -8, SEEK_END);

if( read(fd, str, 8) > 0)

write(STDOUT_FILENO, str, strlen(str));

//测试往文件中写

lseek(fd, 0, SEEK_SET);

write(fd, "##########", 10);

lseek(fd, 20, SEEK_SET);

write(fd, "@@@@@@@@@@", 10);

lseek(fd, 0, SEEK_END);

write(fd, "**********", 10);

exit(0);

}

如果把上面代码中fflush注释掉,那每次运行的结果如下:

Hello world!

234567890

********

read from start: read from MID: read from END:

如果再printf打印的字符串后面添加‘\n’或者fflush, 则能正常输出:

read from start: Hello world!

read from MID: 234567890

read from END: ********

在C语言中,与串口(Serial Port)建立联系通常涉及到硬件的底层通信以及使用特定的库,例如POSIX标准提供的sys/time.h、fcntl.h、termios.h或者在Windows平台上使用Win32 API(如CreateFile、WriteFile、ReadFile等)。 以下是一个简单的步骤概述: 1. **包含头文件**:首先,你需要包含相关的头文件,如在Linux中可能会用到`#include <stdio.h>`(用于标准输入输出)、`#include <fcntl.h>`(文件描述符处理)、`#include <termios.h>`(控制终端)。 2. **打开串口**:使用`open()`函数,传入设备名(如`"/dev/ttyS0"` 或 `"/dev/ttyUSB0"`),设置访问权限标志,以创建一个文件描述符。在Windows中,通常使用`CreateFile()`。 3. **配置串口**:使用`tcgetattr()``tcsetattr()`来获取设置串口属性,如波特率、数据位、停止位校验位等。在Linux中,`struct termios`结构体用于存储这些参数。 4. **读写操作**:通过文件描述符调用`read()``write()`函数进行数据发送接收。在Windows上,对应的是`ReadFile()``WriteFile()`。 5. **关闭串口**:完成操作后,记得使用`close()`或`CloseHandle()`关闭打开的串口。 示例代码片段(简化版): ```c #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <termios.h> int main() { int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY); // Linux // or on Windows // HANDLE hSerial = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, ...); struct termios options; tcgetattr(fd, &options); // Set serial port configuration here... cfsetispeed(&options, B9600); // 设置波特率为9600 options.c_cflag &= ~CSIZE; // Clear any existing size setting options.c_cflag |= CS8; // Set 8 data bits tcflush(fd, TCIFLUSH); // Flush input buffer tcsetattr(fd, TCSANOW, &options); // Apply changes immediately char send_data[] = "Hello from C!"; write(fd, send_data, strlen(send_data)); // Read from the serial port char receive_data[100]; read(fd, receive_data, sizeof(receive_data)); printf("Received: %s\n", receive_data); close(fd); // Close the device return 0; } ``` 请注意,实际的代码可能会更复杂,特别是当你需要处理错误情况、同步读写或者异步通信的时候。在编写这类代码时,请确保理解你的目标平台及其特定的API。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值