-1表示的是什么?

时间:2012-03-01 13:55:32

标签: c++ ascii

我正在使用我的C ++类中的自动摘要系统,并且对我正在进行的ASCII比较之一有疑问。这是代码:

    char ch;
    string sentence;
    pair<char, char> sentenceCheck;
    int counter = 0;
    while (!ifs2.eof())
    {
        ch = ifs2.get();
        ch = tolower(ch);

        if (ch == 13)
            ch = ifs2.get();

        if (ch != 10 && ch != '?' && ch != '!' && ch != '.')
            sentence += ch;

        sentenceCheck.first = sentenceCheck.second;
        sentenceCheck.second = ch;

        cout << sentenceCheck.first << "-" << (int)sentenceCheck.first << " ---- " << sentenceCheck.second << "-" << (int)sentenceCheck.second << endl;

        if(sentenceCheck.second == ' ' || sentenceCheck.second == 10 || sentenceCheck.second == -1)
        {
            if(sentenceCheck.first == '?' || sentenceCheck.first == '!' || sentenceCheck.first == '.')
            {
                istringstream s(sentence);
                while(s >> wordInSentence)
                {
                    sentenceWordMap.insert(pair<string, int>(wordInSentence, 0));
                }
                //sentenceList.push_back(pair<string, int>(sentence, 0));
                sentence.clear();
            }
        }
    }

这里所做的(使用两个if语句)正在检查是否已在稍后要分析和处理的文本中开始新句子。条件工作,但只是因为我们发现我们必须检查-1。任何想法代表什么?

5 个答案:

答案 0 :(得分:6)

-1不表示ASCII中的任何内容。所有ASCII码都在[0,127]范围内。 C ++甚至不保证-1char的有效值。

问题是您没有检查ifs2.get()的返回值,该值返回int(不是char!),结尾可能是-1的文件。检查这个的正确方法是

int ch = ifs2.get();
if (!ifs2)
    // break the loop

因为EOF值不能保证为-1(实际上是std::char_traits<char>::eof())。

(顺便说一句,你不应该把ASCII代码写成幻数;使用\n代替换行,\r代表回车。)

答案 1 :(得分:2)

while结构不正确:您需要在eof()之后立即检查get()

for (;;)
{
    ch = ifs2.get();
    if (ifs2.eof()) break;
    ch = tolower(ch);

    if (ch == 13)
    {
        ch = ifs2.get();
        if (ifs2.eof()) break;
    }

    ...
}

-1可能是EOF指标。

注意(正如已经说明的那样)get()会返回int,而不是char

答案 2 :(得分:1)

这不是ASCII,这是istream::get

返回的错误
ch = ifs2.get();

这可能是EOF,即你的输入用完了。

答案 3 :(得分:1)

作为ASCII字符-1不代表任何东西(也就是说-1不是有效的ASCII值)。作为get()的返回值,这意味着读取操作失败 - 很可能是由于文件结束了。

请注意,如果下一次调用get将因为文件结束而失败,则eof()函数不会返回true - 如果上一次调用失败,则返回true到达文件的结尾。

答案 4 :(得分:0)

检查-1工作的事实是一个意外,并没有任何结果 使用ASCII值(仅使用0127)。您的代码将失败 如果普通字符是无符号的(使用VC ++编译/J,我认为), 或者EOF不是-1(很少见,但所有保证的都是它 负)。如果输入正好,您的代码也将失败 Latin-1,它包含'ÿ'

您的代码中的基本问题是您没有检查结束 文件正确。将测试置于循环顶部不起作用; 在使用之前,您需要在输入之后测试失败(不是eof() 读取的值。有几种方法可以做到这一点;在你的情况下, 最简单的可能是使用:

if ( !ifs2.get(ch) ) {
    //  Input failed...
}

或者,您可以将ch设为int,然后执行:

ch = ifs2.get();
if ( ch == EOF ) {
    //  Input failed...
}

这样做的好处是不再需要对tolower进行以下调用 未定义的行为(tolower接受一个int,它必须在范围内 [0...UCHAR_MAX]EOF - 如果简单char已签署,则不是 保证这一点)。另一方面,它不允许链接,即 你不能写相当于:

while ( ifs2.get( sentenceCheck.first )
        && ifs2.get( sentenceCheck.second ) ) {
    //  ...
}

(在某些情况下可能有用)。

FWIW:您正在使用的技术称为滑动窗口 流入一个流,值得把它推到一个单独的类中 处理保持窗口填充和更新的逻辑。 或者,可以使用简单的状态机来解决您的问题。

我肯定会避免使用魔术常数:如果你想检查 回车,与'\r'比较。同样,换行符为'\n', 在外if,看起来你想要检查空格 (isspace( static_cast<unsigned char>( sentenceCheck.second ) )), 而不是比较价值。

我可能还会补充一点,你的代码无法正确处理那些句子 以引用结束,如This is the "text in your input.";它也是 没有像Mr. Jones is here.这样的缩写。但那些问题 可能超出了您的任务范围。 (缩写一个是 可能无法完全解决:有时"etc."是一个结束 句子,有时它不是。)