2012-03-02 5 views
0

эй, ребята, я пытаюсь перетасовать содержимое моего динамического массива и его не работает. Им интересно, если yall получил какие-либо советы или ссылки/ресурсы, которые могут мне помочь. Я пытаюсь использовать std :: randomshuffle, но мой тест выплевывает 0s вместо правильных данных.C++ перетасовка содержимого динамического массива?

Songs *ptr; 
ptr = new Songs[25]; 

ifstream fin; 
fin.open("input.txt"); 

while (fin.good())     //my input 
{ 
     getline(fin, song[num].title);  
     getline(fin, song[num].artist); 
     fin >> song[num].mem; 
     num++; 
     fin>>ws; 
} 
fin.close(); 

и Heres моя функция им пытаются использовать randomshuffle

void shuffle (char choice, Songs song[], Songs *ptr, string title, string artist, int mem, int num) 
{ 
    if (choice == '4') 
    { 
     std::random_shuffle(ptr, ptr + num);    //shuffle 
    } 
    for (int i = 0; i<num; i++) //test 
    { 
     cout << ptr[i].title << ptr[i].artist << ptr[i].mem << endl; 
    } 
} 
+0

Почему все параметры в функция 'shuffle()'? Вы используете только 'ptr' и' num'. И логика, чтобы перетасовать или нет, не должна быть действительно сделана внутри функции перетасовки. – jrok

+0

ну вот содержание моего массива ptr, поэтому я решил, что должен был включить их также – gamergirl22

+0

@ gamergirl22 абсолютно не нужно и не должен этого делать. Позже вам нужно подумать о том, как эффективно проектировать код: точка этой функции тасования - это перетасовать песни и распечатать их. Итак, все, что нам нужно, это песни и num (не то, что «песня» и «ptr») также излишни. – stinky472

ответ

2

Обратите внимание на следующее, это более современный подход 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; 
} 

компилирует но UNTESTED НА ВАШЕМ Формат файла

без вектора (НО узнавайте ИМ) это :

 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

+0

это выглядит очень хорошо, но, к сожалению, я havent изучил векторы, поэтому я бы не знал, как включить это в мои вызовы функций и т. Д. лол. очень хорошая работа, я голосую. – gamergirl22

+1

УЗНАЙТЕ ВЕКТОРЫ СЕЙЧАС ЭТО ВТОРОЕ! серьезно – 111111

+0

@ gamergirl22 Посмотрите еще раз, я добавил дополнительный бит – 111111

3

Никогда не используйте istream::good() или istream::eof() как условие цикла. Это почти всегда производит глючный код (как это делает в этом случае.)

Try:

while (std::getline(fin, song[num].title) && 
     std::getline(fin, song[num].artist) && 
     fin >> song[num].mem) 
{ 
     num++; 
     fin>>ws; 
} 

Как вонючие точки, ваш перетасовать является правильным, хотя ужасным стилем. Попытайтесь:

void shuffle (char choice, Songs *ptr, int num) 
{ 
    if (choice == '4') 
    { 
     std::random_shuffle(ptr, ptr + num);    //shuffle 
    } 
    for (int i = 0; i<num; i++) //test 
    { 
     std::cout << ptr[i].title << ptr[i].artist << ptr[i].mem << "\n"; 
    } 
} 
Смежные вопросы