Reputation: 21
I wanted to write an algorithm that takes an input which contains the name of a certain item and its price, and a dash between them. The output is supposed to state the name of the item and its price. I would also like to know how can I separate the input into two strings, one being the name, and the other being the price, since I can't really come up with anything.
int getprice(char item[]);
void printitem(char item[]);
int main()
{
char item[40];
int i, j, len;
int price = 0;
fgets(item, 40, stdin);
price = getprice(item);
printitem(item);
return 0;
}
int getprice(char item[])
{
int i = 0;
int price = 0;
int len = strlen(item);
int temp;
for (i = 0; i < len; i++)
{
if ((item[i] >= '0') && (item[i] <= '9'))
{
break;
}
i++;
}
for (i; i < len; i++)
{
temp = item[i] - '0';
price = price * 10;
price = price + temp;
}
printf("price is: %u\n", price);
return price;
}
void printitem(char item[])
{
int i = 0;
int len = strlen(item);
for (i = 0; i < len; i++)
{
if (item[i] != '-')
{
printf("%c", item[i]);
}
else // if '-' is encountered the next char is checked if it stops or if it needs to keep going
{
i++; //the for loop increments by itself
if (item[i] == ' ') //if there is a space after '-' that means we printed the whole thing
{
break;
}
i--; //if it needs to keep going
printf("-");
}
}
}
Input:Chocolate-Chip Cookie - 30
Output:Item: Chocolate-Chip Cookie
Price: 30
actual Output: Item: Chocolate-Chip Cookie
Price: 262
Why is the output price wrong, and is there a better way of doing it?
Upvotes: 2
Views: 92
Reputation: 490348
Seems to me that this can be simplified somewhat. Omitting error checking for clarity, you could do something like this:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
char input[] = "Chocolate-Chip Cookie - 30";
char *sep = strstr(input, " - ");
int len = sep-input;
printf("Item: '%.*s'\nPrice: '%s'\n", len, input, sep + 3);
}
Result:
Item: 'Chocolate-Chip Cookie'
Price: '30'
Upvotes: 1
Reputation: 84579
Another way (that you can use to parse anything from any string), is to use a pair of pointers to walk-the-string setting a begin and end pointer at the start and end of each segment of the string you want and then copy those portions of the string to separate storage.
A short example (with comments) would be:
#include <stdio.h>
#include <string.h>
#define NUMC 32 /* if you need a constant, #define one (or more) */
#define MAXC 1024
#define DELIM " - "
int main (void) {
/* read buffer, buffers for item, price and begin, end pointers */
char buf[MAXC], item[MAXC], price[NUMC], *p_begin = buf, *p_end;
size_t len;
fputs ("input: ", stdout); /* prompt */
if (!fgets (buf, MAXC, stdin)) { /* read/validate input */
return 0;
}
if (!(p_end = strstr (buf, DELIM))) { /* locate start of delim */
fputs ("error: invalid input format.\n", stderr);
return 1;
}
memcpy (item, p_begin, p_end - p_begin); /* copy item */
item[p_end - p_begin] = 0; /* nul-terminate item */
p_begin = p_end + strlen(DELIM); /* set begin to start of price */
len = strcspn (p_begin, "\n"); /* get length of price */
memcpy (price, p_begin, len); /* copy to price */
price[len] = 0; /* nul-terminate price */
/* output results */
printf ("\nitem : '%s'\nprice : '%s'\n", item, price);
}
Example Use/Output
./bin/split_price-item
input: Chocolate-Chip Cookie - 30
item : 'Chocolate-Chip Cookie'
price : '30'
Now, your delimiter must remain " - "
, but you can easily pass that as a parameter instead of using a constant (up to you). Let me know if you have any questions.
Upvotes: 1
Reputation: 154245
Why is the output price wrong?
Code attempts to change "30\n"
rather than "30"
into the value 30.
is there a better way of doing it?
int getprice(const char *item){ // add const
// Look for a non-digit
while ((*item < '0' || *item > '9') && *item) {
item++;
}
if (*item == 0) {
// No digit found, maybe add error message
return 0;
}
int price=0;
while (*item >= '0' && *item <= '9') { // Loop while a digit
price = price*10 + (*item - '0');
item++;
}
printf("price is: %d\n", price); // %d not %u
return price;
}
Upvotes: 0
Reputation: 8204
Well, right away, I see that you're incrementing i
twice each time through this loop, probably not what you want:
for(i=0;i<len;i++) // <- First increment
{
if((item[i] >= '0') && (item[i] <= '9'))
{
break;
}
i++; // <- Second increment
}
The i
here is unnecessary:
for(i;i<len;i++)
// ^ does nothing
You can print some values in your price-calculation loop to see what's going on:
for(i;i<len;i++)
{
printf("price = %d, item[i] = %d, new price = %d\n",
price, item[i], price * 10 + (item[i] - '0'));
temp = item[i] - '0';
price = price * 10;
price = price + temp;
}
$ ./test
Chocolate-Chip Cookie - 30
price = 0, item[i] = 51, new price = 3
price = 3, item[i] = 48, new price = 30
price = 30, item[i] = 10, new price = 262 <-- Hmm
price is: 262
The issue is that fgets
is adding the \n
(the return you press after the input) to the string and you're interpreting it as part of the price.
Upvotes: 1