2012-11-30 100 views
1

我的代碼打開一個文本文件,計算行數,分配一個數組來存儲所有行,然後調用一個函數來填充每行的數組。此功能file.getline調用返回空字符串:ifstream getline問題

下面的代碼:

typedef char* line; 

...

char* filename=new char[256]; 
cout << "Type a file name: " << endl; 
cin.ignore(); 
cin.getline(filename,255); 

ifstream iFile(filename); 

int nLines=CountLines(iFile); 

line* LineArray = new line[nLines]; 
ReadLines(LineArray,iFile); 

了countLines功能:

int CountLines(ifstream &file) 
{ 
line templine=new char[64]; 
int nLines=0; 

while (!file.eof()) 
{ 
    file.getline(templine,64); 

    if (*templine != '\n') 
     nLines++; 

} 
delete [] templine; 

return nLines; 
} 

這正常工作。然而readlines方法並不:

void ReadLines(line* LineArray, ifstream &file) 
{ 
    line templine=new char[64]; 

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

int i = 0; 
while (!file.eof()) 
{ 

    if (*templine != '\n') 
    { 
     LineArray[i]=templine; 
     i++; 
    } 

} 
delete [] templine; 
} 

我有一種感覺,它是與函數getline的「\ n」的問題,但我取指針設置爲0,該文件對普通的文字,而不是一開始行,我不明白爲什麼它填充空字符串templine。

+4

使用['標準:: VECTOR'(http://en.cppreference.com/w/cpp/container/矢量)和['std :: string'](http://en.cppreference.com/w/cpp/string/basic_string),它會讓你的生活變得更容易。另外,你有很多潛在的內存泄漏。 –

+1

'LineArray [i] = templine;'你在哪裏積累'我'? – xiaoyi

+5

不要使用'while(!file.eof())'!它檢查* previous * read是否是文件的結尾。你想'while(file.getline(...))'。 (這似乎是最近出乎意料地突然出現) –

回答

1

您的代碼中存在太多錯誤。

  • 參數istream::getline()是錯誤的
  • 你需要明確的EOF標誌之後CountLines()
  • 錯誤的內存釋放操作。
  • 等等等等...

指針不是玩具,你最好用蒂諾Didriksen的解決方案去。

如果你很喜歡char和指針,它應該是這樣的:

#include <iostream> 
#include <fstream> 
#include <cassert> 

using namespace std; 

int CountLines(ifstream &fin) { 
    char templine[1024];  // no need for dynamic allocation. 
    int count = 0; 
    while (fin.getline(templine, 1024)) 
    count++; 
    return count; 
} 

void ReadLines(char** lines, int count, ifstream &fin) { 
    fin.seekg(0, ios::beg); 
    for (int i = 0; i < count; i++) { 
    lines[i] = new char[1024];  // you need dynamic allocation here. 
    fin.getline(lines[i], 1024); 
    assert(fin.gcount() < 1024); // assure the line is shorter than 1023 chars 
    } 
} 

int main() { 

    char filename[256];   // no need for dynamic allocation. 
    cin.getline(filename, 256); // second parameter should be the same size of your buffer. 

    ifstream fin(filename); 

    int count = CountLines(fin); 
    char** lines = new char*[count]; 

    // After CountLines() called, fin.eof is set, you need to clear it. 
    // Otherwise fin.getline() won't do a thing. 
    fin.clear(); 
    ReadLines(lines, count, fin); 

    // When every thing is done, you need to free all the memory. 
    for (int i = 0; i < count; i++) 
    delete[] lines[i]; 
    delete[] lines; 

} 
+0

謝謝你的詳細澄清,但老實說你可以做到沒有冒犯性語氣。我剛剛在2周前就開始使用C,我更願意學習基本知識,比如指針操作,而不是直接去自動化的東西 – Tsaras

+0

@Tsaras哦,對不起。我知道你是C新手,你不應該玩指針,即使你做錯了,你也看不出來,並且在大多數情況下系統不會發出錯誤。而你沒有使用C,它是C++。 – xiaoyi

-1

你的錯誤是在此代碼:

if (*templine != '\n') 

,因爲你正在檢查排在第一位的象徵。

你應該改變這樣的代碼:

int CountLines(ifstream &file) 
{ 
    string line; 
    int nLines=0; 
    while(getline(file,line)) 
     nLines++; 

    return nLines; 
} 


void ReadLines(string LineArray, ifstream &file) 
{ 
    file.seekg(0,ios::beg); 

    string line; 
    while(getline(file,line)) 
    { 
     LineArray += line; 
    } 
} 
+0

我使用了你的代碼結構,同時保留了我的char * s而不是你的字符串,並且ReadLines仍然從第一個循環中讀取空字符串 – Tsaras

5

你並不需要先計算行然後讀線。你可以做

#include <istream> 
#include <vector> 
#include <string> 

std::vector<std::string> ReadLines(std::istream& is) { 
    std::vector<std::string> lines; 
    std::string line; 

    while (std::getline(is, line)) { 
     lines.push_back(line); 
    } 

    return lines; 
} 

這將返回一個std ::向量的所有行,沒有任何大驚小怪或手動內存管理。