我正在尝试使用字符串实现简单的
fread()
和 frwite()
示例。该程序给我segfault
或free(): invalid pointer
错误。下面是我正在使用的示例代码。
#include <fstream>
#include <iostream>
static bool file_read(FILE* file) {
std::string value="abcd";
std::string retrieved;
size_t read, write;
write = fwrite(&value, sizeof(value), 1, file);
fseek(file, 0, SEEK_SET);
read = fread(&retrieved, sizeof(value), 1, file);
return true;
}
int main(int argc, char *argv[]) {
FILE *file = NULL;
file = fopen("file_test", "wb+");
file_read(file);
fclose(file);
}
我检查了
file
是否正确打开并且retrieved
与value
的值相同。我不认为我在我的代码中释放任何变量。我怀疑是fread
造成了所有麻烦。
fread(&retrieved[0], sizeof(char), 4, file)
没有读到
retrieved
的值,这是我做错的地方。
如果你想访问 std::string 中的实际字符缓冲区,你需要使用
value.c_str()
字符串的长度不是sizeof给定的,使用
value.length()
您不能使用
std::string
从文件直接读入 fread
。您必须将其读入中间 char []
缓冲区并从那里加载。或者使用ifstream
std::string
不是平凡的类型。它包含几个私有数据成员,包括一个指向字符数据的指针,该数据可能驻留在字符串对象之外的内存中。所以你不能读/写字符串对象本身的原始字节,就像你试图做的那样。您需要单独序列化它的字符数据,例如:
#include <fstream>
#include <iostream>
#include <string>
#include <cstdio>
static bool file_writeStr(std::FILE* file, const std::string &value) {
size_t len = value.size();
bool res = (std::fwrite(reinterpret_cast<char*>(&len), sizeof(len), 1, file) == 1);
if (res) res = (std::fwrite(value.c_str(), len, 1, file) == 1);
return res;
}
static bool file_readStr(std::FILE* file, std::string &value) {
size_t len;
value.clear();
bool res = (std::fread(reinterpret_cast<char*>(&len), sizeof(len), 1, file) == 1);
if (res && len > 0) {
value.resize(len);
res = (std::fread(&value[0], len, 1, file) == 1);
}
return res;
}
static bool file_test(std::FILE* file) {
std::string value = "abcd";
std::string retrieved;
bool res = file_writeStr(file, value);
if (res) {
std::fseek(file, 0, SEEK_SET);
res = file_readStr(file, retrieved);
}
return res;
}
int main() {
std::FILE *file = std::fopen("file_test", "wb+");
if (file_test(file))
std::cout << "success";
else
std::cerr << "failed";
std::fclose(file);
}