C语言多进程管道程序问题:无法将命令行参数argv[1]转换为大写
问题分析与修复方案
我帮你排查了代码里的几个核心问题,尤其是没实现转大写的逻辑,还有一些管道和字符串处理的细节错误:
主要问题点
- 完全缺失转大写逻辑:子进程只是读取了管道内容,根本没调用
toupper()处理字符,这是最核心的问题 - 字符串长度计算错误:
sizeof(argv[1])获取的是指针的字节数(比如64位系统是8),不是字符串实际长度,应该用strlen(argv[1]) + 1(要包含字符串结束符\0) - 输出内容错误:父进程读取管道B的内容后,依然打印原
argv[1],而不是转换后的结果;子进程写入管道B的也是原字符串,不是处理后的大写版本 - 变量复用错误:创建第二个管道时,你定义了
err2但还是用了err接收返回值,会覆盖第一个管道的错误状态 - 多余的等待调用:父进程里已经用
wait(0)等待子进程退出,后面的wait(NULL)会导致不必要的阻塞 - 缓冲区溢出风险:
readmessage固定为12字节,如果输入的字符串超过11个字符会溢出,建议根据输入长度动态调整
修正后的代码
#include <sys/wait.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> // 要包含strlen的头文件 int main(int argc, char* argv[]) { // 先检查命令行参数是否存在 if (argc < 2) { fprintf(stderr, "Usage: %s <text>\n", argv[0]); exit(EXIT_FAILURE); } int fd[2], err; int fd2[2], err2; pid_t pid; // 根据输入字符串长度定义缓冲区,避免溢出 char* readmessage = malloc(strlen(argv[1]) + 1); if (!readmessage) { perror("malloc error"); exit(EXIT_FAILURE); } // 创建管道A err = pipe(fd); if (err < 0) { perror("pipe A error"); free(readmessage); exit(EXIT_FAILURE); } // 创建管道B,用err2接收错误 err2 = pipe(fd2); if (err2 < 0) { perror("pipe B error"); close(fd[0]); close(fd[1]); free(readmessage); exit(EXIT_FAILURE); } pid = fork(); if (pid < 0) { perror("fork error"); // 出错时要关闭已打开的管道和释放内存 close(fd[0]); close(fd[1]); close(fd2[0]); close(fd2[1]); free(readmessage); exit(EXIT_FAILURE); } else if (pid > 0) { /* 父进程逻辑 */ close(fd[0]); // 关闭管道A的读端 close(fd2[1]); // 关闭管道B的写端 size_t msg_len = strlen(argv[1]) + 1; printf("Parent Process - Writing to pipe A - Message is: %s\n", argv[1]); // 写入正确长度的字符串 write(fd[1], argv[1], msg_len); // 从管道B读取转换后的内容 read(fd2[0], readmessage, msg_len); printf("Parent Process - Reading from pipe B - Uppercase Message is: %s\n", readmessage); sleep(1); printf("Child is Terminated!\n"); wait(NULL); // 等待子进程退出 // 清理资源 close(fd[1]); close(fd2[0]); free(readmessage); } else { /* 子进程逻辑 */ close(fd[1]); // 关闭管道A的写端 close(fd2[0]); // 关闭管道B的读端 size_t msg_len = strlen(argv[1]) + 1; read(fd[0], readmessage, msg_len); printf("Child Process - Reading from pipe A - Original Message is: %s\n", readmessage); printf("Converting to uppercase...\n"); sleep(1); // 核心:遍历字符串,转换每个字符为大写 for (int i = 0; readmessage[i] != '\0'; i++) { readmessage[i] = toupper((unsigned char)readmessage[i]); } printf("Child Process - Writing to pipe B - Uppercase Message is: %s\n", readmessage); // 写入转换后的字符串 write(fd2[1], readmessage, msg_len); printf("Child is exiting!\n"); // 清理子进程的资源 close(fd[0]); close(fd2[1]); free(readmessage); exit(EXIT_SUCCESS); } return 0; }
关键修复说明
- 添加转大写逻辑:子进程中用循环遍历字符串的每个字符,调用
toupper()转换,注意要把字符转成unsigned char避免处理负数的ASCII值 - 正确处理字符串长度:用
strlen()获取实际长度,加1包含\0,避免截断或写入错误长度 - 动态分配缓冲区:根据输入字符串长度分配内存,避免固定大小的缓冲区溢出
- 修正管道和资源清理:每个进程只保留需要的管道端,出错时正确关闭管道和释放内存
- 参数检查:添加了命令行参数的检查,避免用户忘记输入文本
内容的提问来源于stack exchange,提问作者AdamOl_TR
相关产品推荐
相关产品推荐

