简体   繁体   English

C语言中的Unix HEAD命令实现在较大行上失败

[英]Unix HEAD command implementation in C fails on larger lines

I am currently implementing the Unix HEAD command with C and using only system functions. 我目前正在用C实现Unix HEAD命令,并且仅使用系统功能。 So far, it works perfectly on files, which have lines with less length than the one that I specified for my buffer : 到目前为止,它完美的作品上的文件,它有比我为我指定的长度小于buffer

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define LINES_TO_READ 10
#define BUFF_SIZE 4096

int main(int argc, char const *argv[]) {
    for (ssize_t i = 1; i < argc; i++) {
        const char *filename = argv[i];

        int fd = open(filename, O_RDONLY);

        if (fd < 0) {
            perror("open");
            return -1;
        }

        char ch, buffer[BUFF_SIZE];
        size_t index = 0, lines = 1;
        ssize_t rresult, wresult;

        // Read the file byte by byte
        while ((rresult = read(fd, &ch, 1)) != 0) {
            if (rresult < 0) {
                perror("read");
                return -1;
            }

            // Check if the current character is a new line (the line ends here)
            if (ch == '\n') {
                buffer[index] = ch;
                buffer[index + 1] = '\0';
                ch = 0;
                index = 0;

                // Print the line
                wresult = 0;
                ssize_t buffer_length = strlen(buffer);
                while (wresult != buffer_length) {
                    ssize_t res = write(STDOUT_FILENO, buffer + wresult, buffer_length - wresult);

                    if (wresult < 0) {
                        perror("write");
                        return -1;
                    }

                    wresult += res;
                }

                // Stop if we read 10 lines already
                if (lines == LINES_TO_READ) {
                    break;
                }

                lines++;
            } else {
                buffer[index++] = ch;
            }
        }

        if (close(fd) < 0) {
            perror("close");
            return -1;
        }
    }

    return 0;
}

And it works on files, which have a line length with less than BUFF_SIZE (as now set, 4096 ). 它适用于BUFF_SIZE小于BUFF_SIZE (现在设置为4096 )的文件。

How to avoid this and make it work for whatever the line length is? 如何避免这种情况并使之适用于任何线长?

Don't read one byte at a time. 不要一次读取一个字节。 Read a chunk (4096 or 8192 bytes are reasonable sizes, or use PIPE_BUF (from limits.h)) into a buffer. 将一个块(4096或8192字节是合理的大小,或使用PIPE_BUF(来自limits.h))读取到缓冲区中。 Output each character while counting newlines. 在计算换行符时输出每个字符。 If you print enough newlines, terminate. 如果您打印足够的换行符,请终止。 If you reach the end of the buffer and haven't printed enough lines, read more data into the buffer. 如果到达缓冲区的末端并且没有打印足够的行,请向缓冲区中读取更多数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM