可能导致调试断言错误的原因.具体来说,在我的代码中

What can cause a Debug Assertion Error. Specifically, in my code

本文关键字:具体来说 我的 代码 调试 错误 断言      更新时间:2023-10-16

我正在为一个学校项目编写编译器,这项作业要求我将文本文件的标记打印到控制台窗口。我想明确表示我不想为我做作业。

我一直在使用这个愚蠢的函数,它遍历文件,并将一个char或c字符串值(我的导师在他的指令中对此含糊其辞…(连接到一个名为"token"的字符串变量。我可以很好地遍历文件的第一行,即"main((",但当我尝试访问下一行时,我会得到两个错误中的一个。第一个是字符串下标超出范围错误,尽管我认为这是因为我试图访问不存在的字符串数组的一部分。我遇到的最常见的错误是调试断言错误:

调试断言失败Final.exe文件:f:\dd\vctools\crt_bld\self_x86\crt\src\isctype.c表达式:(无符号((c+1(<=256

我已经包含了我的函数及其相关的头文件。除了一个函数调用之外,主要什么都没有发生。如果可能的话,你能看到我没有看到的东西吗。我意识到我的代码结构很差,我不会撒谎(毕竟我还在上学(。因此,欢迎任何评论、批评和建议。永远感谢你的光临。

.CPP文件(现在是这样(

    #include <iostream> 
    #include <string>
    using namespace std; 
    void tokenWork::openFile()
    {
        fileName = "test.txt"; 
        source.open(fileName);
        if(!source.is_open())
        {
       cout << "Cannot find file " << endl; 
        }
    }
    void tokenWork::traveseLine()
    {
    pos = 0; 
    while (!source.eof())
    {  
          getline(source,myLine); 
          int length = myLine.length(); 
          letters = new char[length];
          myLine.copy(letters,length); 
          c = letters[pos]; 
          if (isalpha(c))
             token = token + myLine[pos]; 
          else if (isdigit(c))
             token = token + letters; 
          else 
          {
             cout << token << endl; 
             token = ""; 
          }
          if (c == '{' || c == '}' || c == '+' || c == '=' || myLine[pos] == '(' || c == ')' || c == ';')
                cout << myLine[pos] << endl;  
          c = letters[pos++]; 
    }
}

.h文件

    #ifndef H_LEX
    #define H_LEX
    #include <string> 
    #include <iostream> 
    #include <fstream> 
    using namespace std; 
    class tokenWork
    {
    public: 
    std::string fileName; 
    std::string myLine; 
    std::string token; 
    int pos; 
    int length; 
    int c;
    char *letters; 
    ifstream source; 
    void openFile(); 
    void traveseLine(); 
    void closeFile(); 
};
    #endif 

当您向std::isalpha/isdigit传递一个值>255的参数时,调试断言错误源于对它的调用,这是类型char(您可能应该在此处使用它而不是int(可以容纳的最大值。虽然我不能告诉你确切的来源,因为你没有提供源文件,但你应该能够很容易地自己弄清楚:在调试器下运行程序,它会在断言时中断。在调用堆栈中向上移动并检查变量的值,这将为您提供线索。

几个提示:

  • 您在这里使用的是c++,不需要使用原始的char数组。请改用std::string
  • 不要使用名称空间std;在头文件中:包含该文件的所有内容都将导入整个std命名空间
  • 如果包含在标头中,则不必再次将其包含在源文件中
  • 学会使用调试器,它是一个非常宝贵的工具,可以帮助您了解错误的原因

如果你只想在每一行打印标记,我会对你所做的所有额外工作感到非常困惑。缩小你的功能(和一个小的改变(应该会让你有一个开始:

// note, poorly named function, it traverses the whole file
void tokenWork::traveseLine()
{
pos = 0; 
while (!source.eof())
{  
   getline(source,myLine); 
   int len = myLine.size();
   // NOTE: This was missing from your code, it traverses the line
   //       that was read in with getline() above.
   for(int x = 0; x < len; ++x)
   {
       // NOTE: This is (in my opinion) a slightly more readable
       //       version of your if() statement above on tokens
       //       It doesn't have all your tokens, additional ones
       //       can be added by adding a case for them above the 
       //       line that prints them out.  Since there is no break
       //       statement, the functionality for all the cases above 
       //       fall through so they all get printed out.
       switch(myLine[x])
       {
          case '{':
          case '}':
          case '+':
          case '=':
          // add additional tokens as case statements as necessary
            cout << myLine[x] << endl;  // print it out
            break;
          default:   // not a token
            break;  
       }
   }
}

您忘记了

#include <cctype>

以便使用isdigit((和isalpha((

和这个

c = letters[pos++];

看起来像是一个bug的来源。pos总是递增,但它会停止吗?如果它到达最后一个字符(letters.length((-1(,并且您点击了这一行:增量,会发生什么?我怀疑数组越界了。

很难指出代码中的特定位置——它有很多问题。。。

你看到的错误很可能是造成的

token = token + letters; 

letters不是以null结尾的(string::copy不提供null结尾,而且您无论如何都不会为null保留空间(,所以+运算符从末尾掉下来,遇到了一些讨厌的东西。

除此之外,似乎每个getline增加pos一次,但从未重置。您的代码看起来应该有一个内部循环,但我看不到任何内部循环。