fread() 和 fwrite() 使用字符串

问题描述 投票:0回答:2

我正在尝试使用字符串实现简单的

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
的值,这是我做错的地方。

c++ segmentation-fault fread
2个回答
3
投票

如果你想访问 std::string 中的实际字符缓冲区,你需要使用

value.c_str()

字符串的长度不是sizeof给定的,使用

value.length()

您不能使用

std::string
从文件直接读入
fread
。您必须将其读入中间
char []
缓冲区并从那里加载。或者使用
ifstream


2
投票

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);
}
© www.soinside.com 2019 - 2024. All rights reserved.