Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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
", getDollars(string));
printf("%u
", 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);
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
1.1k views
Welcome To Ask or Share your Answers For Others

1 Answer

This:

char price[4] = "2.20";

leaves out the nul terminator on price. I think you want this:

char price[5] = "2.20";

or better:

char price[] = "2.20";

So, you will run off the end of the buffer the second time you try to get a token out of price. You're just getting lucky that getCents() doesn't segfault every time you run it.

And you should almost always make a copy of a string before using strtok on it (to avoid the problem that Jonathan Leffler pointed out).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...