【问题标题】:Use strtok() to break string into 3 parts使用 strtok() 将字符串分成 3 部分
【发布时间】:2014-04-07 00:05:54
【问题描述】:

以下代码行给我一个分段错误。寄存器是:fgets之后的inputPtr = 00 PRNT 02(来自stdin的正确输入),第一个strtok()之后的inputPtr = 00,第二个strtok()之后的inputPtr =(null)

返回 3 的 if/else;是错误检查。

据我了解,问题是对 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, " ");

【问题讨论】:

  • fgets(input, 15, stdin); 还是fgets(inputPtr, 15, stdin);

标签: c string segmentation-fault strtok


【解决方案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, " ");

【讨论】:

    【解决方案2】:

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 2013-08-17
      • 2022-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多