保存到文件中的字符串数组

时间:2011-12-10 12:44:32

标签: c++ string file-io

基本上,我想从文件中读取高分,并检查用户是否已将得分点记在记分板上。我试着这样做:

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个暗淡。数组,但我想用字符串尝试。它显示我疯狂一个大小为10的字符串。我应该如何编写它以便它可以使用10个数组而不是1个? (我知道我可以制作10个数组,将它们从array1 ...命名为10,循环播放它们听起来要好得多。高分文件只是一组10个initialas AAA,BBB等等,还有一些分数。

highscores.txt的例子:

AAA 5000
BBB 4000
CCC 3000

3 个答案:

答案 0 :(得分:1)

使用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;
}

答案 1 :(得分:1)

有两个任务:

  • 如果足够高,请添加新的用户分数

    // 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 loaded\n";
    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 5000\nCCC 3000\nBBB 4000" | ./a.out
Before:
AAA 5000
BBB 4000
CCC 3000

After:
AAA 5000
AAA 4000
BBB 4000

答案 2 :(得分:0)

重新阅读后得到你的问题:)

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)使用迭代器循环。

3)如果将它与我的第一种方法进行比较,那么性能也不会有太大差异。