Пожалуйста, примите во внимание следующее, это более современный подход C ++ к вашей проблеме.Вы создаете оператор потока, поэтому вам не нужно анализировать объект вручную каждый раз, когда вы хотите прочитать.
#include <algorithm>
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
struct song {
std::string title, artist;
int mem;
};
std::ostream& operator<<(std::ostream& os, const song& s) {
return os << s.title << "\t" << s.artist << "\t" << s.mem;
}
std::istream& operator>>(std::istream& is, song& s) {
std::getline(is, s.title);
std::getline(is, s.artist);
return is >> s.mem;
}
int main()
{
std::ifstream file("input.txt");
if(!file.is_open()) return 1;
std::vector<song> songs((std::istream_iterator<song>(file)),
std::istream_iterator<song>());
std::random_shuffle(songs.begin(), songs.end());
std::copy(songs.begin(), songs.end(),
std::ostream_iterator<song>(std::cout, "\n"));
return 0;
}
компилируется, но НЕ ПРОВЕРЯЕТСЯ НА ФОРМАТЕ ФАЙЛА
без вектора (НО ПОЖАЛУЙСТАУЗНАЙТЕ ИХ) это:
std::vector<song> songs((std::istream_iterator<song>(file)),
std::istream_iterator<song>());
можно записать как:
const size_t sz=20;
song songs[sz];
for(unsigned i=0; i!=sz && file; ++i)
file >> songs[i];
, а остальная часть вызова функции будет работать как
std::random_shuffle(songs, songs+sz);
, но серьезно учитесьвекторы сейчас (а затем и другие контейнеры).Массив в основном считается устаревшим для вашей задачи, примером чего является то, что если у вас более 20 элементов в файле, вы получите переполнение буфера и произойдет плохая вещь.
http://en.cppreference.com/w/cpp/container/vector
Также вам не нужно явно открывать и закрывать файлы (в большинстве случаев вы, скорее всего, будете вводить ошибки) из-за RAII:
http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization