0

データベースを作成しようとしていますが、これまでのところ、文字列を使用してエントリをテキスト ファイルから配列に格納してきましたが、うまくいきません。そこで、新しい方法を考え始めました。

私がしたいこと:

次のデータベースを含むテキストファイルがあるとしましょう...

ジョン・スミス 00001 jsmith@email pw1

ロブ・デニロ 00002 rdeniro@email pw2

アル・パチーノ 00003 apacino@email pw3

ジョー・ペシ 00004 jpesci@email 307 pw4

ジョアック・フェニックス 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の API は非常に簡単なので、SQLiteをコードベースに組み込むのに 1 時間以上かかることはありません。

#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
 #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 に答える
0

で一度に 1 行ずつ読み取り、ifstreamを使用strtokして各行を分割し、空白を区切り文字として使用します。大きな値をサポートする必要がある場合は、またはstringとして保存できる数値以外を使用する必要があります。また、セキュリティが必要な場合は、パスワードを暗号化して保存することをお勧めします。intlong

スペース、パフォーマンス、セキュリティなど、さまざまな理由から、プレーン テキストの代わりにデータを保存する別のソリューションを探すことをお勧めします。バイナリ データベース ファイルを使用することをお勧めします。

于 2008-12-19T03:07:28.077 に答える