如何修复';strtok销毁原始字符串';在c中
我正在为汇编程序编写一个编译器,我需要对从文件中获取的文本进行解析,而不需要对原始字符串进行任何更改。我用于将字符串复制到缓冲区的函数是如何修复';strtok销毁原始字符串';在c中,c,string,strtok,C,String,Strtok,我正在为汇编程序编写一个编译器,我需要对从文件中获取的文本进行解析,而不需要对原始字符串进行任何更改。我用于将字符串复制到缓冲区的函数是strcpy,用于剪切字符串的函数是strtok,用于剪切缓冲区。 一切都很完美,但在使用函数addressingConstantIndex后尝试剪切原始字符串时,我得到了null 我试图将缓冲区的类型更改为字符指针,但实际上没有起作用。我想主要的问题在于我将原始字符串复制到缓冲区的方式 int main(){ char desti[MAXCHAR];
strcpy
,用于剪切字符串的函数是strtok
,用于剪切缓冲区。
一切都很完美,但在使用函数addressingConstantIndex
后尝试剪切原始字符串时,我得到了null
我试图将缓冲区的类型更改为字符指针,但实际上没有起作用。我想主要的问题在于我将原始字符串复制到缓冲区的方式
int main(){
char desti[MAXCHAR];
char *temp;
char *token;
temp = "mov LIST[5] , r4";
strcpy(desti,temp);
printf("\ndest is : %s\n", desti);
token = strtok(desti," ");
printf("\nthe Token in Main is : %s \n", token);
token = strtok(NULL, ",");
printf("\nthe Token in Main is : %s\n", token);
printf("\nThe value is %d \n ",addressingConstantIndex(token));
token = strtok(NULL, " ,");
printf("\nthe Token in Main is : %s\n", token);
return 0;
}
int addressingConstantIndex(char * str) {
char buf[43];
char *token;
int ans;
strcpy(buf, str);
token = strtok(buf, "[");
printf("The string is %s\n",str);
if (token != NULL)
{
printf("the token is %s\n", token);
token = strtok(NULL, "]");
printf("the token is %s\n", token);
if(isOnlyNumber(token))
{
token = strtok(NULL, " ");
if (checkIfSpaces(token,0) == ERROR)
{
printf("ERROR: Extra characters after last bracket %s \n", str);
ans = ERROR;
} else
ans = OK;
} else {
printf("ERROR: Unknown string - %s - its not a macro & not a number.\n", token);
ans = ERROR;
}
} else {
printf("ERROR: %s , its not a LABEL", token);
ans = ERROR;
}
return ans;
}
int isOnlyNumber(char *str) {
int i, isNumber;
i = 0;
isNumber = 1;
if (!isdigit(str[i]) && !(str[i] == '-' || str[i] == '+'))
{
isNumber = ERROR;
}
i++;
while (i < strlen(str) && isNumber == 1)
{
if (!(isdigit(str[i]))) {
if (isspace(str[i]))
isNumber = checkIfSpaces(str, i);
else
isNumber = ERROR;
}
i++;
}
return isNumber;
}
int checkIfSpaces(char *str, int index) {
int i;
if (str == NULL)
{
return OK;
} else {
for (i = index; i < strlen(str); i++)
{
if (!isspace(str[i])) return ERROR;
}
}
return OK;
}
真正的结果是:
dest is : mov LIST[5] , r4
the Token in Main is : mov
the Token in Main is : LIST[5]
The string is LIST[5]
the token is LIST
the token is 5
The value is 1
the Token in Main is : (null)
不同之处在于结果的最后一行。问题在于
strtok()
维护一个指向当前字符串位置的静态指针。因此,在addressingConstantIndex()
中,您开始处理本地buf
,这样当您返回main()
时,它不再解析desti
,而是从addressingConstantIndex()
解析现在超出范围的buf
对现有代码最简单的更改是在Windows上使用strtok\u r()
(或strtok\u s()
):
然后在寻址Constantindex()中类似地:
strtok
在每次调用时将字符串中的分隔符替换为NULL。您的代码正在主级别查找“LIST[5]”标记,此时它已将“,”替换为NULL
在addressingConstantIndex
中,strtok
用新字符串重置并正确解析(尽管您的函数类型为void而不是int)
在主级,strtok
没有被重置,因此它将继续解析addressingConstantIndex
中使用的字符串
要解决此问题,您需要再次重置strtok。但是,您不能仅使用strtok(desti,“,”)
调用它,因为desti
将以前调用的所有分隔符设置为NULL
一个快速的解决方案是复制令牌,以便在主级将其馈送到addressingConstantIndex
,并在下一级解析之前完成主级
int main(){
char desti[MAXCHAR];
char *temp;
char *token;
temp = "mov LIST[5] , r4";
strcpy(desti,temp);
printf("\ndest is : %s\n", desti);
token = strtok(desti," ");
printf("\nMnemonic : %s \n", token);
token = strtok(NULL, ",");
printf("\nLIst bit: %s\n", token);
char buf[80]; //Save the token
strcpy(buf, token);
token = strtok(NULL, " ,"); //Finish this level of processing
printf("\nRegister: %s\n", token);
//Continue at the next level with copy
printf("\nThe value is %d \n ",addressingConstantIndex(buf));
return 0;
}
尽管strtok\u r
解决方案可能更符合您的需要,但如果您需要保留原始字符串,请复制字符串并在副本上使用strtok()
,或者不要使用strtok()
。还要注意,不能同时使用strtok()
分析两个不同的字符串。基本上,strtok();这是许多次错误的函数之一。请尝试strspn()
和strcspn()
。我需要对我得到的字符串的每个部分进行验证。您的平台是否有strtok\r
?
char* context = 0 ;
token = strtok_r( desti, " ", &context ) ;
printf("\nthe Token in Main is : %s \n", token);
token = strtok_r( NULL, ",", &context ) ;
...
char* context = 0 ;
token = strtok_r(buf, "[", &context);
...
int main(){
char desti[MAXCHAR];
char *temp;
char *token;
temp = "mov LIST[5] , r4";
strcpy(desti,temp);
printf("\ndest is : %s\n", desti);
token = strtok(desti," ");
printf("\nMnemonic : %s \n", token);
token = strtok(NULL, ",");
printf("\nLIst bit: %s\n", token);
char buf[80]; //Save the token
strcpy(buf, token);
token = strtok(NULL, " ,"); //Finish this level of processing
printf("\nRegister: %s\n", token);
//Continue at the next level with copy
printf("\nThe value is %d \n ",addressingConstantIndex(buf));
return 0;
}