2012-03-02 92 views
0

嘿傢伙我試圖洗牌我的動態數組的內容,它不工作。即時通訊想知道如果有任何建議或鏈接/資源,可以幫助我。我正在嘗試使用std :: randomshuffle,但我的測試正在吐出0而不是正確的數據。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(); 

和我的繼承人功能我嘗試使用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 2012-03-02 00:09:13

+0

以及那些是我的ptr數組的內容,所以我想我不得不包括那些以及 – gamergirl22 2012-03-02 00:17:28

+0

@ gamergirl22絕對不需要,不應該這樣做。之後,你必須考慮如何有效地設計代碼:這個洗牌功能的重點在於將歌曲洗牌並打印出來。所以我們需要的是歌曲和歌曲(不是'歌曲'和'ptr')也是多餘的。 – stinky472 2012-03-02 00:22:24

回答

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 ON YOUR文件格式

無向量(但請學習他們)這:

 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]; 

和福其餘nction調用將像

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

這看起來非常好,但不幸的是,我還沒有學習矢量,所以我不知道如何將它納入我的函數調用等。大聲笑。非常好的工作,我給你投票。 – gamergirl22 2012-03-02 00:49:31

+1

現在學習第二本!認真 – 111111 2012-03-02 00:51:19

+0

@ gamergirl22再看一遍,我已經添加了一個額外的位 – 111111 2012-03-02 00:54:42

3

切勿使用istream::good()istream::eof()作爲循環條件。它幾乎總是產生bug的代碼(因爲它在這種情況下做。)

嘗試:

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"; 
    } 
}