You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

进程间Pipe实现字符串大写转换程序故障排查求助

问题排查与修复方案

你的管道程序无法正常工作,核心问题并非子进程提前读取,而是代码中存在多处逻辑错误和未定义行为,以下是具体问题和修复步骤:

1. 父进程写入循环的未初始化变量与逻辑错误

  • 问题:父进程中int n;未初始化就进入while(n < len)循环,触发未定义行为,程序可能直接跳过写入逻辑。同时循环条件错误,应判断已写入总字节数total是否小于需要写入的长度len,而非单次写入的n。
  • 修复:初始化n = 0,修改循环条件为while(total < len),且每次写入剩余未发送的字节:
int n = 0;
int total = 0;
while(total < len) {
    n = write(fd[1], buffer + total, len - total);
    if(n < 0) {
        perror("FEHLER BEIM SENDEN\n");
        break;
    }
    total += n;
}

2. 父进程未关闭管道写端

  • 问题:父进程写完数据后未关闭fd[1],导致子进程的read会一直阻塞等待更多数据(管道写端仍处于打开状态)。
  • 修复:写入完成后调用close(fd[1]);。

3. 子进程未检查read返回值

  • 问题:子进程的read未判断返回值,当管道写端关闭后,read返回0表示无更多数据,但当前代码会继续读取,导致c值不确定,可能陷入无限循环或处理垃圾值。
  • 修复:读取时检查read返回值:
ssize_t ret;
while(1) {
    ret = read(fd[0], &c, 1);
    if(ret <= 0) { // 返回0表示写端关闭,-1表示出错
        break;
    }
    if(c == '\0') {
        break;
    }
    if(isalpha(c)) { // 判断字母,需包含<ctype.h>
        buffer[i] = c;
        i++;
    }
}

4. 子进程字符判断逻辑错误

  • 问题:c > 64 || c < 123会匹配所有ASCII字符(所有ASCII字符都满足大于64或小于123),起不到过滤字母的作用。
  • 修复:使用isalpha(c)(需包含<ctype.h>),或直接判断(c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')。

5. 子进程buffer未初始化

  • 问题:buffer由malloc分配,初始为垃圾数据,后续处理可能输出无效值。
  • 修复:子进程读取前初始化buffer:memset(buffer, 0, BUF);

6. 子进程遍历buffer的效率问题

  • 问题:处理和输出时遍历整个BUF长度,但实际仅读取了i个有效字符,多余遍历会处理空值或垃圾值。
  • 修复:循环到i即可,避免变量名冲突:
for(int j = 0; j < i; j++) {
    if(buffer[j] >= 'a' && buffer[j] <= 'z') {
        buffer[j] -= 32;
    }
}
// 输出同理
for(int j = 0; j < i; j++) {
    printf("%c   ", buffer[j]);
}

完整修正代码

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <ctype.h>

#define BUF 64

/*
任务:
父进程:通过pipe将包含大小写字母的数组传递给子进程
子进程:将所有字符转换为大写
*/

int main(void) {
    pid_t pid;
    int fd[2];

    if(pipe(fd) == -1) {
        perror("FEHLER BEIM ERSTELLEN DER PIPE\n");
        exit(EXIT_FAILURE);
    }

    char *buffer = malloc(sizeof(char)*BUF);
    if(buffer == NULL) {
        perror("FEHLER BEIM SPEICHERANFORDERUNG\n");
        exit(EXIT_FAILURE);
    }

    switch(pid = fork()) {
        case -1:
            perror("FEHLER BEI FORK\n");
            free(buffer);
            close(fd[0]);
            close(fd[1]);
            exit(EXIT_FAILURE);
        case 0: //子进程
            close(fd[1]);
            memset(buffer, 0, BUF);
            char c;
            int i = 0;
            ssize_t ret;
            while(1) {
                ret = read(fd[0], &c, 1);
                if(ret <= 0) {
                    break;
                }
                if(c == '\0') {
                    break;
                }
                if(isalpha(c)) {
                    buffer[i] = c;
                    i++;
                    if(i >= BUF-1) {
                        break;
                    }
                }
            }
            close(fd[0]);

            for(int j = 0; j < i; j++) {
                if(buffer[j] >= 'a' && buffer[j] <= 'z') {
                    buffer[j] -= 32;
                }
            }

            printf("Die Zeichen in Großbuchstaben sind:\n\n");
            for(int j = 0; j < i; j++) {
                printf("%c   ", buffer[j]);
            }
            printf("\n");

            free(buffer);
            exit(EXIT_SUCCESS);
        default: //父进程
            close(fd[0]);
            char string1[] = "a b c d e f G h I";
            memset(buffer, 0, BUF);
            strcpy(buffer, string1);
            int len = strlen(buffer) + 1;
            int n = 0;
            int total = 0;

            while(total < len) {
                n = write(fd[1], buffer + total, len - total);
                if(n < 0) {
                    perror("FEHLER BEIM SENDEN\n");
                    break;
                }
                total += n;
            }
            close(fd[1]);

            printf("Nachricht gesendet.\n");

            free(buffer);
            wait(NULL);
            exit(EXIT_SUCCESS);
    }
}

内容的提问来源于stack exchange,提问作者Chanyoung Woo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 08:02:54