问题的strtok和分割故障 [英] Problem with strtok and segmentation fault

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

问题描述

我有两个辅助功能,打破了格式字符串的十进制价格IE浏览器。 23.00,2.30

考虑一下:

 焦炭价格[4] =2.20;    无符号getDollars(字符*价格)
    {
       返回的atoi(strtok的(价格)。);
    }    无符号getCents(字符*价格)
    {
       strtok的(价格,。);
       返回的atoi(的strtok(NULL,。));
    }

现在,当我运行下面的我得到一个分段错误:

 的printf(%U \\ N,getDollars(字符串));
的printf(%U \\ N,getCents(字符串));

然而,当我无一遵循另一单独运行它们,它们做工精细。我缺少的是在这里吗?我必须做的strtok的重置的某种??

我的解决方案:

使用约我从我在下面选择的答案获得的strtok的知识,我改变了辅助功能的实现,让他们复制的字符串传递第一名,从而屏蔽了原始字符串和preventing此问题:

 的#define MAX_PRICE_LEN 5 / *假设没有价格越过99.99 * /无符号getDollars(字符*价格)
{
   / *更改原来的*复制字符串prevent的strtok /
   字符复制[MAX_PRICE_LEN]
   焦炭TOK [MAX_PRICE_LEN]   / *创建原始字符串的副本* /
   的strcpy(复制,价格);   的strcpy(TOK,strtok的(复制)。);   / *则返回0,如果格式是错误的* /
   如果(TOK == NULL)返回0;
   否则返回的atoi(TOK);
}无符号getCents(字符*价格)
{
   字符复制[MAX_PRICE_LEN]
   焦炭TOK [MAX_PRICE_LEN]
   的strcpy(复制,价格);   / *跳到价格*的第一部分/
   strtok的(复印件,);
   的strcpy(TOK,strtok的(NULL,)。);   / *则返回0,如果格式是错误的* /
   如果(TOK == NULL)返回0;
   否则返回的atoi(TOK);
}


解决方案

由于的strtok()修改输入的字符串,你遇到问题时没有找到的分隔符在 getCents()之后您调用函数 getDollars()

注意的strtok()时没有找到的分隔符返回一个空指针。您code不检查的strtok()发现,它正在寻找 - 这始终是有风险的。


您的问题更新表明您已经了解了至少有一些危险的(邪恶?)的strtok的()。不过,我认为更好的解决方案将只使用和strchr()

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

 无符号getDollars(为const char *价格)
{
    回报(与atoi(价格));
}

我们可以使用和strchr() - 不修改字符串 - 找到 和那么后处理文本:

 无符号getCents(为const char *价格)
{
    为const char *点=和strchr(价格,'。');
    收益率((点== 0)?0:与atoi(点+ 1));
}

相当简单了很多,我想。


还有一个疑难杂症:假设字符串为26.6;你将不得不工作比修订后的 getCents更难()略高于确实来获取返回的60,而不是6此外,由于26.650,它会返回650,不是65。

I have two helper functions to break up strings in the format of decimal prices ie. "23.00", "2.30"

Consider this:

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\n", getDollars(string));
printf("%u\n", getCents(string));

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??

My solution:

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

解决方案

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().

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.


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().

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

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

Quite a lot simpler, I think.


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天全站免登陆