我用 C++ 编写的文件中有更多字符

I am having more characters in the file that I am writing in C++

我正在使用 C++ 中的 ofstream 写入文件。每行都必须有一个相对时间、一个逗号和我正在写的值。这些值是 std::vector<unsigned char> 以便写入我想要的任何值并以另一种方法读回。我的测试是写 3 个值。第一个值在末尾连接到一个奇怪的字节,即使我使用 [=17=]\n。但是其他2个值没问题。

这是输出文件:

0,BAC�
1000,DEF
2000,GHI

第二个问题是当我读取值时。我不知道如何动态设置一个数组来只读取写在行上的值并与我之前写的前一个字符向量进行比较。

头文件:

class SensorRecorder {
private:
    std::ofstream outFile;
    std::ifstream infile;
    std::string path;
    long duration = -1;
public:
    const std::string OUTPUT_DIR = "out";
    const std::string EXTENSION = ".out";
    const char SEPARATOR = ',';
    SensorRecorder(const char *classNameType);
    ~SensorRecorder();
    int write(std::vector<unsigned char> value);
    std::vector<unsigned char> read(long relativeTime);
    void close();
    std::string getFileName();
};

实施:

#include "utils/SensorRecorder.h"
#include "utils/DateTools.h"
#include <cstring>
#include <iostream>
#include <boost/filesystem.hpp>

SensorRecorder::SensorRecorder(const char *classNameType) {
    boost::filesystem::path full_path(boost::filesystem::current_path());
    full_path.append(OUTPUT_DIR, boost::filesystem::path::codecvt());
    if (boost::filesystem::create_directory(full_path)) {
        std::cout << "Directory Created: " << full_path << std::endl;
    }
    std::string fileName = classNameType + ((std::string) "-") + DateTools::getPlainDate() + EXTENSION;
    full_path.append(fileName, boost::filesystem::path::codecvt());
    path = full_path.c_str();
    outFile.open(path);
}
int SensorRecorder::write(std::vector<unsigned char> value) {
    if (outFile.is_open()) {
        char *data = reinterpret_cast<char *>(value.data());
        auto now = std::chrono::system_clock::now();
        auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
        auto value = now_ms.time_since_epoch();

        if (duration == -1) {
            duration = 0;
        } else {
            duration = value.count() - duration;
        }
        // write in the file
        outFile << duration << SEPARATOR << data << '[=12=]' << '\n';
        duration = value.count();
    } else {
        return 0;
    }
    return 1;
}
std::vector<unsigned char> SensorRecorder::read(long relativeTime) {
    infile.open(path);
    if (infile.is_open()) {
        std::cout << "Reading from the file" << std::endl;
        long duration;
        char comma;
        unsigned char data[300];

        while (infile >> duration >> comma >> data) {
            std::cout << "duration: " << duration << std::endl;
            std::cout << "data: " << data << std::endl;
            if (duration == relativeTime) {
                std::cout << "INSIDE " << std::endl;
                infile.close();

                // cast the value
                std::vector<unsigned char> outputValues(data, data + sizeof(data));
                return outputValues;
            }
        }
        infile.close();
    }
    return std::vector<unsigned char>();
}

我的测试:

TEST_F(SensorRecorderTest, TestWriteOnFile) {
    std::vector<unsigned char> inputValues01 = {'B', 'A', 'C'};
    std::vector<unsigned char> inputValues02 = {'D', 'E', 'F'};
    std::vector<unsigned char> inputValues03 = {'G', 'H', 'I'};
    mySensorRecorder = new SensorRecorder("SensorRecorderTest");

    // write on the file
    int ret = mySensorRecorder->write(inputValues01);
    ASSERT_EQ(ret, 1);

    std::this_thread::sleep_for(std::chrono::seconds(1));
    ret = mySensorRecorder->write(inputValues02);
    ASSERT_EQ(ret, 1);

    std::this_thread::sleep_for(std::chrono::seconds(2));
    ret = mySensorRecorder->write(inputValues03);
    ASSERT_EQ(ret, 1);

    mySensorRecorder->close();

    // read from the file
    std::vector<unsigned char> outputValues01 = mySensorRecorder->read(0);
    ASSERT_EQ(inputValues01, outputValues01);
}

错误:

Expected equality of these values:
  inputValues01
    Which is: { 'B' (66, 0x42), 'A' (65, 0x41), 'C' (67, 0x43) }
  outputValues01
    Which is: { 'B' (66, 0x42), 'A' (65, 0x41), 'C' (67, 0x43), '\xE4' (228), '\x16' (22), '\x7F' (127), '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', '[=14=]', ... }

问题是空终止字符串。

char *data = reinterpret_cast<char *>(value.data());
outFile << duration << SEPARATOR << data << '[=10=]' << '\n';

char* 本身的约定是它以 [=12=] 结尾(要知道要写入多少个字符,strlen 将查找第一个可用的 [=12=])。在你的情况下,它没有。你应该使用一个真正的字符串,或者至少使用:

outFile << duration << SEPARATOR << std::string(data, data+3) << '\n';

在此指令上添加 [=12=] 不会使字符串被魔法终止为 null。你必须保持尺寸。

(read有同样的缺陷)

我将写入方法更改为不将向量转换为字符数组,然后我只是 push_back [=12=] 字符。

int SensorRecorder::write(std::vector<unsigned char> value) {
    if (outFile.is_open()) {
        auto now = std::chrono::system_clock::now();
        auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
        auto v = now_ms.time_since_epoch();

        if (duration == -1) {
            duration = 0;
        } else {
            duration = v.count() - duration;
        }
        // write in the file
        value.push_back('[=10=]');

        std::cout << value.size() << " " << value.data() << std::endl;
        outFile << duration << SEPARATOR << value.data() << '\n';

        // evaluate duration time to the next write
        duration = v.count();
    } else {
        std::cerr << "error writing..." << std::endl;
        return 0;
    }
    return 1;
}