【问题标题】:How can I get certain things out of a string如何从字符串中获取某些内容
【发布时间】:2021-09-15 22:20:54
【问题描述】:

我想编写一个算法,它接受一个输入,其中包含某个项目的名称及其价格,以及它们之间的破折号。输出应该说明物品的名称及其价格。 我也想知道如何将输入分成两个字符串,一个是名称,另一个是价格,因为我真的想不出任何东西。

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

为什么输出价格不对,有没有更好的方法?

【问题讨论】:

  • 阅读 strtok()
  • 第 1 步:启用所有编译器警告以节省时间。 2) temp = item[i] - '0'; 转换非数字。提示:输入为"Chocolate-Chip Cookie - 30\n"
  • 提示:“为什么输出价格错误”信息量不足。最好发布输入、真实输出和预期输出。
  • fgets()sscanf() 是一个不错的选择。否则,fgets()strtok(),(或使用 strcspn())——或者只使用一对指针和 strchr() 以及 memcpy()
  • 感谢您是否可以正确缩进代码。更难阅读。谢谢

标签: c c-strings


【解决方案1】:

嗯,马上,我看到您在此循环中每次增加 i 两次,可能不是您想要的:

for(i=0;i<len;i++)  // <- First increment
{
    if((item[i] >= '0') && (item[i] <= '9'))
    {
        break;
    }
    i++;            // <- Second increment
}

这里的i是不必要的:

for(i;i<len;i++)
 // ^ does nothing

您可以在价格计算循环中打印一些值以查看发生了什么:

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

问题在于fgets\n(您在输入后按的回车键)添加到字符串中,并且您将其解释为价格的一部分。

【讨论】:

    【解决方案2】:

    另一种方法(您可以用来解析任何字符串中的任何内容)是使用一对指针来 walk-the-string 在开头和结尾设置一个开始和结束指针您想要的字符串的每个段,然后将字符串的这些部分复制到单独的存储中。

    一个简短的例子(使用 cmets)是:

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

    使用/输出示例

    ./bin/split_price-item
    input: Chocolate-Chip Cookie - 30
    
    item  : 'Chocolate-Chip Cookie'
    price : '30'
    

    现在,您的分隔符必须保留为" - ",但您可以轻松地将其作为参数传递,而不是使用常量(由您决定)。如果您有任何问题,请告诉我。

    【讨论】:

    • 很抱歉迟到了 3 个月,但由于学校工作,还没有完成这个项目,实施了类似于这个解决方案的东西,它就像一个魅力!非常感谢您,先生。
    • 别担心,祝你的项目好运。如果您有任何问题,请告诉我。
    【解决方案3】:

    在我看来,这可以简化一些。为清楚起见省略错误检查,您可以执行以下操作:

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

    结果:

    Item: 'Chocolate-Chip Cookie'
    Price: '30'
    

    【讨论】:

      【解决方案4】:

      为什么输出价格不对?

      代码尝试将 "30\n" 而不是 "30" 更改为值 30。

      有没有更好的方法?

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

      【讨论】:

        猜你喜欢
        • 2016-01-07
        • 1970-01-01
        • 1970-01-01
        • 2010-12-23
        • 1970-01-01
        • 2022-07-06
        • 1970-01-01
        • 2022-08-22
        • 1970-01-01
        相关资源
        最近更新 更多