Сохранение в массив строк из файла - PullRequest
0 голосов
/ 10 декабря 2011

По сути, я хочу прочитать рекорды из файла и проверить, набрал ли пользователь достаточно очков, чтобы оказаться на табло.Я пытаюсь сделать это так:

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 массивов, называя их от массивов от 1 до 10, циклически просматривая их, звучит намного лучше. Файл рекордов - это всего лишь набор из 10 инициалов AAA, BBB и т. Д. И некоторых оценок.of highscores.txt:

AAA 5000
BBB 4000
CCC 3000

Ответы [ 3 ]

1 голос
/ 10 декабря 2011

Есть две задачи:

  • добавить новый пользовательский балл, если он достаточно высок* недостаточно высокий, он не останется в таблице результатов, т. е. содержимое scores будет таким же до / после add_score_if() в этом случае.

  • loadрезультаты из файла

    // 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
1 голос
/ 10 декабря 2011

Используйте 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;
}
0 голосов
/ 10 декабря 2011

Получил ваш вопрос после перечитывания:)

1. string str[10], как вы упомянули, не создает массив из 10 строк, так как строки создаются в куче, а не в стеке.

Если вы хотите создать массив строк для размещения ваших данных ... тогда это должно быть char * name[10];, и каждый раз, когда вы читаете строку и получаете первые 3 символа, которые вы делаете new char[3] (вы должны сохранить его всимвол * правильно ??).

Иначе, чтобы быть более эффективным и в зависимости от ваших данных, вы можете создать char arr[30] и выполнить выравнивание в 3 байта для самостоятельного чтения.

Теперь вы можете значительно упростить свою жизнь, используя контейнеры STL.

vector &lt map &lt string,int &gt &gt arr; arr.reserve(10);

Преимуществ много: 1) Нет управления памятьюбыть сделано вами.

2) Использование итераторов для циклического прохождения.

3) И не будет большой разницы в производительности, даже если вы сравните его с моим первым методом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...