我正在使用C ++中的ofstream
写入文件。每行必须有一个相对时间,一个逗号和我要写的值。值是std::vector<unsigned char>
,以便写入所需的任何值并以其他方法回读。我的测试是写3个值。即使我使用\0
或\n
,第一个值最后也会连接到一个奇怪的字节。但是其他两个值都可以。
这是输出文件:
0,BAC�
1000,DEF
2000,GHI
第二个问题是当我读取值时。我不知道如何动态地设置一个数组,使其仅读取写在该行上的值,并与我之前编写的上一个char向量进行比较。
头文件:
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', ... }
答案 0 :(得分:4)
问题是以null结尾的字符串。
char *data = reinterpret_cast<char *>(value.data());
outFile << duration << SEPARATOR << data << '\0' << '\n';
一个char *的契约本身以\0
结尾(要知道要写多少个字符,strlen会查找第一个可用的\0
)。就您而言,事实并非如此。您应该使用真实的字符串,或者至少使用:
outFile << duration << SEPARATOR << std::string(data, data+3) << '\n';
在此指令上添加\0
不会使字符串被魔术终止。您必须保持大小。
(read具有相同的缺陷)。
答案 1 :(得分:0)
我更改了write方法,不将向量转换为char数组,之后我只是push_back
\0
字符。
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('\0');
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;
}