1

下面是 lex 中的 C 代码。我有三个输入字符串,如下所示。前两个打印正确。在第三个输入字符串的末尾,有两个奇怪的字符被打印出来。我知道这是因为空字符。但是我的代码会处理它,而且我的前两个输入字符串不会发生这种情况。

第一个输入字符串:(c,a,b,ma,mb,low) 第二个输入字符串:(c,a,b,ma,mb+1,low) 第三个输入字符串:(c,data, istart, mid,BASE )

执行代码时,func_initial_var 将根据字符串包含“(”,而 func_var 将包含字符串的其余部分。

问题仅在于第三个输入字符串。假设如果我在第三个字符串的末尾添加两个额外的字符,它会正确打印,我猜有两个额外的空间被分配。我的问题是为什么只在第三个输入字符串中?为什么不在前两个?请帮忙。从昨天早上开始,这一直困扰着我。谢谢。

    char *func_var = "";
    char *func_initial_var = "";

<SOME_STATE>.       { char c;
                    func_initial_var = strdup(yytext);
                    c = input();
                    func_var = (char*) malloc(sizeof(char));
                    for(q=0;;q++) {
                        if(c == ')')
                        {
                          func_var[q] = c;
                          printf("%s\n",func_var);
                          BEGIN SOME_STATE_X;
                          break;
                        }
                    func_var[q] = c;
                    printf("%s\n",func_var);
                    temp_func = (char*) realloc(func_var,(q+2)*sizeof(char));
                    if(temp_func != NULL) 
                        {
                        func_var = temp_func;
                        } else {
                      free(func_var);
                      printf("Error allocating memory\n");
                      return 1;
                        }
                    c = input();
                      }
                    }
4

2 回答 2

0

这已经有一段时间没有关闭了,但答案的提示在评论中。问题不在于 lex/flex。理解C中字符、字符数组和字符串之间的区别只是一个问题。从提出的编码错误来看,问题表明初学者在使用字符指针和字符数组进行编码时理解这些差异时存在混淆。总结可能有助于指出一些混淆点。

让我们以图表的形式看一下C中的这些结构:

单个字符可能如下所示:

           .---.
char c;    | c |
           `---'

两个字符的数组可能如下所示:

           .----.----.
char c[2]; |c[0]|c[1]|
           `----'----'

一个由两个字符组成的字符串可能如下所示:

           .---.  .----.----.---.
char *s;   | s--->|s[0]|s[1]|0x0|
           `---'  `----'----'---'

包含单个字符的字符串可能如下所示:

           .---.  .----.---.
char *s;   | s--->|s[0]|0x0|
           `---'  `----'---'

因此,当一个字符或字符数组被复制到一个字符串或被转换为用作字符串时,由于终止null 字节,它将比等效的非字符串长。存在空字节是因为字符串是可变长度构造。它表示字符串的结尾。使用这些知识,可以修改原始示例以使用正确的存储长度并将字符串终止符放置在正确的位置:

%{
    char *func_var = "";
    char *func_initial_var = "";
    char *temp_func;
    static int q;
    #include <string.h>
%}
%s SOME_STATE_X
%%
<INITIAL>.       { char c;
                    func_initial_var = strdup(yytext);
                    c = input();
                    func_var = (char*) malloc(sizeof(char)+1);
                    for(q=0;;q++) {
                        if(c == ')')
                        {
                          func_var[q] = c;
                          func_var[q+1] = 0;
                          printf("%s\n",func_var);
                          BEGIN SOME_STATE_X;
                          break;
                        }
                    func_var[q] = c;
                    func_var[q+1] = 0;
                    printf("%s\n",func_var);
                    temp_func = (char*) realloc(func_var,(q+2)*sizeof(char)+1);
                    if(temp_func != NULL) 
                        {
                        func_var = temp_func;
                        } else {
                      free(func_var);
                      printf("Error allocating memory\n");
                      return 1;
                        }
                    c = input();
                      }
                    }

对于示例测试用例,此代码现在运行并生成以下内容:

(c,data, istart, mid,BASE)
c
c,
c,d
c,da
c,dat
c,data
c,data,
c,data,
c,data, i
c,data, is
c,data, ist
c,data, ista
c,data, istar
c,data, istart
c,data, istart,
c,data, istart,
c,data, istart, m
c,data, istart, mi
c,data, istart, mid
c,data, istart, mid,
c,data, istart, mid,B
c,data, istart, mid,BA
c,data, istart, mid,BAS
c,data, istart, mid,BASE
c,data, istart, mid,BASE)

现在代码可能不是使用该工具的最佳方式lex,但这不是 lex教程!

于 2015-04-21T10:32:11.167 回答
0

您可以尝试分配更多内存,例如:

func_var = (char*) malloc(sizeof(char)* strlen(func_initial_var));

在您的代码中,您分配了 4 个字节(字符大小)

于 2013-07-26T15:35:14.340 回答