简体   繁体   English

如何在C中的字符串中添加逗号分隔的值

[英]How to add comma separated values in string in C

How do I add all csv values in the string? 如何在字符串中添加所有csv值?

I made a skeleton but should I convert string to integer and use += to add all integers? 我做了一个骨架,但是我应该将字符串转换为整数并使用+=来添加所有整数吗?

#include <stdio.h>
int main(void)
{
    int i;                  // index
    int num=0, sum=0;       // number
    char str[]="123,456,789";

    for(i=0; str[i]; i++) {
        if (str[i] == ',') { // begin a new number
            - ① - // multiple statements are allowed
        } else { // a digit
            num = ②;
        }
    }
    sum += num; 
    printf("Sum of all values in CSV[%s] : %d", str, sum);

    return 0;
}

There are many many ways to go about this. 有很多方法可以解决此问题。 The preferred is simply to use strtol for its intended purpose and iterate over the string using the endptr parameter to update your position in the string to one after the last digit following a successful conversion. 首选方法是简单地将strtol用于其预期目的,并使用endptr参数遍历字符串,以在成功转换后将字符串中的位置更新为最后一位之后的位置。

However, there is good value in learning to iterate over a string with either array indexing (or preferably pointers ) to parse what you need from the string. 但是,在学习使用数组索引 (最好是指针 )遍历字符串以解析字符串中的内容时,具有很好的价值。 There is nothing too complicated to parse with a pair of pointers inch-worming your way down the string picking out what you need. 解析指针对没有什么太复杂的了,它在字符串中寸步前进,挑出所需的东西。

Here it appears you want to loop over each character in the string, testing for commas or digits and taking the appropriate action to either add the digit to your number , or add your number to the sum if a comma is encountered. 在这里,您似乎想要遍历字符串中的每个字符,测试逗号或数字,并采取适当的措施将数字添加到您的number ,或者在遇到逗号时将您的number添加到sum Don't forget you must convert the ASCII value for the character to its integer value before using it in your number. 别忘了,在将数字用于字符之前,必须将其ASCII值转换为数值。

A simple implementation of what you are attempting could look like the following: 您尝试的内容的简单实现如下所示:

#include <stdio.h>

int main(void)
{
    int i,
        num=0,
        sum=0;
    char str[] = "123,456,789";

    for (i = 0; str[i]; i++)    /* loop over each char */
        if (str[i] == ',') {    /* begin a new number */
            sum += num;         /* add number to sum */
            num = 0;            /* reset number to 0 */
        }
        else                    /* add digit to number */
            num = num * 10 + (str[i] - '0');

    sum += num;                 /* add final number to sum */

    printf ("Sum of all values in CSV[%s] : %d\n", str, sum);

    return 0;
}

Example Use/Output 使用/输出示例

$ ./bin/csvsum
Sum of all values in CSV[123,456,789] : 1368

A strtol Implementation 一个strtol实施

The reason strtol (or any of the strtoX family) are preferred is due to the error checking they provide for the conversion as well as the built in advancing of the pointer within the string being converted to the next character in the string following the digits converted. 之所以选择strtol (或任何strtoX家族)的原因是由于它们提供了转换的错误检查以及将字符串内的指针内置转换为数字后的下一个字符的内置前进方式。 。 (in your case the endptr parameter will either point to a comma or the nul-terminating character in the string after each conversion. (在您的情况下,每次转换后, endptr参数将指向字符串中的commanul终止字符。

This allows you to simply walk down the string with strtol and a pair of pointers ( p and ep -- pointer and end-pointer ), converting each set of digits to a number as you go with strtol (p, &ep, base) . 这使您可以简单地使用strtol和一对指针( pep 指针结束指针 )在字符串中向下移动,并在使用strtol (p, &ep, base)将每组数字转换为数字。 After each successful conversion, just skip forward with ep until you find the next '+-' or '0-9' that will start the next valid conversion and set p = ep; 每次成功转换后,只需向前跳ep直到找到下一个'+-''0-9'开始下一次有效的转换并设置p = ep; and repeat. 并重复。 (if you reach the nul-terminating character while advancing ep - you know you are done with the conversions) (如果在前进ep达到零终止字符-您知道转换已完成)

A simple implementation would be: 一个简单的实现是:

#include <stdio.h>
#include <stdlib.h>     /* for strtol */
#include <limits.h>     /* for INT_MAX */
#include <errno.h>      /* for errno */

#define BASE 10         /* added benefit - strtol will convert from many bases */

int main (void)
{
    int sum=0;
    long tmp = 0;                   /* tmp long for strtol conversion */
    char str[] = "123,456,789",
        *p = str, *ep = NULL;       /* pointer and end-pointer */

    for (;;) {                      /* perform conversion until end (or error) */
        errno = 0;                      /* reset errno */
        tmp = strtol (p, &ep, BASE);    /* perform conversion, update ep */
        if (errno) {                    /* check conversion was valid */
            fprintf (stderr, "error: invalid conversion.\n");
            return 1;
        }
        if (tmp < INT_MAX - sum)        /* make sure tmp will fit in sum */
            sum += (int)tmp;            /* add tmp to sum */
        else {
            fprintf (stderr, "error: sum overflowed.\n");
            return 1;
        }
        /* find the next '+-' or 'digit' or end of string */
        while (*ep && *ep != '+' && *ep != '-' && ( *ep < '0' || '9' < *ep))
            ep++;
        if (!*ep) break;    /* if *ep is nul-character, end reached, bail */
        p = ep;             /* update pointer to end-pointer, repeat */
    }

    printf ("Sum of all values in CSV[%s] : %d\n", str, sum);

    return 0;
}

Look things over and let me know if you have further questions. 仔细检查一下,如果您还有其他问题,请告诉我。

First you can trim all white spaces and all. 首先,您可以修剪所有空白和所有空白。

Secondly as you mentioned there will only be integers separated by commas so you should understand the general way to get an integer. 其次,正如您所提到的,只有整数之间用逗号分隔,因此您应该了解获取整数的一般方法。

So what is the idea? 那是什么主意?

You will continue to form the number unless you see a comma or end of string. 除非看到逗号或字符串结尾,否则将继续形成数字。

How to form the number? 号码如何形成?

|ABCD
      num
A|BCD  A   [Here also 10*0+A]
AB|CD  A*10+B
ABC|D  (A*10+B)*10+C
ABCD|  ((A*10+B)*10+C)*10+D = 1000*A+100*B+10*C+1*D

You repetitively multiply the existing number with 10 and then add it. 您将现有数字重复乘以10,然后将其相加。

This way you form the number. 这样您就可以形成号码。

I have avoided giving the answer with functions. 我避免给出函数的答案。 There are other options like using builtin functions like strtok etc. You can check them in reference. 还有其他选项,例如使用诸如strtok等内置函数。您可以参考进行检查。

You can perform want you want with strtok and strtol functions: 您可以使用strtokstrtol函数执行所需的操作:

int main(void)
{
    /* delimiter: string will be cut on spaces and comma */
    char delim[] = " ,";
    char *tok;
    /* string to parse */
    char str[] = "123,465,798";

    int sum = 0, num;

    /* get first token, warning `str` is modified */
    tok = strtok(str, delim);
    while (tok)
    {
        /* convert token to int */
        num = strtol(tok, NULL, 0);

        /* add it to sum */
        sum += num;

        /* read next token */
        tok = strtok(NULL, delim);
    }
    printf("sum is %d\n", sum);
    return 0;
}
int main() {

    int i;  // index

    int iGroup=0;// groupNumber array

    int num=0, sum=0;       // number
    char str[]="123,456,789";
    char strNum[16];
    memset(&strNum[0], 0, sizeof(strNum));

    for(i=0; str[i]!='\0'; i++) {
        if (str[i] == ',' ) { // Get the group number array since the numbers 

            iGroup=0;                     //Reset the index of the groupNumber array
            num=atoi(strNum);                 //Convert the array to numbers
             memset(&strNum[0], 0, sizeof(strNum)); //Set the groupNumber array to null 
                   sum += num; 
        } else { // a digit
            strNum[iGroup]=str[i];             //Add the character to groupNumber array
            iGroup++;
        }
    }
       num=atoi(strNum); 
       sum += num;
    //sum += num; 
    printf("Sum of all values in CSV[%s] : %d", str, sum);

    return 0;
}

Here is a solution with strtol() and strspn() that does not modify the input string: 这是使用strtol()strspn()的解决方案,它不会修改输入字符串:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int sum_csv(const char *str) {
    int sum = 0;
    for (;;) {
        char *p;
        int n = strtol(str, &p, 10);  /* convert number */
        if (p == str)                 /* stop if no number left */
            break;
        sum += n;                     /* accumulate (ignore overflow) */
        str = p + strspn(p, ", ");    /* skip number and delimiters */
    }
    return sum;
}

int main(void) {
    printf("sum is %d\n", sum_csv("123,465,798");
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM