问题描述
我正在为必须使用Flex的学校分配作业。我正在尝试执行一些简单的字符串操作,但是遇到了一些我不理解的奇怪结果。以下代码应该用相应的数字替换输入的第二个字母。
我的代码:
uid [a-z][a-z][a-z]+
%%
{uid} {
char ID[strlen(yytext)];
strncat(ID,yytext,1);
char comp = yytext[1];
if (comp=='a'||comp=='j'||comp=='s'){
strcat(ID,"1");
}else if(comp=='b'||comp=='k'||comp=='t'){
strcat(ID,"2");
}else if(comp=='c'||comp=='l'||comp=='u'){
strcat(ID,"3");
}else if(comp=='d'||comp=='m'||comp=='v'){
strcat(ID,"4");
}else if(comp=='e'||comp=='n'||comp=='w'){
strcat(ID,"5");
}else if(comp=='f'||comp=='o'||comp=='x'){
strcat(ID,"6");
}else if(comp=='g'||comp=='p'||comp=='y'){
strcat(ID,"7");
}else if(comp=='h'||comp=='q'||comp=='z'){
strcat(ID,"8");
}else if(comp=='i'||comp=='r'){
strcat(ID,"9");
}
strncat(ID,yytext+2,strlen(yytext)-2);
printf("%s\n",ID);
printf("ID strlen: %d\n",strlen(ID));
return 1;
运行以上代码后得到的结果是:
所以我不太确定为什么会得到上述结果,该结果也不是完全可重复的,我得到的随机字母和字符总是不同的。我查找了有关如何操作字符串的多种指南,但无法弄清自己一生中做错了什么。第一个输入的结果是正确的,但是我尝试输入的第二个输入的结果中包含不可读的字符。
解决方法
C99可变长度数组(VLA)
char ID[strlen(yytext)];
的大小不足以容纳完整的yytext
。如果C字符串s
的长度(即strlen(s)
为n
,则需要n+1
个字节的存储空间。这是因为字符串以空字节结尾。
strncat(ID,yytext,1);
strncat
函数需要使用有效字符串作为参数:以null终止的字符数组。它将字符附加到左参数。但是ID
数组尚未初始化。
另一个问题是strncat
函数和它的strncpy
堂兄一样,不会以空字符终止目标缓冲区(在琐碎的情况下,字符串短于指定的{{1}时除外) }。
这里可能是其中之一:
n
或
snprintf(ID,1,"%s",yytext);
或
sprintf(ID,"%.1s",yytext);
我将按照以下内容写整件事:
char ID[strlen(yytext)] = ""; // zero-initialize it
ID[0] == yytext[0]; // ID now string of length 1.
这个想法似乎只是用数字代码代替第二个字符,或者根本不用任何代码。我们知道char ID[strlen(yytext)+1];
int comp = yytext[1];
int code = -1;
switch (comp) {
case 'a': case 'j': case 's':
code = 1;
break;
// ... similarly for other cases:
}
if (code != -1)
sprintf(ID,"%c%d%s",yytext[0],code,yytext + 2);
else
sprintf(ID,"%c%s",yytext + 2);
足够大,可以容纳ID
的结果,只要sprintf
是0到9范围内的整数。
这是另一种方式:
code