c++ - UNIX API 调用 : Using read() function to open and print a file to the screen adds extra random characters

标签 c++ unix

我正在尝试编写一个程序来使用 UNIX API 调用来比较两个文本文件。这是我的两个文件的内容:

f1.txt

This is my sample.
It contains text
And for some reason
The last few chars
are duplicated?

f2.txt

This is another sample
Sometimes instead of
duplicating the last few chars,
it prints another new line
instead
4567865

我有一个 cpp 文件可以打开并读取这些文件。我的 OpenRead 函数将文件名作为 c 字符串,并将文本文件的内容放入字符串中并返回它。

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



using namespace std;

string OpenRead(const char*);

int main(int argc, char **argv)
{
    string text1 = "", text2 = "";

    string file1(argv[1]);
    string file2(argv[2]);


    text1 = OpenRead(file1.c_str());
    text2 = OpenRead(file2.c_str());
    cout << text1 << endl;
    cout << text2 << endl;

    exit(EXIT_SUCCESS);


 return 0;
}



string OpenRead(const char* filename)
{
    int inFD1;
    string text;

    char * buf = new char[fsize(filename)];

    inFD1 = open(filename, O_RDONLY, 0);
    if(inFD1 < 0) exit(EXIT_FAILURE);
    else
    {
         while (read(inFD1, buf, sizeof(int)) != 0) 
            text += buf; //cout << buf;

    }   

    close(inFD1);
    delete [] buf;
    return text;
}

size_t fsize(const char *filename) {
    struct stat st; 

    if (stat(filename, &st) == 0)
        return st.st_size;

    return -1; 
}

问题是,当我将其编译成可执行文件并运行我的命令时: fileComp f1.txt f2.txt,它几乎完美地打开和读取它们,但产生奇怪的输出,其中额外的字符附加到末尾。输出如下所示:

This is my sample.
It contains text
And for some reason
The last few chars
are duplicated?
e
This is another sample
Sometimes instead of
duplicating the last few chars,
it prints another new line
instead
4567865
8

出于某种原因,它在第一个文件上附加了一个 e,在第二个文件上附加了一个 8。此行为因文本文件而异,但它总是将缓冲区中的随机字符附加到末尾。

最佳答案

我看到的主要问题是您没有检查读取结果以了解读取的字符数。

    while (read(inFD1, buf, sizeof(int)) != 0) 

您要求每次读取 sizeof(int) 字节。但它返回的可能少于此。所以你真的应该拥有那个值(value)。

此外,当向结果 text 添加缓冲区时,您假设缓冲区已经清零(因此您得到默认的空终止符“\0”)

        text += buf; //cout << buf;

注意 operator+= 假定 buf 是一个 C 字符串,因此以 null 终止。您没有为您的代码提供该保证。

int len;
while ((len = read(inFD1, buf, sizeof(int))) > 0) {
    text.append(buf, len); 
}

一旦你开始工作。带到https://codereview.stackexchange.com审查最佳做法。

关于c++ - UNIX API 调用 : Using read() function to open and print a file to the screen adds extra random characters,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49060035/

相关文章:

c++ - 为什么在输出字符数组到控制台时得到垃圾值?

c++ - 为什么取消引用多态指针将获得指针的类型而不是对象的类型?

linux - Rust 中的 Unix errno 常量在哪里?

linux - setjmp 和 longjmp - 通过示例理解

python - 按条件合并具有不同列信息的文件

c++ - 通过引用传递指针(插入二叉搜索树)

C++ - 检测死套接字

来自 php unix 时间戳的 javascript 日期

c++ - 如何在 C++ 对象中重现 Relax NG 规则?

c - 如何在 vim 中为 #include<stdio.h> 创建别名