我正在读取结构中的3件事歌曲:歌曲,艺术家,文件大小。我运行程序时遇到错误,看起来是正确的。
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
using namespace std;
struct Songs
{
string title;
string artist;
int size;
};
int main ()
{
int num_songs;
Songs song[num_songs];
ifstream fin;
fin.open("songlist.txt")
while (fin.good()) {
fin >> song[num_songs].title;
fin >> song[num_songs].artist;
fin >> song[num_songs].size;
num_songs++;
}
fin.close();
cout << "welcome to the show" << endl;
return 0;
}
为什么程序在将文件读入STATUS_ACCESS_VIOLATION
?
struct
答案 0 :(得分:4)
你的程序“看起来不正确”,它有很多错误,详见其他答案。
这是一个正确读入歌曲列表的程序。请注意,这些是用于读取文件的四种替代方法。选择对你最有意义的一个并删除其他三个。
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <iterator>
#include <algorithm>
struct Song
{
std::string title;
std::string artist;
int size;
Song() : size() { }
Song(const Song& song) :
title(song.title), artist(song.artist), size(song.size) { }
Song(std::string title, std::string artist, int size) :
title(title), artist(artist), size(size) { }
};
std::istream&
operator>>(std::istream& is, Song& song) {
return is >> song.title >> song.artist >> song.size;
}
int main ()
{
std::vector< Song > songs;
std::ifstream fin;
fin.open("songlist.txt");
// You could read the songs this way:
std::copy(std::istream_iterator<Song>(fin),
std::istream_iterator<Song>(),
std::back_inserter(songs));
// Or, if you don't like std::copy, you can do this:
Song song;
while(fin >> song)
songs.push_back(song);
// Or, if you don't like operator>>(istream, Song), you can do this:
std::string artist;
std::string title;
int size;
while(fin >> artist >> title >> size)
songs.push_back(Song(artist, title, size));
// Or, if you don't like using the constructor:
while(fin >> artist >> title >> size) {
Song song;
song.artist = artist;
song.title = title;
song.size = size;
songs.push_back(song);
}
int num_songs = songs.size();
std::cout << "welcome to the show: " << num_songs << "\n";
return 0;
}
答案 1 :(得分:1)
你的代码非常疯狂......“歌曲”阵列有多大?目前,您将其初始化为“未定义”大小。你必须在num_songs initalise。没有这样做意味着它“可以”使用任何价值。您正在获取访问冲突,因为您将数组初始化为num_songs大小(我们将以任意数字70为例,尽管它可以是字面上的任何数字)然后您开始以相同的值写入数组(这是超过数组的结尾)。这是一种访问冲突,因为您随后会遇到您的进程不拥有的内存。因此,您通过尝试使用 access 的内存来违反内存空间。
您需要将其初始化为已知大小,以便您可以解析文件并找出其中有多少首歌曲。然后初始化你的数组,然后填充它。
使用stl向量会好得多,如下所示:
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
using namespace std;
struct Songs
{
string title;
string artist;
int size;
Songs() {};
};
int main ()
{
std::vector< Songs > song;
ifstream fin;
fin.open("songlist.txt")
while (fin.good())
{
song.push_back( Songs() );
fin >> song.back().title;
fin >> song.back().artist;
fin >> song.back().size;
}
fin.close();
int num_songs = song.size();
cout << "welcome to the show" << endl;
return 0;
}
答案 2 :(得分:1)
Songs song[num_songs];
num_songs
的初始化在哪里?
答案 3 :(得分:0)
你有这个:
int num_songs;
Songs song[num_songs];
这不是合法的C ++。数组大小需要是编译时常量表达式。
GNU编译器有一个允许它的扩展,但即使在GNU中,用于定义数组大小的变量值也需要有一个定义的值。
当您写入具有未定义大小的数组时,您最终会到达内存中您不允许写入的位置,或者覆盖某些内存并更改程序中其他内容的含义。访问冲突是对这种情况的完全合法的回应。
您应该使用C ++容器,例如矢量,列表或双端队列。它们可以动态增长,以适应您文件中的许多项目。