【问题标题】:How to read contents of a file into two separate char buffers using a while loop?如何使用 while 循环将文件的内容读入两个单独的字符缓冲区?
【发布时间】:2021-04-09 06:06:44
【问题描述】:

首先,我试图在 C 中模拟“uniq”Linux 命令,只使用系统调用。我目前正在尝试做的是将文本文件中的行读入两个不同的字符缓冲区,即char *buffer1char *buffer2

这是我迄今为止尝试过的:

    char *buffer1 = malloc(MAX_LINE_LENGTH * sizeof(char));
    char *buffer2 = malloc(MAX_LINE_LENGTH * sizeof(char));

    // read the first line into buffer1 using read() sys call
    int i = 0;
    while (read(input_fd, &buffer1[i], 1) == 1) 
    {
        if (buffer1[i] == '\n')
        {
            buffer1[i] = '\0';
            write(output_fd, buffer1, i);
            break;
        } 
        else
        {
            i++;

            if (i > MAX_LINE_LENGTH)
            {
                perror("ERROR: Line is longer than the allocated buffer.\n");
                exit(EXIT_FAILURE);
            }
        }
    }

    // read the second line into buffer2
    int j = 0;
    char *temp_ptr;
    while(read(input_fd, &buffer2[j], 1) == 1)
    {
        if (buffer2[j] == '\n')
        {
            buffer2[j] = '\0';

            while (buffer2 != NULL)
            {
                if (strcmp(buffer1, buffer2) != 0)
                {
                    write(output_fd, buffer2, j);
                }

                j = 0;
               // after this if-statement, read in another line of text and compare it
               // to the string in buffer2 
                temp_ptr = buffer2;

                if (temp_ptr == buffer2) 
                {
                    temp_ptr = buffer1;
                }
                else
                {
                    temp_ptr = buffer2;
                }
            }
        
        }
        else
        {
            j++;

            if (j > MAX_LINE_LENGTH)
            {
                perror("ERROR: Line is longer than the allocated buffer.\n");
                exit(EXIT_FAILURE);
            }
        }
    }

这可以只使用一个while循环来完成吗?再一次,我想强调一个事实,我只能使用系统调用。非常感谢任何帮助!

【问题讨论】:

  • i++; 之前为什么不是buffer2[i] = buffer1[i];?和buffer2[i] = '\0'; 关注buffer1[i] = '\0';??或者只填写buffer1,然后填写memcpy (buffer2, buffer1, i * sizeof *buffer1);(需要string.h,这样不符合约束条件,但第一种方法可以。)
  • @DavidC.Rankin while 循环条件是什么样的?您能否详细说明buffer2[i] = buffer1[i] 应该做什么?对于您的第二个建议,您是说我应该将文件的所有行读入 buffer1 吗?
  • 不要更改任何内容,只需在i++; 上方添加buffer2[i] = buffer1[i];,然后在buffer1[i] = '\0'; 之后立即添加buffer2[i] = '\0';。然后buffer1buffer2 在第一个while() 循环退出后将保持完全相同的内容。 (仔细检查您的i++; 是否在正确的位置...
  • 用块读取代替单字符读取效率更高(即读取整个缓冲区,然后在内存中工作)
  • @tofro 那么你的意思是我应该只创建一个while循环,将整个文件读入一个缓冲区,然后将每一行添加到适当的缓冲区中?如何一次读取多个字节?是不是类似于:read(fd, &buffer, 20)?

标签: c system-calls uniq


【解决方案1】:

我想通了:

// read the first line into buffer1 using read() sys call
    int i = 0;
    
    while (read(input_fd, &buffer1[i], 1) != 0) 
    {
        if (buffer1[i] == '\n')
        {
            buffer1[i] = '\0';
            write(output_fd, buffer1, i);
            
            i = 0;
            break;
        } 
        else
        {
            i++;
            if (i > MAX_LINE_LENGTH)
            {
                perror("ERROR: Line is longer than the allocated buffer.\n");
                exit(EXIT_FAILURE);
            }
        }
    }

    int j = 0;
    ssize_t nr;
    while (read(input_fd, &buffer2[j], 1) != 0)
    {
        if (buffer2[j] == '\n')
        {
            buffer2[j] = '\0';
            if (strcmp(buffer1, buffer2) != 0)
            {
                write(output_fd, buffer2, j);
                if (nr == -1) {
                    perror("ERROR.\n");
                }
            }
            
            j = 0;
            char *current_ptr = buffer2;
            if (current_ptr == buffer2)
            {
                current_ptr = buffer1;
            } 
            else
            {
                current_ptr = buffer2;
            }
        }
        else
        {
            j++;
            if (j > MAX_LINE_LENGTH)
            {
                perror("ERROR: Line is longer than the allocated buffer.\n");
                exit(EXIT_FAILURE);
            }
        }
    }

【讨论】:

  • 这个答案仍然无法检查 I/O 错误事件
猜你喜欢
  • 1970-01-01
  • 2021-09-26
  • 1970-01-01
  • 2015-01-19
  • 1970-01-01
  • 2012-12-09
  • 2014-01-06
  • 1970-01-01
  • 2015-08-20
相关资源
最近更新 更多