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

C语言读取/etc/passwd提取用户名与Shell的代码问题求助

问题修复:读取/etc/passwd提取用户名与Shell的C程序

原代码的核心问题

  • 参数传递错误:main中调用customized_print("%s", outbuff),但函数定义要求传入待处理的缓冲区buff和输出缓冲区outbuff,传参完全不匹配。
  • 逐字节读取逻辑错误:每次只读1字节就调用处理函数,无法获取完整行数据,自然没法正确解析字段。
  • 运算符优先级错误:outbuff[j++]=buff[i++] == ':'中,==优先级高于=,实际是把布尔值(0/1)赋值给输出缓冲区,而非目标字符。
  • 未处理行边界:没有累积字符到换行符,导致无法按行解析/etc/passwd的结构。
  • 输出缓冲区未初始化:outbuff每次使用前未清空,可能残留垃圾数据。

修复后的完整代码

#include <unistd.h>
#include <fcntl.h>

// 自定义printf原型(假设环境提供该函数实现)
int printf(const char *text, ...);

void parse_passwd_line(char* line, char* outbuff);

int main(void)
{
    int fd;
    char line[512];
    char outbuff[512];
    int size;
    int pos = 0;

    fd = open("/etc/passwd", O_RDONLY);
    if (fd < 0)
    {
        printf("Error opening file\n");
        return -1;
    }

    // 累积读取字符,直到换行或缓冲区满
    while ((size = read(fd, &line[pos], 1)) > 0)
    {
        if (line[pos] == '\n' || pos >= 511)
        {
            line[pos] = '\0'; // 终止字符串
            parse_passwd_line(line, outbuff);
            printf("%s\n", outbuff);
            pos = 0; // 重置位置,处理下一行
        }
        else
        {
            pos++;
        }
    }

    // 处理文件末尾无换行的剩余内容
    if (pos > 0)
    {
        line[pos] = '\0';
        parse_passwd_line(line, outbuff);
        printf("%s\n", outbuff);
    }

    close(fd);
    return 0;
}

void parse_passwd_line(char* line, char* outbuff)
{
    int i = 0, j = 0;
    int colon_count = 0;

    // 清空输出缓冲区
    for (int k = 0; k < 512; k++)
    {
        outbuff[k] = '\0';
    }

    // 提取第一个冒号前的用户名
    while (line[i] != '\0' && line[i] != ':')
    {
        outbuff[j++] = line[i++];
    }
    outbuff[j++] = ':'; // 添加分隔符

    // 跳过前5个冒号,定位到第六个冒号后的Shell部分
    while (line[i] != '\0' && colon_count < 5)
    {
        if (line[i++] == ':')
        {
            colon_count++;
        }
    }

    // 提取Shell部分
    while (line[i] != '\0' && line[i] != '\n')
    {
        outbuff[j++] = line[i++];
    }
}

修复说明

  1. 按行读取:在main中累积字符直到换行符,确保每次处理的是完整的一行数据。
  2. 修正参数传递:调用parse_passwd_line时传入完整行缓冲区和输出缓冲区,匹配函数定义。
  3. 修复运算符问题:直接复制字符,避免错误的优先级导致的赋值错误。
  4. 初始化输出缓冲区:每次处理前清空outbuff,避免垃圾数据干扰。
  5. 处理文件末尾:针对文件最后一行无换行的情况,确保剩余内容也能被解析。
  6. 重命名函数:将customized_print改为parse_passwd_line,更符合功能语义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:05:20