如何从字符串中获取某些内容

Posted

技术标签:

【中文标题】如何从字符串中获取某些内容【英文标题】: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() 感谢您是否可以正确缩进代码。更难阅读。谢谢 【参考方案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;

【讨论】:

以上是关于如何从字符串中获取某些内容的主要内容,如果未能解决你的问题,请参考以下文章

如何在Google表格中获取某些值后如何进行正则表达式提取

Unix Shell 脚本仅从文件内容中获取需要的行,并在下一行考虑某些条件

在java中如何修改文本文件中的某一行的某些数据??

如何从 UILabel 的第 n 行获取文本/字符串?

PHP cURL字符串获取字符串某些部分之前和之后的所有内容

如何从 Swift 中的加密 JSON 字符串中提取某些字段?