好的,让我们一步一步来:
但它正在创建一个空文件
那是因为你正在清空文件
std::fstream::trunc - 删除文件中的所有内容(截断它)
这意味着当您打开 data.data 文件时,您会删除其中的所有数据(如果有的话)。
'std::fstream' 中有两种标准格式:
-
格式是std::ios::binary 格式,data.data 不能用文本编辑器读取,但它紧凑且高效。是的
-
format 将字符串存储为可打印字符。
在这种情况下,data.data 就像带有通用文件编辑器的 txt 文件一样可读。
由于@Andreas H. 提供了一个二进制文件格式示例并且您没有使用二进制格式,因此我提供了一个最小的可执行示例,该示例使用可打印字符存储您的数据。
-
int main(int argc, char *argv[]) 需要 [ ]-括号才能正常工作
-
旧 c 风格 (char*)&this->db; 的类型转换工作正常,Scott Meyers 在“Effective C++”中写道,应该避免旧 c 风格,因为旧 c 类型转换不是类型安全的并且“隐藏”在代码所以不容易找到像static_cast<char*>(...)
在这里您可以看到不同之处 - 两者都在做同样的事情:
int firstNumber = 1, secondNumber = 2;
double result1 = ((double)firstNumber) /secondNumber;
double result2 = static_cast<double>(firstNumber)/secondNumber;
std::cout << result1 << std::endl;
std::cout << result2 << std::endl;
为了提供一个最小的可执行示例和
更好的理解我跳过了这门课;)
应该很容易让您在一个漂亮的界面中解析它。
#include <iostream>
#include <map>
#include <fstream>
#include <string>
int main(int argc, char *argv[])
{
std::map<std::string, std::string> db{{"Key1","value"},{"Key2","value"}};
std::fstream mydata;
//PRINT MAP
for(const auto &[k,v] : db)
std::cout << k << " " << v << std::endl;
//WRITE MAP TO FILE
//Open File in write mode
mydata.open("data.data", std::ios::out);
if(!mydata.is_open())
std::cout << "Could not open file!" << std::endl;
//Write data to file
for(const auto &[k,v] : db)
mydata << k <<" " << v << std::endl;
//Close file
mydata.close();
//proof of concept, DESTROY MAP VALUES
db.clear();
//READ MAP BACK IN FROM FILE
std::string key , value;
//Open Data in read mode
mydata.open("data.data", std::ios::in);
if(!mydata.is_open())
std::cout << "Could not open file!" << std::endl;
//Read data back to map
while(mydata >> key >> value)
db[key] = value;
//Close File again
mydata.close();
//PRINT MAP
for(const auto &[k,v] : db){
std::cout << k << " " << v << std::endl;
}
return 0;
}
我希望这会帮助你完成你的项目:)
顺便说一句。如果您有多个单词作为键或值,则可以使用带分隔符的 getline,并将数据文件存储为 csv 格式(逗号分隔值文件),以便轻松导入数据 f.e.如果您将联系人数据存储在数据库中,则在电子邮件软件中。
作为一个练习,我写了一个最小的可执行示例,将二进制格式的字符串映射写入文件:
#include <iostream>
#include <fstream>
#include <map>
#include <string>
#define FILENAME "BinaryMap.bin"
int main()
{
std::fstream file;
std::string key{"Key One"}, value{"Value One"};
std::map<std::string, std::string> map{{key,value},{"Key Two","Value Two"}};
//Print Map
for(const auto &[key,value] : map){
std::cout << key << " " << value << '\n';
}
//Open file and check for errors
file.open(FILENAME, std::ios::binary | std::ios::out);
if(!file.is_open())
std::cout << "Could not open file!" << '\n';
//Position write cursor to the beginning of the file
file.seekp(0);
//Write the number of entries
size_t entries = map.size();
file.write(reinterpret_cast<const char*>(&entries), sizeof(entries));
//Write the number of entries
for(auto& it : map){
//Write the lenth of the key string to the file
size_t len = it.first.size();
file.write(reinterpret_cast<char*>(&len), sizeof(len));
//Write the string itself to the file
file.write(it.first.data(), it.first.size());
//Write the length of the value string to the file
len = it.second.size();
file.write(reinterpret_cast<char*>(&len), sizeof(len));
//Write the value string itself to the file
file.write(it.second.data(), it.second.size());
}
//Close the file
file.close();
map.clear();
std::cout << "--------clear---------" << '\n';
//READ STUFF
file.open(FILENAME, std::ios::binary | std::ios::in);
if(!file.is_open())
std::cout << "Could not open file!" << '\n';
// Position read cursor to the beginning
file.seekg(0);
// read the number of entries
entries = 0;
file.read(reinterpret_cast<char*>(&entries), sizeof(entries));
//Read the length of the string stored in the file
size_t length {};
for(size_t i = 0; i < entries; ++i){
//Read the length of the string in the file
if(file.read(reinterpret_cast<char*>(&length), sizeof(length)).fail())
std::cout << "Failed to read bin" << '\n';
//Pointer to variable address
std::string* p_target = &key;
//Preallocate memory for the string
p_target->resize(length);
//Read string from file
file.read(&p_target->front(), p_target->size()).good();
//Read the length of the string in the file
if(file.read(reinterpret_cast<char*>(&length), sizeof(length)).fail())
std::cout << "Failed to read bin" << '\n';
//Dereference value
key = *p_target;
//Assign variable address to pointer
p_target = &value;
//Preallocate memory for the string
p_target->resize(length);
//Read string from file
file.read(&p_target->front(), p_target->size()).good();
//Dereference value
value = *p_target;
//Write key and value to map
map[key] = value;
}
//Close the file
file.close();
for(const auto &[key,value] : map){
std::cout << key << " " << value << '\n';
}
std::cout << "Hit 'return' to continue";
std::cin.get();
return 0;
}