调试断言失败 c >= -1 && c <= 255

Debug Assertation Failed c >= -1 && c <= 255

本文关键字:lt gt 断言 失败 调试      更新时间:2023-10-16

我很难理解代码中的这个运行时错误。这是我班的一项作业,我认为这很容易,但奇怪的事情正在发生。我已经在下面发布了我的代码。

这个任务的提示是创建一个程序,要求用户输入一些单词,然后它应该输出有多少单词。我有一个朋友运行了这个程序,它很有效,然而,每当我尝试运行它时,我都会遇到这个运行时错误。[https://i.stack.imgur.com/Vhqbe.jpg]

请记住,我是C++和编程的初学者,所以我无法理解非常技术性的回答。提前感谢您的帮助。

#include <string>
#include <iostream>
#include <cstring>
using namespace std;
int wordCounter(char *);
int main()
{
    char *stringArray = nullptr;
    stringArray = new char[120];
    cout << "Please enter a saying or a phrase that has more than one word: " << endl;
    cin.getline(stringArray, 120);
    int words = wordCounter(stringArray);
    cout << "Your statement contains " << words << " words." << endl;
    system("pause");
    return 0;
}
int wordCounter(char *stringTest)
{
    char characterToTest;
    int numberOfWords = 0;
    for (int i=0; i < 120; i++)
    {
        characterToTest = *(stringTest + i);
        if (isspace(characterToTest) && i != 120)
        {
            char characterToTestTemp = *(stringTest + (i + 1));
            if (isalnum(characterToTestTemp))
            {
                numberOfWords++;
            }
        }
    }
    return numberOfWords;
}

isspace和朋友们很难正确呼叫。特别是,您不能安全地将char传递给它们,因为char值可能为负数,这是不允许的,正如错误消息所说。

为了安全起见,您应该转换为unsigned char

isspace(static_cast<unsigned char>(characterToTest))

这不是主要问题,您需要首先修复溢出,但这也是您收到错误消息的部分原因。

您不是在输入字符串的终止处停止,而是进入输入缓冲区尾部留下的非输入、不确定的缓冲区数据。

这就是你可能要做的:

int wordCounter(const char *str)
{
    int numberOfWords = 0;
    while (*str)
    {
        // skip any leading whitespace
        while (*str && isspace(static_cast<unsigned char>(*str)))
            ++str;
        // if we're still on string data, we have another word
        if (*str)
        {
            // skip everything up to more whitespace
            while (*str && !isspace(static_cast<unsigned char>(*str)))
                ++str;
            // and count the word
            ++numberOfWords;
        }
    }
    return numberOfWords;
}

或者类似的东西。可能需要应用额外的处理来解释标点符号等。一旦到达输入字符串的终止符,就会停止。

祝你好运。

无论实际读取的输入字符串的长度如何,wordcount函数始终处理120个字符。因此,您正在读取字符串的末尾,并处理未初始化的内存。

Microsoft文档中写道:"如果c不是EOF或在0到0xFF的范围内(包括0和0xFF),则_isctype和_isctype_l的行为是未定义的。当使用调试CRT库并且c不是这些值之一时,函数会引发断言。"

这就是断言的原因。

C字符串是以零结尾的,您必须在循环中测试该条件。

int wordCounter(char *stringTest)
{
    char characterToTest;
    int numberOfWords = 0;
    for (int i = 0; i < 120; i++)
    {
        characterToTest = *(stringTest + i);
        if (characterToTest == 0)  
            break; // <-- exit the loop at the end of the string
        if (isspace(characterToTest) && i != 120)
        {
            char characterToTestTemp = *(stringTest + (i + 1));
            if (isalnum(characterToTestTemp))
            {
                numberOfWords++;
            }
        }
    }
    return numberOfWords;
}

您的计数函数中可能还有其他逻辑错误,比如不计算第一个单词。

感谢大家的帮助。读到这一点(我确实意识到我有一些逻辑错误,如果用户什么都不输入并提交,它仍然会打印1),我能够想出一个稍微不同的方法。

这是修改后的代码。

#include <string>
#include <iostream>
#include <cstring>
using namespace std;
int wordCounter(char *, int);
int main()
{
    cout << "Please enter a saying or a phrase that has more than one word: " << endl;
    string testString;
    getline(cin, testString);
    int stringLength = testString.length();
    char *stringArray = nullptr;
    stringArray = new char[stringLength];
    strcpy(stringArray, testString.c_str());
    int words = wordCounter(stringArray, stringLength);
    cout << "Your statement contains " << words << " words." << endl;
    system("pause");
    return 0;
}
int wordCounter(char *stringTest, int length)
{
    char characterToTest;
    int numberOfWords = 1;
    for (int i=0; i < length; i++)
    {
            characterToTest = *(stringTest + i);
            if (isspace(characterToTest) && (i != length))
            {
                    char characterToTestTemp = *(stringTest + (i + 1));
                    if (isalnum(characterToTestTemp))
                    {
                            numberOfWords++;
                    }
            }
    }
    return numberOfWords;
}