我正在尝试创建一个系统,如果数据不存在,它允许我将数据写入txt文件。由于某种原因,它不适用于现有数据,我似乎无法理解为什么。将数据写入文件没有问题,但看不到现有数据。这是代码:
#include <iostream>
#include <fstream>
using namespace std;
int main(void){
bool foundname = false;
ifstream file("names-genders.txt");
string name, surname, gender,checkbuffer;
cout << "Name, surname: ";
cin >> name >> surname;
while (getline(file,checkbuffer)){
if (checkbuffer.find(name) != string::npos){
gender = checkbuffer.substr(checkbuffer.find_last_of(' ')+1);
foundname = true;
}
}
if (not(foundname)){
{
file.close();
ofstream file("names-genders.txt",ios::app);
cout << "Name not found in database. Please enter the gender by hand: ";
cin >> gender;
file << "\n"+ name + " " + gender;
}
}
file.close();
//there is more code here, but it is not related to the issue
cout << "Hi";
}
“names-genders.txt”是与项目位于同一文件夹中的文件,它包含两行: 亚历山大男 费多男
在第三次启动时输入“Fedor”后,它会给我“未找到名称......”输出,并添加带有输入数据的第三行。
此外,这部分之后的所有代码都不起作用,似乎编译器在它之后看不到任何内容或类似的东西
尝试重写多次,但似乎没有任何效果。很可能我没有看到或不知道一些重要的事情,这会阻止它工作。当找到套装项目时添加“break”也没有给出任何结果。 为了进行测试,我删除了这部分之后的所有代码,并在输出中添加了一个无用的“Hi”,但由于某种原因,代码在输入数据后完成了工作,并且不输出“Hi”
您基本上正在实现一个简单的数据库,但是您可以使用一些数据库理论来使您的程序更好地运行。
数据库使用固定长度的记录来使读写变得更容易和更快。 例如,如果每条记录的宽度为 256 个字符,那么您的第三条记录从 (3-1) * 256 开始。{-1 是因为第一条记录位于 0。}您可以使用块读取和写入,因为您知道记录长度,例如
istream::read()
。
您应该使用其他字符(例如“;”)来分隔列。 这允许您使用
std::getline(my_file, my_text, ';')
读取分号之前的所有内容(包括空格)。 每个文本行使用一条记录比每行重复列更有优势。
您基本上使用的是CSV格式,即使用分隔符来分隔列。 在互联网上搜索“C++ CSV 示例”或“C++ CSV 库”。 您可以使用许多库,并且有大量现有示例供您比较。
您可能还想研究其他人类可读的格式:XML、JSON、INI。 他们都有库和示例来帮助您。
许多关系数据库使用两个表来存储数据。 第一个表包含所有未排序的记录。 第二个表是按键列(字段)排序的 index 表。 在 C++ 中,您可以使用类似
std::map<key-type, unsigned-int>
的内容。 unsigned-int
字段将是第一个表的索引。 索引表允许您开发不同的排序参数,而无需更改第一个表。
您可能需要考虑使用实际的数据库。 数据库有很多,从小型到大型,从免费到付费。 如果这是一个严肃的应用程序,请考虑使用现有的数据库或电子表格。