【发布时间】:2023-08-03 15:33:02
【问题描述】:
我正在使用 C++ 中的 ofstream 写入文件。每行都必须有一个相对时间、一个逗号和我正在写的值。这些值是std::vector<unsigned char>,以便写入我想要的任何值并以另一种方法读回。我的测试是写 3 个值。第一个值最后连接到一个奇怪的字节,即使我使用\0 或\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 << '\0' << '\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), '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', ... }
【问题讨论】:
-
data显然是一个非空终止的字符串,outFile << duration << SEPARATOR << data << '\0' << '\n';不是你如何去写一个空终止的字符串到输出流。您显然认识到data必须以 null 结尾,以便正确地编写为 C 样式字符串,但这不是您这样做的方式。您必须将'\0'附加到data本身,然后只写data。