从文件保存到字符串数组

Saving to an array of strings from file

本文关键字:字符串 数组 保存 文件      更新时间:2023-10-16

基本上,我想从文件中读取高分,并检查用户是否已经获得了足够的积分在计分板上。我试着这样做:

string initials[10];
int scores[10];
//load txt
ifstream highscores("highscores.txt");
if(highscores.is_open())
{
   while(highscores.good())
   {
    for(int x=0;x<10;x++)
    {
        getline(highscores,initials[x],' '); 
        highscores >> scores[x];
    }
   }
    }

首字母只有3个字符长,所以我可以实现一个2 dim.数组,但我想尝试它与字符串。它显示我创建了一个大小为10的字符串。我应该如何写它,使它将工作与10个数组而不是1?(我知道我可以从array1中创建10个数组…到10,循环通过它们听起来好多了。高分文件只是一组10首字母AAA,BBB等和一些分数。

hilicores.txt示例:

AAA 5000
BBB 4000
CCC 3000

使用std::map保存首字母和相关分数。例如:

int main()
{
    // Map is keyed by initials.
    std::map<std::string, int> scores;
    std::ifstream in("highscores.txt");
    if (in.is_open())
    {
        for (;;)
        {
            std::string line;
            std::getline(in, line);
            if (!in.good())
            {
                break;
            }
            const size_t space_idx = line.find(' ');
            if (std::string::npos != space_idx)
            {
                // The initials are everthing before the space.
                // Score everything after the space.
                scores[line.substr(0, space_idx)] =
                    atoi(line.substr(space_idx + 1).c_str());
            }
        }
        in.close();
    }
    // Check who has achieved required score.
    for (std::map<std::string, int>::iterator i = scores.begin();
         i != scores.end();
         i++)
    {
        if (i->second > 3500)
        {
            std::cout << i->first << "n";
        }
    }
    return 0;
}

有两个任务:

  • 添加一个新的用户评分,如果它是足够高

    // Add a new score (score => name pair); pop the lowerest score and return it
    template <class Map> typename Map::value_type
    add_score_if(Map& scores, typename Map::value_type new_score) {
      scores.insert(new_score);
      // pop the lowerest score
      auto it = scores.begin();
      typename Map::value_type lowerest(*it);
      scores.erase(it);
      return lowerest;
    }
    

    add_score_if()弹出最低分数,因此如果new_score不够高,它将不会留在得分表中,即在这种情况下,scores的含量将在add_score_if()之前/之后相同。

  • 从文件中加载分数

    // Load scores (score => name pairs) from input stream
    // where each line is: name score
    // Return whether all scores have been loaded
    template <class Istream, class Map> bool
    load_scores(Istream& in, Map& scores) {
      std::string name; int score;
      while (in >> name >> score) scores.insert(std::make_pair(score, name));
      return in.eof(); //XXX ignore errors at eof
    }
    

程序
#include <iostream>
#include <map>
template<class Map> void
dump_scores(std::ostream& out, const Map& scores) {
  for (auto it = scores.rbegin(); it != scores.rend(); ++it)
    out << it->second << ' ' << it->first << 'n';
}
int main() {
  // load scores
  std::multimap<int, std::string> scores;
  if (! load_scores(std::cin, scores)) {
    std::cerr << "error: not all scores have been loadedn";
    return 1;
  }
  std::cout << "Before:n";
  dump_scores(std::cout, scores);
  // add new score
  add_score_if(scores, std::make_pair(4000, "AAA"));
  std::cout << "nAfter:n";
  dump_scores(std::cout, scores);
}

例子
$ g++ -std=c++0x *.cc && printf "AAA 5000nCCC 3000nBBB 4000" | ./a.out
Before:
AAA 5000
BBB 4000
CCC 3000
After:
AAA 5000
AAA 4000
BBB 4000

重读后明白你的问题了:)

1. 正如你提到的string str[10]不会创建一个包含10个字符串的数组,因为字符串是在堆上创建的,而不是在堆栈上。

如果你想创建一个字符串数组来存放你的数据,那么它应该是char * name[10];,每次你读一行并得到前3个字符时,你做new char[3](你必须将它存储在char *中,对吗??)。

否则,为了更高效,根据您的数据,您可以创建一个char arr[30],并自己对3个字节进行读取对齐。

现在,您可以通过使用STL容器来简化您的工作。

vector < map < string,int > > arr; arr.reserve(10);

优点有很多:1)您无需进行内存管理。

2)使用迭代器进行循环。

如果你把它和我的第一种方法相比,在性能上也不会有太大的区别。