使用read()读取stdin后无法printf/write输出数组值的问题
问题分析与解决方案
1. printf无输出的核心原因
stdout默认是行缓冲模式,只有当输出缓冲区填满、遇到换行符\n,或者程序退出时才会刷新缓冲区。你的代码中printf("%lf", sin_output[0]);没有添加换行符,且程序一直在无限循环中,导致缓冲区从未刷新,所以控制台看不到输出。
解决方法二选一:
- 在printf中添加换行符:
printf("%lf\n", sin_output[0]); - 手动强制刷新缓冲区:
printf("%lf", sin_output[0]); fflush(stdout);
2. write输出乱码的原因
write()是底层系统调用,它直接将内存中的二进制数据写入文件描述符。double类型的二进制存储格式(IEEE 754)和人类可读的字符串完全不同,所以控制台会显示乱码。
如果后续要向套接字/管道传输数值,直接用write()发送二进制double是可行的(接收方需要按同样的格式解析);但如果要在控制台显示,必须先将数值格式化为字符串,比如用sprintf先写到字符数组,再用write输出:
char output_str[32]; sprintf(output_str, "%lf\n", sin_output[0]); write(1, output_str, strlen(output_str));
3. sin(0.01)输出0.010000的精度问题
sin(0.01)的实际值约为0.009999833334166664,%lf格式默认保留6位小数,四舍五入后就显示为0.010000。如果需要更精确的输出,指定更高的小数位数即可:
printf("%.10lf\n", sin_output[0]); // 输出0.0099998333
4. 实际程序的优化建议
你的代码还有几个可以改进的点:
- 处理read的返回值:
read()可能返回-1(错误)或0(EOF),不处理会导致死循环:ssize_t read_ret = read(0, buf, sizeof(buf)); if (read_ret <= 0) { // 处理错误或EOF,比如退出循环 break; } - 调整输出时机:当前代码每次循环都输出,而你的需求是按回车才增加counter并输出,应该把输出逻辑放到
if (buf[0] == 10)的分支里:if (buf[0] == '\n') { enter_counter += 0.01; sin_output[0] = sin(enter_counter); printf("%lf\n", sin_output[0]); fflush(stdout); // 或者靠换行符刷新 } - 简化buf初始化:
memset没必要,read()会直接覆盖buf的内容,每次循环前不需要清零。
修正后的完整代码
/* includes*/ #include <math.h> #include <stdio.h> #include <unistd.h> /* main function*/ int main() { /* declare variables*/ char buf[1]; double enter_counter = 0; double sin_output[1]; /* master loop*/ while (1) { /* read stdin and handle errors/EOF*/ ssize_t read_ret = read(0, buf, sizeof(buf)); if (read_ret <= 0) { break; } /* if stdin == enter key, progress sin by 0.01rad and output*/ if (buf[0] == '\n') { enter_counter += 0.01; sin_output[0] = sin(enter_counter); printf("sin(%.2lf) = %.10lf\n", enter_counter, sin_output[0]); } } return 0; }
内容的提问来源于stack exchange,提问作者tech_scholar
相关产品推荐
相关产品推荐

