【问题标题】:Attempting to Create a Simple "Debugger" (A Trivial C Program)尝试创建一个简单的“调试器”(一个简单的 C 程序)
【发布时间】:2014-11-18 10:17:25
【问题描述】:

我尝试创建一个简单的 C 程序,当大括号“不平衡”时通知用户。然而,结果往往是不正确的。例如,输入 {{}} 提示错误语句,而不是“未检测到错误”。任何帮助将不胜感激:)

注意:我是初学者! :)

#include <stdio.h>

main()
{
        char filter[100]; // "Filtered" array (contains braces)
        char s[100]; 

        int i; // Increment variables
        int j;
        int z;
        int l;
        int c;

        int linecount = 0;
        int pair = 0; // Brace pair {}
        int k = 0;
        int y = 1;


        while (y == 1)
        {

                linecount++;

                for (i = 0; i < 99 &&  (c=getchar()) != '\n' && c != EOF; i++) 
                        s[i] = c; // Initializing array with a line

                if (c == EOF)
                        break;


                for (j = 1; j <= i; j++)
                {
                        if (s[j] == '{'|| s[j] == '}') // Filter extraneous characters
                                s[j] = filter[k++];
                }

                if (filter[0] == '{') // Determines if filtered array starts with {
                {

                        for (z = 0, l = (k-1);  z < k && l >= 0; z++, l--) //Determine pairs
                        {
                                if (filter[z] == '{' && filter[l] == '}')
                                        pair++;
                        }

                        if (pair > 0)
                                printf("No errors detected.\n");
                }

                else
                        printf("Line %d: syntactic error.\n", linecount);
        }
}
~

【问题讨论】:

  • 正确解析(甚至只是词法分析)C 确实相当具有挑战性。你可能会改进你所拥有的,但是完全正确地完成这项工作是一项大量的工作。
  • 您的读取循环从 0 开始存储在 s,但过滤器循环从 1 开始,因此错过了 s[0]
  • 谢谢,弗雷德!我改了j = 0,但结果还是不正确。另外,分配 l = (k-1) 是正确的,对吧?因为当 j = i 时,k 将在“过滤器循环”中加一。
  • 您确实应该在编译时包含所有警告和调试信息 (gcc -Wall -g) 并学习如何使用调试器 (gdb)...使用调试器是基本技能。
  • 你的程序不是“调试器”,它是parser

标签: c arrays string indices


【解决方案1】:

实现“不平衡”检查的更好、更简洁的方法是使用堆栈。 整体算法可以简化为。

  1. 如果遇到{ 将其推入堆栈。
  2. 如果遇到 '}' 检查堆栈是否为空, 如果没有,则从堆栈中弹出},即对于每个},应该有一个{ 如果堆栈为空,则有一些不平衡}

【讨论】:

    【解决方案2】:

    没有必要写这么复杂的程序。只需使用计数器来计算括号level。就这样……

    /* At the beginning of the file/funciton */
    curlyCounter = 0;
    
    /* read characters one at a time in a variable called c */
    
    if (c == '{') curlyCounter++;
    if (c == '}') curlyCounter--;
    
    /* at the end of the program or ufnction */
    
    if (c == 0){
        /* Correctly formed expression */
    } else {
        /* Incorrectly formed expression*/
    }
    

    这要简单得多,应该可以解决您的问题。请注意,如果您还想求解其他括号,则需要有更多参与的求解器。您将需要递归堆栈实现。

    【讨论】:

    • 谢谢!一个简洁而合乎逻辑的解决方案:)
    • “} {”怎么样?最终结果仍然为零。 nu11p01n73R 的基于堆栈的解决方案似乎适合我。
    【解决方案3】:

    我首先注意到的是s[j] 在左侧:s[j] = filter[k++]。所以s[] 会被filter[] 的空元素填满

    其次,由于for(z, l)filter[] 的开头迭代到两个变量的结尾,并且它们的值是对称的,因此您仔细检查filter[] 的每个元素。

    第三,由于zl的值是对称的,这个条件只有在大括号的排列是这样的情况下才有效:{{{}}},或{{}}或@987654332 @,而不是 {{}}}{}}}。因为即使在filter[1] = '}'filter[k-2] = '}' 时,pair 在最后一种情况下也会增加

    此外,当您到达filter[2] = '}'(中间的右侧)和filter[k-3] = '}'(中间的左侧)时。

    编辑:顺便说一句,我说错了s[] 被“空”元素填充,我的意思是未定义:因为filter[] 是一个静态数组,如果不是,它的元素都设置为 0显式初始化,至少根据 C99 标准行为。

    【讨论】:

      猜你喜欢
      • 2015-07-27
      • 1970-01-01
      • 1970-01-01
      • 2010-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多