【问题标题】:Count lines of a file using file descriptor in C使用C中的文件描述符计算文件的行数
【发布时间】:2019-01-17 14:58:35
【问题描述】:

我正在尝试通过文件描述符计算我正在读取的文件的行数,但我不知道我做错了什么,因为它不起作用。

这是代码:

fd_openedFile = open(filename, O_RDONLY)        
char *miniBuffer[1];
int lineCounter = 0;
while( read(fd_openedFile, miniBuffer, 1) >0) {
    if (*miniBuffer[0] == '\n')
        lineCounter++;
}

该软件从不进入“如果”,我已经测试了很多我认为可以工作的变体,但它们都没有工作(这只是对我来说更有意义的一个)。

我们将不胜感激。

非常感谢!

我在下面添加了完整的代码:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

void err_sys(const char* cadena, int continueExecuting) {
    perror(cadena);
    if (continueExecuting == 0)
        exit(1);
}

int main()
{
    //vars
    char filename[200];
    int fd_output = 1;
    int fd_openedFile = -1;
    int fd_newFile = -1;


    //Ask for the file and open it
    while (fd_openedFile < 0){
        write(fd_output, "Write the filename: ", 20);
        scanf("%s", filename);
        if ((fd_openedFile = open(filename, O_RDONLY)) < 0)
            err_sys("Error opening the original file", 1);
    }

    //Construct the new file's name
    char *partOfOldFilename = strtok(filename, ".");
    char newFileName[208], finalPart[8];
    strcpy(newFileName,  partOfOldFilename);
    strcpy(finalPart, "OUT.txt");
    strcat(newFileName, finalPart);

    //Create the new file
    if ((fd_newFile = open(newFileName, O_WRONLY | O_CREAT)) < 0)
        err_sys("Error opening the new file", 1);

    //Count the number of lines
    char miniBuffer[1];
    int lineCounter = 0;
    while( read(fd_openedFile, &miniBuffer[0], 1) >0) {
        write(fd_output, "R", 1); //To debug
        if (miniBuffer[0] == '\n') {
            lineCounter++;
            write(fd_output, "1", 1); //To debug
        } else {
            write(fd_output, "0", 1); //To debug
            write(fd_output, miniBuffer, 1); //To debug
        }
    }

    lseek(fd_openedFile,0,SEEK_SET);
    write(fd_output, "=========\n", 10); //To debug


    //Count the number of chars per line
    char* charsPerLine[lineCounter];
    lineCounter = 0;
    int charCounter = 0;
    while( read(fd_openedFile, miniBuffer, 1) >0){
        write(fd_output, "C", 1); //To debug
        if (miniBuffer[0] == '\n') {
            *(charsPerLine[lineCounter]) = charCounter +'0';
            lineCounter++;
            charCounter = 0;
            write(fd_output, "1", 1); //To debug
        } else {
            write(fd_output, "0", 1); //To debug
            write(fd_output, miniBuffer, 1); //To debug
            charCounter ++;
        }
    }
    lseek(fd_openedFile,0,SEEK_SET);
    write(fd_output, "END", 4); //To debug

    //Write a copy of the original file starting each line with the number of chars in it
    lineCounter = 0;
    int bufSize = 1;
    char buffer[bufSize];
    //First number write
    if (write(fd_newFile,charsPerLine[lineCounter], bufSize)!=bufSize)
        err_sys("write_error", 0);
    lineCounter++;
    while( read(fd_openedFile, buffer, bufSize) >0){
        if (write(fd_newFile,buffer, bufSize)!=bufSize)
            err_sys("write_error", 0);
        if (buffer[0] == '\n') {
            if (write(fd_newFile,charsPerLine[lineCounter], bufSize)!=bufSize)
                err_sys("write_error", 0);
            lineCounter++;
        }
    }

    //Finish program
    if (close(fd_openedFile)!=0) err_sys("error closing original file's file descriptor", 0);
    if (close(fd_newFile)!=0) err_sys("error closing new file's file descriptor", 0);
    return 0;
}

此代码假定文件是一个 .txt 文件,并且在每一行的末尾都有一个“断行”并且它目前正在开发中。

再次感谢。

【问题讨论】:

  • Guillem Poy,好奇:如果一个文件只包含 7 个字节 "abc\nxyz"(它不以 '\n' 结尾),你算作 1 行文件还是 2 行文件?跨度>
  • 我打算稍后添加一些东西来处理它。首先,我想计算断线。在它之后,我会计算如果在断行之后还有另一个字符并且文件完成了,那么将计算另一行。

标签: c file newline file-descriptor


【解决方案1】:

您没有为miniBuffer 分配任何内存,它是char 指针数组。这不是真正的问题 - 问题在于它首先不应该是 char 指针数组。您只需要它是一个 char 数组,如下所示。

char miniBuffer[1];

然后另一个更改是检查数组的单个元素是否为\n 字符。

if (miniBuffer[0] == '\n')

您可能会发现通过增加数组的大小并使用 strchr 之类的函数在字符串中查找任何 \n 来读取更大的块会更有效。您需要存储 read 返回的金额,以便您可以正确地 NUL 终止字符串。

【讨论】:

  • 但是,如果我这样做,“读取”似乎会返回错误并且只计算一行。我有这样的代码:i.imgur.com/CImULGi.png 所有“写”方法都用于调试标准输出上的打印。问题是它只打印一个“R1”(这意味着读取一个字符并认为这是一个新行)但仅此而已。没有打印任何其他内容。
  • 我只能纠正您在答案中显示的代码中的错误。听起来您没有显示的代码还有其他问题,因为我建议的更改应该可以正常工作
  • 我已经在原始问题中添加了代码。我已经修改了几个小时和多次,但我无法弄清楚为什么会发生这种情况。是我在 C 中的第一个项目,所以也许我做的很多事情都非常错误......(我正在通过 ubuntu shell gcc 执行和编译它,我不知道它是否相关)
  • 你做错的主要事情是你试图一口气写完整个东西——你应该把项目分成更小的部分。在处理下一个之前先让一个部分工作。因此,在尝试计算每行中有多少字符的代码之前,请编写一些代码来计算文件中的行数并让它工作。还可以了解printf 的作用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-08
  • 1970-01-01
  • 1970-01-01
  • 2017-02-12
  • 1970-01-01
  • 2018-08-15
相关资源
最近更新 更多