分段故障搜索终点

时间:2013-08-08 12:22:43

标签: c++

我正在编写计算文件行数和字符数的代码。

#include <fstream>
#include <iostream>
#include <stdlib.h>    
using namespace std;


int main(int argc, char* argv[])
    {
    ifstream read(argv[1]);


    char line[256];
    int nLines=0, nChars=0, nTotalChars=0;
    read.getline(line, 256);

    while(read.good())                      /
        {
        nChars=0;

        int i=0;
        while(line[i]!='\n')
            {

            if ((int)line[i]>32) {nChars++;}
            i++;
            }

        nLines++;
        nTotalChars= nTotalChars + nChars;
        read.getline(line, 256);
        }
    cout << "The number of lines is "<< nLines << endl;
    cout << "The number of characters is "<< nTotalChars << endl;
    }

while(line[i]!='\n')似乎是导致以下错误的原因

  

分段错误(核心转储)

我无法弄清楚出了什么问题。互联网告诉我,据我所知,我正在检查线路的末端。

5 个答案:

答案 0 :(得分:6)

您的代码找不到'\n',因为它会从输入序列中丢弃。来自getline的文档:

  

分隔字符是换行符[...]:当在输入序列中找到时,它从输入序列中提取,但被丢弃而不写入s。

您应该搜索'\0'

    while(line[i])
        {
        if ((int)line[i]>32) {nChars++;}
        i++;
        }

答案 1 :(得分:1)

因为getline不会存储\n,所以循环:

    while(line[i]!='\n')
        {

        if ((int)line[i]>32) {nChars++;}
        i++;
        }

永远不会结束,直到line[i]超过数组长度并导致分段错误。

答案 2 :(得分:1)

行中没有行尾字符。因此,您应该检查NULL字符(字符串的结尾)而不是行尾。另外,请确保在您的情况下不要超过缓冲区的大小(256)。

答案 3 :(得分:0)

我认为for循环会更安全:

for ( unsigned int i = 0; i < line.size(); i++ ) {
  //whatever
}

答案 4 :(得分:0)

您的代码有几个问题,但对于初学者,您 不应该将行读成char[]。如果你使用 std::string,那么你不必担心阅读 部分线等。

然后事实是getline从中提取'\n' 该文件,但存储它,所以你的代码(甚至修改 使用std::string)永远不会在缓冲区中看到'\n'。如果 你正在使用字符串,你从line.begin()迭代到 line.end();如果您使用的是char[],则可以迭代 read.gcount()返回的字节数,在。之后调用 致电getline。 (这个代码很难得到 使用char[] ,除非您认为没有文本文件 world包含'\0'。)

最后,如果最后一行没有以'\n'结束(频率 在Windows下的情况),你不会处理它。如果你正在使用 std::string,你可以写一下:

std::getline( read, line );
while ( read ) {
    //  ...
    std::getline( read, line );
}

甚至:

while ( std::getline( read, line ) ) {
    ++ nLines;
    for ( std::string::const_iterator current = line.begin();
            current != line.end();
            ++ current ) {
        //  process character *current in line...
    }
}

(后者无处不在,即使它很难看。)

使用char[],您必须将其替换为:

while ( read.getline( buffer, sizeof(buffer) ) || read.gcount() != 0 ) {
    int l = read.gcount();
    if ( read ) {
        ++ nLines;
    } else {
        if ( read.eof() ) {
            ++ nLines;  //  Last line did not end with a '\n'
        } else {
            read.clear();   //  Line longer than buffer...
    }
    for ( int i = 0; i != l; ++ i ) {
        //  process character buffer[i] in line...
    }
}

最后一个问题:(int)line[i] > 32应该是什么 意思?你想要!isspace( line[i] ) && !iscntrl( line[i] )吗? (这根本不是它的作用 当然。)