c++对动态数组的内容进行混洗

c++ shuffling contents of dynamic array?

本文关键字:混洗 动态 数组 c++      更新时间:2023-10-16

嘿,伙计们,我正试图打乱我的动态数组的内容,但它不起作用。我想知道yall是否有任何建议或链接/资源可以帮助我。我尝试使用std::randomshuffle,但我的测试结果是0,而不是正确的数据。

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();

我的功能是尝试使用随机洗牌

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

切勿将istream::good()istream::eof()用作循环条件。它几乎总是产生有缺陷的代码(就像在这种情况下一样)

尝试:

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

请考虑以下内容,这是一种更现代的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