我试着给自己写一个文本计数器,它告诉我一段文字中有多少个字符和单词。每当我尝试粘贴一段长文本进行计数时,它就会崩溃或显示随机的内容。
有人有任何建议吗?
这就是我写的:
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "Text counter\nPlease insert text.\n";
string text = "";
getline(cin, text);
double countTotal = text.size();
cout << "Total characters: " << countTotal << "\n";
int wordCount = 1;
for (int chrSearch = 0; chrSearch < (int)text.size(); chrSearch++)
{
char chr = text.at(chrSearch);
if(chr == ' ')
{
wordCount++;
}
}
cout << "Total words: " << wordCount << "\n";
return 0;
}
答案 0 :(得分:2)
首先,代码最多读取一行:std::getline(std::cin, line)
在收到第一个换行符时停止读取。您可以指定要停止的字符,例如,字符'\0'
不太可能出现在典型文本中。例如,您可以使用:
std::string text;
if (std::getline(std::cin, text, '\0')) {
// do something with the read text
}
您还应始终检查输入是否成功。虽然上述内容适用于短文本,但当文本变大时,一次读取一行更有意义,最终读取一行将在流结束时失败。
如果你不喜欢读取一切空字符的方法,你可以使用以下代码读取整个流:
std::istreambuf_iterator<char> it(std::cin), end;
std::string text(it, end);
if (!text.empty()) {
// do something with the read text
}
关于代码其他部分的一些注释:
double
表示使用整数。您可能希望使用更大的整数,例如unsigned long
或unsigned long long
,但double
用于浮点值。在迭代序列时,您应该在处理索引时使用无符号整数类型,例如unsigned int
或std::size_t
。这样就不需要施放size()
了。最好使用迭代器:
for (auto it(text.begin()), end(text.end()); it != end; ++it) {
char chr(*it);
// ...
}
或
for (char chr: text) {
// ...
}
请注意,如果有两个连续的空格,则您的字数错误。此外,如果您不使用换行符中断文本,则需要使用'\n'
作为分隔单词的附加空白字符。如果你想考虑所有空格,你应该使用这样的东西来确定一个字符是否是一个空格:
if (std::isspace(static_cast<unsigned char>(chr)) { ... }
static_cast<unsigned char>(chr)
是必需的,因为char
往往是签名的,而std::isspace()
使用负值会导致未定义的行为。将角色投射到unsigned char
可以避免任何问题。请注意,负面字符并非完全不常见:例如,我的姓氏的第二个字符(u-umlaut 'ü'
)通常会导致负char
,例如UTF-8或使用ISO-Latin-1编码。