0

我正在尝试创建一个数据库,到目前为止,我一直在使用字符串将我的条目从一个文本文件存储到一个数组中,但这只是行不通。于是,我开始思考一种新的做法。

我想做的事:

假设我有一个包含以下数据库的文本文件......

约翰·史密斯 00001 jsmith@email pw1

Rob Deniro 00002 rdeniro@email pw2

阿尔·帕西诺 00003 apacino@email pw3

乔·佩西 00004 jpesci@email 307 pw4

Joaq Phoenix 00005 jphoe@email 208 pw5

约翰·马登 00006 jmadden@email 708 pw6

好吧,所以基本上我所坚持的就是让这种“继承”变得友好。存储每个条目的最佳方法是什么?单个字符串?我一直认为最好的方法是存储每个单独的字符,直到出现空格,然后将其存储到一个字符串中,但我不确定如何做到这一点。

4

4 回答 4

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 模块或更好的 CSV 库,SQLite,SQLite 非常易于安装和使用,而且它比手动编写数据库更好,除了它应该将SQLite加入您的代码库不会花费您超过 1 小时,因为它的 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;
}
于 2008-12-19T03:18:26.057 回答
1

通常,术语“数据库”保留为关系数据库的标准概念,例如 MySQL、MS SQL Server、Oracle 等

所以这引出了一个问题,为什么不使用标准的关系数据库?

您可能想尝试查找TinySQL

于 2008-12-19T03:16:25.687 回答
0

一次读取一行,ifstream然后使用strtok分割每一行,使用空格作为分隔符。您应该使用stringexcept 数值,如果您需要支持大值,您可以将其保存为 anint或 a 。long如果您想要安全,以加密方式存储密码也是更明智的做法。

出于各种原因,您可能希望寻找另一种解决方案来存储数据而不是纯文本:空间、性能、安全性……尝试使用二进制数据库文件可能是个好主意。

于 2008-12-19T03:07:28.077 回答
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++ 和其他使用相同方法的情况下制作平面文件数据库。

于 2010-01-21T21:27:55.590 回答