与文本计数器一起苦苦挣扎

时间:2015-01-07 21:34:47

标签: c++ string

我试着给自己写一个文本计数器,它告诉我一段文字中有多少个字符和单词。每当我尝试粘贴一段长文本进行计数时,它就会崩溃或显示随机的内容。

有人有任何建议吗?

这就是我写的:

#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;
}

1 个答案:

答案 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 longunsigned long long,但double用于浮点值。
  • 在迭代序列时,您应该在处理索引时使用无符号整数类型,例如unsigned intstd::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编码。