以下代码行给出了分段错误。寄存器是:inputPtr = 00 PRNT 02(来自stdin的正确输入)fgets后,inputPtr = 00后第一个strtok(),inputPtr =(null)后第二个strtok()
if / else with return 3;是一个错误检查。
我理解的问题是对strtok()的第二次调用不是在PRNT中读取,所以我得到了段错误发生的原因。我真的很想能够阅读PRNT。 一点点帮助会很棒!谢谢!
fgets(input, 15, stdin);
/*Tokenize instr00 into "00"(instructionCounter) "INST"(operationCode) and "OP"(operand)*/
if(atoi(strtok(inputPtr, " ")) >= 0 && atoi(strtok(inputPtr, " ")) <= 99)
{
*instructionCounter = atoi(strtok(inputPtr, " "));
}
else
{
return 3;
}
inputPtr = strtok(NULL, " ");
答案 0 :(得分:1)
strtok
的使用方式与您使用的方式不同。以下是C++ Reference的一些文档:
在第一次调用时,函数需要一个C字符串作为str的参数,其第一个字符用作扫描标记的起始位置。 在后续调用中,函数需要一个空指针 ,并在最后一个标记结束后立即使用该位置作为扫描的新起始位置。
试试这个:
#include <stdio.h>
#include <string.h>
int main()
{
// fgets(input, 15, stdin);
char input[20]; // = "00 PRNT 02";
char* firstToken = NULL;
char* secondToken = NULL;
char* thirdToken = NULL;
int instructionCounter = 0;
strcpy(input, "00 PRNT 02");
firstToken = strtok(input, " ");
secondToken = strtok(NULL, " ");
thirdToken = strtok(NULL, " ");
instructionCounter = atoi(firstToken);
fprintf(stdout, "First token: %s\n", firstToken);
fprintf(stdout, "Second token: %s\n", secondToken);
fprintf(stdout, "Third token: %s\n", thirdToken);
fprintf(stdout, "Instruction Counter: %d\n", instructionCounter);
return 0;
}
答案 1 :(得分:1)
让我们进行以下测试。
fgets(inputPtr, 15, stdin);
现在inputPtr
的值为"00 PRNT 02"
现在使用strtok获取“00”
char *p = strtok(inputStr," ");
现在printf("%s",p)
提供"00"
作为输出。
strtok是否为“00”分配新内存并将地址返回给p? 答案是否。它只返回指向第一个字符的指针,并将其内部指针移动到下一个标记的开头。因此,下次调用
strtok(NULL," ")
时,它将从该内部指针开始。
因此p
指向inputPtr
的第一个字符。但printf
打印字符串,直到遇到空字符'\0'
。因此"00"
后跟p
后跟空字符。但由于p
指向inputStr
,所以inputStr
也是如此。
因此,在第一个strtok
之后,系统将" "
之后的初始"00"
(空格)替换为空字符。
您可以使用以下命令序列进行检查。
char *p = strtok(inputStr," ");
printf("%s",p); //output is "00"
printf("%s",inputStr); // output is "00"
因此,当您第二次执行p = strtok(inputStr," ");
时,您只会对字符串"00"
进行标记,而不是"00 PRNT 02"
,因此您不会打印PRNT
。不要再打电话了。修改后的代码如下。
fgets(inputPtr, 15, stdin);
int a = atoi(strtok(inputPtr, " "));
if(a >= 0 && a <= 99)
{
*instructionCounter = a;
}
else
{
return 3;
}
inputPtr = strtok(NULL, " ");