2012-12-11 78 views
3

我正在爲我的C++類做一個程序。最後,我想我的程序上按以下格式的聯繫人的文本文件進行快速排序:將信息讀入結構數組C++

姓Secondname數

每接觸一個新行分離。我已經開始計算行數並使用動態內存分配來創建一個與行數相同大小的結構數組。

但是,當我試圖讀取文本文件中的信息並將其輸出到屏幕上時,我所得到的只是亂碼。我在互聯網上看了一遍,試圖找到一個解決方案,但是我發現的一切似乎都對我使用了不同的語法。

這裏是我到目前爲止的代碼:

#include <iostream> 
#include <fstream> 
#include <istream> 

char in[20]; 
char out[20]; 

using namespace std; 

struct contact 
{ 
    char firstName[14]; 
    char surName[14]; 
    char number[9]; 
}; 
//structure definition 

int main(void){ 

    cout << "Please enter the input filename: " << endl; 
    cin >> in; 
    ifstream input(in); 

    if(!input){ 
     cerr << "failed to open input file " << in << endl; 
     exit(1); 
    } 

    cout << "Please enter tne output filename: " << endl; 
    cin >> out; 

    // read in the input and output filenames 

    char a; 
    int b=0; 
    while (input.good()) 
    { 
     a=input.get(); 
     if (a=='\n') 
     { 
      b++; 
     } 
    } 
    // count the number of lines in the input file 

    input.seekg (0, ios::beg); 

    //rewind to beginning of file 

    contact* list = new contact[b]; 

    //dynamically create memory space for array of contacts 

    int i = 0.; 
     while(input){ 
      if(i >= b) break; 
      if(input >> *list[i].firstName >> *list[i].surName >> *list[i].number) i++; 
      else break; 
     } 
    input.close(); 

    //read information from input file into array of contacts 

    for(int N = 0; N < b; N++){ 
     cout << list[N].firstName << list[N].surName << list[N].number << endl; 
    } 

    ofstream output(out); 
    int k = 0; 
    for(int k = 0; k<b; k++){ 
     output << list[k].firstName << "  " << list[k].surName << "  " << list[k].number << endl; 
    } 

    //print out the unsorted list to screen and write to output file 
    //i've done both here just to check, won't print to screen in final version 

    output.close(); 
    delete []list; 

}  // end of main() 
+0

我敢肯定你需要刷新輸入流,因爲它已經到達文件的末尾,給對象的值爲false。你也有一些使用input.get的低效方法,當你只需要一次抓一行直到文件結尾 –

+0

你是什麼意思通過刷新輸入流?我以爲seekg會將編譯器帶回到文件的開頭? – GGled

+0

是的,但是當你計算行數時,你的文件已經達到一次eof。文件標誌被設置爲FALSE以顯示它處於eof,但將讀取器設置回零不會刷新此標誌 –

回答

0

您的文件位置重置爲開頭,但文件eofbit仍標註爲真正從當你第一次閱讀量線。快速修復此問題是在讀取行後重新打開文件,可能會使行數爲清除代碼的函數。

int lines(const string path) 
{ 
    ifstream tmp(path.c_str()); 
    string temp; 
    int count = 0; 
    getline(inFile,temp); 
    while(inFile) 
    { 
     count++; 
     getline(inFile,temp); 
    } 
    tmp.close(); 
    return count; 
} 
+0

我試圖通過上面的方法計算行數後關閉並重新打開文件,但我仍然得到相同的亂碼輸出。我試過把你的函數放進去,但intellisense告訴我它在函數的第一行之後會要求聲明。 – GGled

+0

關於你的輸入的另一個註釋:在輸入中的所有列表對象之前移除*,然後回到我所做的事情上。 –

+0

我得到了同樣的結果。 – GGled

0

好吧,我把一個快速和骯髒的方法,使用新的C + +結構,讓你大部分的方式。你自己寫文件(簡單)和快速排序,儘管我已經把結構放到你的向量中,所以排序向量就像編寫自定義函數來比較一個結構和其他結構一樣簡單。如果某些代碼少於標準C++,我很抱歉。我已經過了我的睡覺時間,並且很累,但是這個問題足夠有趣,我想要去解決它。快樂的編碼!

#include <iostream> 
#include <fstream> 
#include <istream> 
#include <string> 
#include <vector> 
#include <algorithm> 
#include <cctype> 
#include <sstream> 

using namespace std; 

std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) { 
    std::stringstream ss(s); 
    std::string item; 
    while(std::getline(ss, item, delim)) { 
     elems.push_back(item); 
    } 
    return elems; 
} 


std::vector<std::string> split(const std::string &s, char delim) { 
    std::vector<std::string> elems; 
    return split(s, delim, elems); 
} 

struct contact 
{ 
    std::string firstName; 
    std::string surName; 
    std::string number; 

    contact(std::string& fName, std::string& lName, std::string& num) : firstName(fName), surName(lName), number(num) {} 
}; 
//structure definition 

char in[20]; 
char out[20]; 

int main() 
{ 
    std::vector<contact> contacts; 

    cout << "Please enter the input filename: " << endl; 
    cin >> in; 
    ifstream input(in); 

    if(!input){ 
     cerr << "failed to open input file " << in << endl; 
     exit(1); 
    } 

    cout << "Please enter tne output filename: " << endl; 
    cin >> out; 

    std::string sinput; 

    // read in the input and output filenames 
    while (input.good()) 
    { 
     getline(input, sinput); 

     vector<string> tokens = split(sinput, ' '); 
     if (tokens.size() == 3) 
     { 
      contact c(tokens[0], tokens[1], tokens[2]); 
      contacts.push_back(c); 
     } 
    } 

    input.close(); 

    //read information from input file into array of contacts 

    std::cout << "Outputting from vector..." << std::endl; 
    for_each(contacts.begin(), contacts.end(), [](contact& c) { 
     cout << c.firstName << " " << c.surName << " " << c.number << endl; 
    }); 

    return 0; 
} 

而且,只是想給信貸的拆分方法來自this answer在這個非常的網站。乾杯!