我正在尝试创建一个数据库,到目前为止,我一直在使用字符串将我的条目从文本文件存储到数组中,但这只是没有用。因此,我开始考虑一种新的方式。
我想做什么:
假设我有一个包含以下数据库的文本文件......
John Smith 00001 jsmith @ email pw1
Rob Deniro 00002 rdeniro @ email pw2
Al Pacino 00003 apacino @ email pw3
Joe Pesci 00004 jpesci @ email 307 pw4
Joaq Phoenix 00005 jphoe @ email 208 pw5
John Madden 00006 jmadden @ email 708 pw6
好吧,基本上我坚持的是让这个“继承”友好。存储每个条目的最佳方法是什么?个别字符串?我一直在想最好的方法是存储每个单独的字符,直到出现空格,然后将其存储到字符串中,但我不确定如何做到这一点。
答案 0 :(得分:3)
正如TomWij所说,你做ifstream然后strtok,但我建议你用“”而不仅仅是空格来逃避你的字符串,这样你可以存储“像这样的东西,例如关于用户的注释”,这是如何用CSV(逗号分隔值)完成。
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;
void readCSV(std::istream &input, std::vector< std::vector<std::string> > &output)
{
std::string csvLine;
// read every line from the stream
while( std::getline(input, csvLine) )
{
std::istringstream csvStream(csvLine);
std::vector<std::string> csvColumn;
std::string csvElement;
// read every element from the line that is seperated by commas
// and put it into the vector or strings
while( std::getline(csvStream, csvElement, ',') )
{
csvColumn.push_back(csvElement);
}
output.push_back(csvColumn);
}
}
int main()
{
std::fstream file("file.csv", ios::in);
if(!file.is_open())
{
std::cout << "File not found!\n";
return 1;
}
// typedef to save typing for the following object
typedef std::vector< std::vector<std::string> > csvVector;
csvVector csvData;
readCSV(file, csvData);
// print out read data to prove reading worked
for(csvVector::iterator i = csvData.begin(); i != csvData.end(); ++i)
{
for(std::vector<std::string>::iterator j = i->begin(); j != i->end(); ++j)
{
std::cout << *j << ", ";
}
std::cout << "\n";
}
}
这让我想到了真正的解决方案,为什么不使用像 CSV module 这样的CSV库,或者更好,SQLite,SQLite很容易安装和使用,而且它更好用而不是手工编写数据库,除了它不应该花费你超过1小时的时间才能获得SQLite代码库,因为它的API非常简单。
#include <stdio.h>
#include <sqlite3.h>
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
int i;
for(i=0; i<argc; i++){
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main(int argc, char **argv){
sqlite3 *db;
char *zErrMsg = 0;
int rc;
if( argc!=3 ){
fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
exit(1);
}
rc = sqlite3_open(argv[1], &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);
if( rc!=SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
sqlite3_close(db);
return 0;
}
答案 1 :(得分:1)
答案 2 :(得分:0)
使用ifstream
一次读取一行,然后使用strtok
拆分每一行,使用空格作为分隔符。除了数值之外,您应该使用string
,如果需要支持大值,可以将其保存为int
或long
。如果您想要安全性,以加密方式存储密码也更为明智。
您可能希望寻找另一种解决方案来存储您的数据而不是纯文本,原因有多种:空间,性能,安全性......尝试使用二进制数据库文件可能是个好主意。
答案 3 :(得分:0)
#include<iostream>
#include<conio.h>
#include<fstream>
using namespace std;
int main(int argc, char *argv[])
{
char Name[100];
char FTE[100];
cout<<"What is the file name?\n";
cin>>FTE;
ifstream myfile (FTE);
while(1)
{
myfile.getline(Name, 30, '|');
cout<<line;
cin.ignore();
}
}
所有这一切都是读取由“|”分隔的所有文本条目字符。适合在C ++中使用相同的方法制作平面文件数据库。