字符串是打印奇怪的字符 - 用lex中的c代码

时间:2013-07-26 15:22:53

标签: c string char lex dynamic-allocation

下面是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();
                      }
                    }

2 个答案:

答案 0 :(得分:0)

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

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

在你的代码中你分配4个字节(sizeof char)

答案 1 :(得分: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|
           `---'  `----'---'

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

%{
    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教程!