我编写了一个程序来计算文本文件中的字母数字字符数。但是,它返回的数字总是大于在线字符计数器返回的数字。
例如,程序将计算此文本中的字母数字字符数:
如果这些人有奇怪的时尚和期望最多的服从 特别重要的事情,他们至少愿意为他们付出代价 偏心
是162.再次运行程序,它会说文本中有164个字符。再次运行,它会说有156个字符。使用this在线字符计数器,似乎字符数应该低于144(在线字符计数器也包括空格)。
以下是代码:
#include <iostream>
#include <fstream>
#include <cctype>
using namespace std;
int main() {
char line[100];
int charcount = 0;
ifstream file("pg1661sample.txt");
while (!file.eof()) {
file.getline(line, 99);
for (int i = 0; i < 100; i++) {
if (isalnum(line[i])) {
charcount++;
}
}
}
cout << endl << "Alphanumeric character count: " << charcount;
cin.get();
return 0;
}
我做错了什么?
答案 0 :(得分:5)
尝试:
#include <iterator>
#include <algorithm>
#include <iostream>
#include <cctype>
bool isAlphaNum(unsigned char x){return std::isalnum(x);}
int main()
{
std::cout << "Alphanumeric character count: " <<
std::count_if(std::istream_iterator<char>(std::cin),
std::istream_iterator<char>(),
isAlphaNum
) ;
}
代码问题:
在您阅读文件末尾之前,EOF不正确:
// this is true even if there is nothing left to read.
// If fails the first time you read after there is nothing left.
while (!file.eof()) {
// thus this line may fail
file.getline(line, 99);
最好总是这样做:
while(file.getline(line, 99))
仅在getline实际工作时输入循环。
您还使用了糟糕的getline版本(因为行数可能超过100个字符) 尝试使用与std :: string一起使用的版本,以便它自动扩展。
std::string line;
while(std::getline(file, line))
{
// stuff
}
接下来,假设该行正好是100个字符 如果该行只有2个字符,那么会发生什么?
for (int i = 0; i < 100; i++)
基本上,您将扫描数据,它将计算前一行遗留的字母(如果前一行长于当前行)或完全随机的垃圾。如果您仍在使用file.getline()
,则可以使用file.gcount()
从一行中检索字符数。如果使用std :: getline(),则变量line
将是读取行(line.size()
)的确切大小。
答案 1 :(得分:1)
while (!file.eof()) {
不要这样做。 eof()在 尝试输入失败后才返回true,因此这样的循环会运行额外的时间。相反,这样做:
while (!file.getline(line, 99)) {
当输入结束时,循环将终止。
另一个问题是在循环中计算字符数。问问自己:在每次通过输入循环时,有多少字符被读入缓冲区?那么,为什么计数循环看100个字符?
答案 2 :(得分:0)
您假设getline()
填充line
只有100个字符。检查getline()
读入的字符串的长度,例如使用strlen()
:
for (int i = 0; i < strlen(line); i++) {
if (isalnum(line[i])) {
charcount++;
}
}
编辑:另外,请务必注意其他答案中的建议,使用getline()
的循环条件返回值,而不是调用eof()
。