2012-02-23 90 views
1

我正在讀取3個東西到結構中歌曲:歌詞,歌手,文件大小。當我運行程序時出現錯誤,它看起來正確。STATUS_ACCESS_VIOLATION讀取文件時int結構

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

爲什麼把文件讀入一個struct當程序產生STATUS_ACCESS_VIOLATION

+0

*「它可能是編譯器?」* ... erm ...不。另外,因爲這是C++而不是C,所以使用'std :: vector'併爲自己節省頭痛。由於'num_songs'沒有初始化,因此您當前創建了一個不確定大小的數組。另外,讀'num_songs'調用UB。很多問題在這裏... – 2012-02-23 22:27:56

+0

啊這裏的幫助是無價的我現在正在工作,感謝所有和祝福 – gamergirl22 2012-02-23 23:58:43

回答

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

那麼你的代碼很瘋狂......「歌曲」數組有多大?目前你正在將它初始化爲「未定義」大小。您必須啓用num_songs。不這樣做意味着它「可能」使用任何價值。因爲您將數組初始化爲num_songs的大小(我們將採用任意數字70作爲示例,儘管它實際上可以是任何數字),然後開始以相同的值向數組寫入數據(這是超過陣列的末尾)。這是訪問衝突,因爲您隨後會遇到您的進程不擁有的內存。因此,你是違反通過嘗試使用內存,你也沒有訪問的內存空間。

您需要將其初始化爲已知大小,以便可以解析文件並找出其中有多少首歌曲。然後初始化你的數組然後填充它。

你會好得多使用STL的vector如下:

#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; 
} 
+0

請不要鼓勵使用'istream :: good'作爲循環條件。它幾乎總是會創建錯誤的代碼,就像在這種情況下一樣。 (你的節目很可能在矢量中創建一個額外的,空白的,最後的'歌曲')。首選'while(fin >> title >> artist >> size){song.push_back(Song(title,artist,size)) ; }' – 2012-02-23 22:49:53

1

Songs song[num_songs];這裏是num_songs初始化?

0

你有這樣的:

int num_songs; 

Songs song[num_songs]; 

這不是合法的C++。數組大小需要是編譯時常量表達式。

GNU編譯器有一個允許它的擴展,但即使在GNU中,用於定義數組大小的變量的值也需要定義一個值。

當你寫入一個未定義大小的數組時,你最終會到達內存中一個你不允許寫入的地方,或者你覆蓋了一些內存並改變了程序中其他內容的含義。訪問違規是對這種情況的完全合法迴應。

您應該改用C++容器,例如向量,列表或雙端隊列。它們可以動態增長以適應您文件中包含的許多項目。