strtok 和分段错误的问题 [英] Problem with strtok and segmentation fault

查看:15
本文介绍了strtok 和分段错误的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个辅助函数来分解十进制价格格式的字符串,即."23.00", "2.30"

I have two helper functions to break up strings in the format of decimal prices ie. "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, "."));
    }

现在,当我运行以下命令时,我遇到了分段错误:

Now when I run the below I get a segmentation fault:

printf("%u
", getDollars(string));
printf("%u
", getCents(string));

但是,当我单独运行它们而没有一个跟随另一个时,它们工作正常.我在这里想念什么?我必须对 strtok 进行某种重置吗??

However when I run them seperately without one following the other, they work fine. What am I missing here? Do I have to do some sort of resetting of strtok??

我的解决方案:

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

With the knowledge about strtok I gained from the answer I chose below, I changed the implementation of the helper functions so that they copy the passed in string first, thus shielding the original string and preventing this problem:

    #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()修改了输入字符串,在getCents中找不到分隔符会遇到问题() 函数后调用 getDollars().

Because strtok() modifies the input string, you run into problems when it fails to find the delimiter in the getCents() function after you call getDollars().

请注意,strtok() 在找不到分隔符时会返回一个空指针.您的代码没有检查 strtok() 是否找到了它正在寻找的东西——这总是有风险的.

Note that strtok() returns a null pointer when it fails to find the delimiter. Your code does not check that strtok() found what it was looking for - which is always risky.

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

Your update to the question demonstrates that you have learned about at least some of the perils (evils?) of strtok(). However, I would suggest that a better solution would use just strchr().

首先,我们可以观察到 atoi() 无论如何都会在 '.' 处停止转换,所以我们可以简化getDollars() 到:

First, we can observe that atoi() will stop converting at the '.' anyway, so we can simplify getDollars() to:

unsigned getDollars(const char *price)
{
    return(atoi(price));
}

我们可以使用 strchr() - 它不修改字符串 - 找到 '.' 然后处理它后面的文本:

We can use strchr() - which does not modify the string - to find the '.' and then process the text after it:

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.

One more gotcha: suppose the string is 26.6; you are going to have to work harder than the revised getCents() just above does to get that to return 60 instead of 6. Also, given 26.650, it will return 650, not 65.

这篇关于strtok 和分段错误的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆