带分隔符的C++文件读取

标签 c++ ifstream getline

姓名~专名~HR编号~HD编号~距离-文件中数据的格式

include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main()
{
  string name;
  string properName;
  string hrN;
  string hdN;
  double distance;
  ifstream fin;
  string fileName;
  cout << "Enter a file name: ";
  getline(cin, fileName);
  fin.open(fileName);
  if(fin.fail())
  {
     cout << "Unable to open the file" << endl;
     return -1;
  }
  else
  {
    string name;
    string properName;
    string hrN;
    string hdN;
    double distance;
    string line;
    string pN1;
    bool found = false;
    while(true)
    {
       getline(fin, name, '~');
       getline(fin, properName,'~');
       getline(fin, hrN,'~');
       getline(fin, hdN, '~');
       fin >> distance;
       cout << "Enter a proper star name:";
       string pN1;
       cin >> pN1;
       if(pN1.compare(properName))
       {
          found = true;
          cout << "Star : "<< "proper name: "<<pN1<< "distance: "<<distance<<"light years" << "HD num: "<<hdN << "HR num: "<< hrN << "common name: "<< name << endl;

       }

   }

   if (found == false)
   {
      cout << "No star with the properName"<<" "<< pN1 <<" "<<"was found"<< endl;
   }
  fin.close();
}

 return 0;

这就是我目前所得到的。 我只是不确定如何存储变量,以便搜索变量并将特定行的内容显示到屏幕上

最佳答案

您的代码有很多错误。您出于某种原因重复了变量名称,您的输入循环永远不会终止,并且您已经询问了有关输入循环内的星名的问题。我会说你是在没有考虑你在做什么或不知道你要去哪里的情况下匆忙编码。

让我们一次拿一件。

您首先拥有的是一堆有关星星、名称、专有名称、距离等的相关数据。因此,让我们通过将相关数据分组到结构中来表达这一事实

struct StarData
{
    string name;
    string properName;
    string hrN;
    string hdN;
    double distance;
};

现在让我们编写一个循环来读取该数据,重要的是在没有更多数据时结束

StarData data;
// loop until no more data
while (getline(fin, data.name, '~') && getline(fin, data.properName, '~') && 
    getline(fin, data.hrN, '~') && getline(fin, data.hdN, '~') && 
    (fin >> data.distance))
{
}

所以这个循环读取星星数据,一次一颗星星到 data 变量中。但目前还没有对这些数据做任何事情。

有多种方法可以存储数据以供搜索,这是很常见的事情,因此 C++ 为您完成了大部分工作。我将使用一种称为 std::map 的数据结构,它非常适合存储数据以便进行搜索。让我们修改上面的循环

#include <map>

std::map<string, StarData> star_database;
StarData data;
// loop until no more data
while (getline(fin, data.name, '~') && getline(fin, data.properName, '~') && 
    getline(fin, data.hrN, '~') && getline(fin, data.hdN, '~') && 
    (fin >> data.distance))
{
    // add star data to database using proper name as the key
    star_database[data.properName] = data;
}

此代码将星星数据存储在名为 star_database 的变量中。特别是因为我们键控 map 上的专有名称,即因为我们说 star_database[data.properName] = data; 稍后我们将能够使用专有名称查找有关该星的数据。

现在我们已经完成了 while 循环,让我们问关于要查找的星星的问题,记住这是在上面的 while 循环之后发生的,而不是在它内部。

cout << "Enter a proper star name:";
string pN1;
cin >> pN1;

现在我们将进行查找

auto answer = star_database.find(pN1); // lookup the proper name in the database
if (answer == star_database.end()) // did we find it?
{
    cout << "No star with the proper name "<< pN1 <<" was found"<< endl;
}
else
{
    cout << "Star : "<< "proper name: "<< pN1 << 
        " distance: "<< answer->second.distance << " light years" << 
        " HD num: "<< answer->second.hdN << 
        " HR num: "<< answer->second.hrN << 
        " common name: "<< answer->second.name << endl;
}

我已经跳过了相当多的细节(我只能解释这么多),但希望您已经掌握了基本概念并可以自己研究其余部分。

所有代码未经测试,如有错别字,敬请谅解。

关于带分隔符的C++文件读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52024083/

相关文章:

C++ 流对象线程安全吗?

c++ - getline() 函数的问题

c++ - 程序跳过 Getline() 而不接受用户输入

C++ 11 : overload resolution and SFINAE

c++ - 在LLVM中获取全局字符串值

c++ - 如何验证自签名证书?

C++ ifstream 失败,为什么这条线没有到达它应该去的地方?

c++ - 通过 BCD 创建大数 - C++

c++ - 逐行散列文件时错误的 md5 散列值

c - 使用 sscanf 迭代