2016-01-18 43 views
3

我使用矢量寫入數據(結構)轉換成文件,當我嘗試使用矢量迭代器檢索數據,這讓我讀:"Vector iterator is not dereferenceable."矢量迭代器不dereferencable,同時試圖從文件

這是我的代碼:

void CProgram_1_STLDlg::OnBnClickedBtnView() 
{ 
    // TODO: Add your control notification handler code here 
    CFile file; 
    CFileException e; 
    studentVector::iterator sit; 
    studentVector::iterator sBegin = sVector.begin(); 
    studentVector::iterator sEnd = sVector.end(); 

    CString path = _T("D:\\Student.txt"); 

    if (file.Open(path, CFile::modeRead, &e)) { 
     while (file.Read((char *)&sVector, sizeof(sVector))) { 
      AfxMessageBox(_T("File opened in read mode."), MB_ICONINFORMATION); 
      AfxMessageBox(_T("ID:\t")+sit->id+L"\nName:\t" 
          +sit->name+L"\nMarks:\t"+sit->marks+L 
          "\nPercentage:\t"+sit->per+L"\nState:\t"+sit->state); 
      sit++; 
     } 
     //file.Read((char *)&sData, sizeof(sData)); 

     /*for (sIterator = sVector.begin(); sIterator != sVector.end(); sIterator++) { 
       //AfxMessageBox(_T("ID:\t")+sIterator->id+L 
           "\nName:\t"+sIterator->name+L"\nMarks:\t" 
           +sIterator->marks+L"\nPercentage:\t"+sIterator->per+L 
           "\nState:\t"+sIterator->state); 
       //AfxMessageBox(_T("Hello..Testing...!")); 
     } 
*/ 

    } else { 
     AfxMessageBox(_T("Error! Unable to open file."), MB_ICONERROR); 
    } 
} 

現在我不知道如何解決這個錯誤。

注意:我提到的一些鏈接是谷歌給我的,但我無法解決我的問題。

+0

'sIterator!= sit' – SHR

+0

@SHR我這樣做了,但是有一兩件事我不知道是怎麼計劃將知道有文件結尾,這就是爲什麼我用while循環來讀取文件,並採取其con帳篷到矢量中。 –

回答

5

你不能簡單地覆蓋矢量的內存。這幾乎保證會破壞你的過程。

此外,你永遠不會分配任何東西給sit,但期望它包含一些合理的東西。

您需要解析Student.txt中的數據並使用向量的成員函數來填充合理的數據。這個任務可能會告訴你這個文件是什麼樣的,以便你可以解析它。

1

... 「嘗試使用向量迭代器檢索數據,這讓我矢量迭代器不提領」 ...

Iterators是指針狀物體,但不像原始指針,如果他們是「dangling」,它們會阻止取消引用(訪問它們指向的值)。

在你的情況下,迭代器sit未被初始化,而不是被指定爲指向矢量sVector的開始的迭代器sBegin = sVector.begin();

因此,當您嘗試訪問不指向有效值的迭代器時,會出現錯誤。

除此之外,要將元素存儲到矢量中,您應該使用its member functions,而不是像在while循環中那樣傳遞其地址。


2

vector<char> cvec 

一個簡單的載體可能會被覆蓋 所以像

vector<char> cvec; 
cvec.resize(100); 
for(char i=0;i<100;i++) 
    cvec[i]=i; 

會工作。

如果您調整大小以改正大小。否則你會損壞內存

sizeof(sVector)將傳遞矢量類的大小。 這與數據無關,因爲vector類中的數據只不過是一個指針。 例如:

class simpleVector; 
{ 
    public: 
    simpleVector(unigned int size) 
    { 
     p=new int[size]; 
    } 
    int* p; 
} 
func() 
{ 
    simpleVector v1(10); 
    simpleVector v2(100000); 
    printf("size v1= %d, Size v2= %d", sizeof(v1),sizeog(v2)); 
} 

我沒有檢查,什麼樣的sizeof將提供這個類,但它肯定會是恆定的。獨立於構造函數的大小

Iterator是Vector 的訪問器,但它需要初始化。 在上面的代碼坐下沒有分配給某些東西。所以你無法訪問有效的東西。

從代碼線

AfxMessageBox的(_T( 「ID:\ t」 的)+靜坐> ID + L 「\ n名稱:\ t」 的+靜坐>名+ L「\ nMarks: \ t 「的+靜坐>標記+ L」 \ nPercentage:\ t 「的+靜坐>每+ L」 \ NSTATE:\ t「的+靜坐>狀態);

我看到向量應該包含從幾個字符串構建的複雜數據類型。 這樣一個向量元素可能看起來像

class student 
{ 
    std::string id; 
    std::string name; 
    std::string marks; 
    std::string per; 
    std::string state; 
}; 

這是最小的每個向量元素的信息保持。 通常字符串的屬性具有不同的長度。 雖然ID可能總是相同的長度名稱可能不會。 因爲它沒有固定長度 甚至

file.Read((char *)&sVector, sizeof(student)) 

是行不通的。 所以我建議讀者加入到「學生」類別:

class student 
{ 
    std::string id; 
    std::string name; 
    std::string marks; 
    std::string per; 
    std::string state; 
    bool ReadElemFromFile(CFile& file) 
    { 
      id=ReadStringFromFile(file); 
      name=ReadStringFromFile(file); 
      marks=ReadStringFromFile(file); 
      per=ReadStringFromFile(file); 
      state=ReadStringFromFile(file); 
      if(id.empty()||name.empty()||marks.empty()||per.empty()||state.empty()) 
       return false; 
      return true; 
    } 
    std::string ReadStringFromFile(CFile% file) 
    { 
      char c; 
      std::string s; 
      do 
      { 
       file.read(&c,1); 
       s+=c; 
      } 
      while(c!='\0') 
      return s; 
    } 
}; 

我知道讀取的方式是不這樣做最高效的方式,但它表明,存儲到文件中的字符串結束指示每個字符串的長度

現在回到你的代碼

void CProgram_1_STLDlg::OnBnClickedBtnView() 
{ 
    // TODO: Add your control notification handler code here 
    CFile file; 
    CFileException e; 
    student* sit=new Student; 
    studentVector.clear(); 

    CString path = _T("D:\\Student.txt"); 

    if (file.Open(path, CFile::modeRead, &e)) { 
     while (sit->ReadElemFromFile(CFile& file)) { 
      AfxMessageBox(_T("File opened in read mode."), MB_ICONINFORMATION); 
      AfxMessageBox(_T("ID:\t")+sit->id+L"\nName:\t"+sit->name+L"\nMarks:\t"+sit->marks+L"\nPercentage:\t"+sit->per+L"\nState:\t"+sit->state); 
      studentVector.push_back(*sit); 
     } 
    } else { 
     AfxMessageBox(_T("Error! Unable to open file."), MB_ICONERROR); 
    } 
    delete stud; 
}