2012-11-30 70 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 ::向量的所有行,没有任何大惊小怪或手动内存管理。