我正在编写计算文件行数和字符数的代码。
#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')
似乎是导致以下错误的原因
分段错误(核心转储)
我无法弄清楚出了什么问题。互联网告诉我,据我所知,我正在检查线路的末端。
答案 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] )
吗? (这根本不是它的作用
当然。)