Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/kubernetes/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C strtok问题和分段错误_C_Segmentation Fault_Strtok - Fatal编程技术网

C strtok问题和分段错误

C strtok问题和分段错误,c,segmentation-fault,strtok,C,Segmentation Fault,Strtok,我有两个助手函数来分解十进制价格格式的字符串,即“23.00”、“2.30” 考虑这一点: char price[4] = "2.20"; unsigned getDollars(char *price) { return atoi(strtok(price, ".")); } unsigned getCents(char *price) { strtok(price, "."); return atoi(st

我有两个助手函数来分解十进制价格格式的字符串,即“23.00”、“2.30”

考虑这一点:

char price[4] = "2.20";

    unsigned getDollars(char *price)
    {
       return atoi(strtok(price, "."));
    }

    unsigned getCents(char *price)
    {
       strtok(price, ".");
       return atoi(strtok(NULL, "."));
    }
现在,当我运行以下命令时,我得到一个分段错误:

printf("%u\n", getDollars(string));
printf("%u\n", getCents(string));
然而,当我单独运行它们时,没有一个接一个,它们工作得很好。我错过了什么?我必须对strtok进行某种重置吗

我的解决方案:

根据我从下面选择的答案中获得的关于strtok的知识,我更改了helper函数的实现,以便它们首先复制传入的字符串,从而屏蔽原始字符串并防止出现此问题:

    #define MAX_PRICE_LEN 5 /* Assumes no prices goes over 99.99 */

unsigned getDollars(char *price)
{
   /* Copy the string to prevent strtok from changing the original */
   char copy[MAX_PRICE_LEN];
   char tok[MAX_PRICE_LEN];

   /* Create a copy of the original string */
   strcpy(copy, price);

   strcpy(tok, strtok(copy, "."));

   /* Return 0 if format was wrong */
   if(tok == NULL) return 0;
   else return atoi(tok);
}

unsigned getCents(char *price)
{
   char copy[MAX_PRICE_LEN];
   char tok[MAX_PRICE_LEN];
   strcpy(copy, price);

   /* Skip this first part of the price */
   strtok(copy, ".");
   strcpy(tok, strtok(NULL, "."));

   /* Return 0 if format was wrong */
   if(tok == NULL) return 0;
   else return atoi(tok);
}
由于
strtok()
修改输入字符串,因此在调用
getDollars()
后,如果在
getCents()
函数中找不到分隔符,就会遇到问题

请注意,
strtok()
在找不到分隔符时返回空指针。您的代码没有检查strtok()是否找到了它要查找的内容—这总是有风险的


您对问题的更新表明您至少了解了
strtok()
的一些危险(邪恶?)。但是,我建议更好的解决方案应该只使用
strchr()

首先,我们可以观察到,
atoi()
无论如何都会在“
”停止转换,因此我们可以简化
get$s()
到:

unsigned getDollars(const char *price)
{
    return(atoi(price));
}
我们可以使用不修改字符串的
strchr()
,找到
,然后处理后面的文本:

unsigned getCents(const char *price)
{
    const char *dot = strchr(price, '.');
    return((dot == 0) ? 0 : atoi(dot+1));
}
我觉得简单多了


还有一个问题:假设字符串是26.6;您必须比上面修订的
getCents()
更加努力,才能使其返回60而不是6。另外,给定26.650,它将返回650,而不是65。

这是:

char price[4] = "2.20";
price
上省略nul终止符。我想你想要这个:

char price[5] = "2.20";
或者更好:

char price[] = "2.20";
因此,当您第二次尝试从
price
中获取代币时,您将耗尽缓冲区的末尾。幸运的是,
getCents()
不会在每次运行时都出错


在对字符串使用
strtok
之前,您几乎应该复制一个字符串(以避免Jonathan Leffler指出的问题)。

我认为两个答案/问题都是因素。我的问题是在同一个字符串上重新使用
strtok()
。你的是一个特殊的非字符串。谢谢你的提示,我已经接受了。