如何修复此代码,以便它可以测试字符旁边的整数?

how to fix this code so that it can test the integers present next to the character?

给定一个包含字母数字字符的字符串,计算该字符串中所有数字的总和。 我的代码的问题是它显示了字符之前的整数,但它没有对字符之后的整数求和。

在 python 和 C++ 中执行很容易,但我无法使用 C 完成它!任何人都可以验证我哪里做错了吗? << 谢谢!

enter code here
#include<stdio.h>
#include<string.h>
int convert(char[]);
int main()
{
    char ch[100],temp[100]={0};
    int i=0,s=0,j=0,n;
    scanf("%s",ch);
    for(i=0;i<strlen(ch);i++)
    {  
        if((ch[i]>='0') && (ch[i]<='9'))
        {
            temp[j]=ch[i]; 
            j++;
        }
        else
        {   
            if(temp[0]== '[=10=]')
            {
                continue;
            }
            else 
            {
                n=convert(temp);
                s+=n;
                temp[0]= '[=10=]';
                j=0;
            }
        }
    }
    printf("%d",s);
    return 0;
}
int convert(char s[]) //converting string to integer
{
    int n=0;
    for(int i=0;i<strlen(s);i++)
    {
        n= n * 10 + s[i] - '0'; 
    }
return n;
}

输入:12abcd4
预期输出:16

但是我的代码的输出是 12。

您可以使用 strtoul() and strpbrk() 的组合来执行此操作。

声明两个字符指针 start_ptrend_ptr 并使 start_ptr 指向正在考虑的字符串的开头。

char *start_ptr=s, *end_ptr;

其中 s 是包含字符串的大小为 100 的字符数组。

由于您的字符串只有字母数字字符,因此没有 - 符号,因此没有负数。所以我们可以使用无符号整数。

我们使用 stdlib.h 中的 strtoul() 来执行字符串到整数的转换。因此,让我们声明两个变量:rv 用于保存由 strtoul() 计算的值 return 和 sum 用于保存数字的总和。

unsigned long rv, sum_val=0;

现在使用循环:

for(; start_ptr!=NULL; )
{
    rv = strtoul(start_ptr, &end_ptr, 10);
    if(rv==ULONG_MAX && errno==ERANGE)
    {
        //out of range!
        printf("\nOut of range.");
        break;
    }
    else
    {
        printf("\n%lu", rv);
        sum_val += rv;
        start_ptr=strpbrk(end_ptr, "0123456789");
    }
}

strtoul() 将尽可能多地转换字符串的一部分,然后使 end_ptr 指向无法转换的字符串部分的第一个字符。

如果数字太大会returnULONG_MAXerrno会设置为ERANGE

否则转换后的数字是returned。

strpbrk() 将搜索一组字符(在本例中为字符 0-9)和 return 指向第一个匹配项的指针。否则 NULL 是 returned.

不要忘记包含以下头文件:

stdlib.h ---> strtoul
string.h ---> strpbrk
limits.h ---> ULONG_MAX
errno.h  ---> errno

简而言之,我们可以把程序做成这样

for(; start_ptr!=NULL; sum_val += rv, start_ptr=strpbrk(end_ptr, "0123456789"))
{
    rv = strtoul(start_ptr, &end_ptr, 10);
    if(rv==ULONG_MAX && errno==ERANGE)
    {
        //out of range!
        break;
    }
}
printf("\n\n%lu", sum_val);

因此字符串“12abcd4”的 sum_val 的值将是 16


scanf() 通常不是接受非 well-formatted 输入的最佳方式。也许您可以使用 fgets()-sscanf() 组合。

如果您必须使用 scanf(),请确保检查由它编辑的值 return,在您的情况下,该值必须是 1scanf()制作)。

为了防止溢出,使用宽度说明符,如

scanf("%99s",ch);

而不是

scanf("%s",ch);

因为 100ch 字符数组的大小,我们需要一个额外的字节来存储字符串分隔符([=46=] 字符)。

您的代码中有两个问题。评论中提到了第一个:如果最后一个字符是数字,则不会考虑最后一个 "number section" 。但我不认为评论中给出的解决方案很好,因为如果最后一个字符不是数字,你将得到一个错误的值。为了纠正这个问题,我添加了一个 if 语句来检查最后一个字符是否是数字,如果是则调用 convert()。

第二个问题是strlen return 你字符串中的字符数从头开始直到它找到'\0'。您使用字符串的方式导致了以下问题:
ch = “12abcd4”。
一开始你有 temp = '1' + '2' + '\0'...
调用 convert() 后,将 temp[0] 设置为 '\0',因此 temp = '\0' + '2' + '\0'...。
当您再次开始读取数字时,您将 temp[0] 设置为“4”。您的字符串现在是:'4' + '2' + '\0'...。
n returned 将为 42,您的结果为 54 (12+42)。有几种解决方案可以实现预期的行为,我选择使用变量 j 来指示应该读取多少个字符,而不是使用 strlen() :

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

int convert(char[], int size);

int main() {
  char ch[100],temp[100]={0};
  int i=0,s=0,j=0,n;
  scanf("%s",ch);
  for(i=0;i<strlen(ch);i++) {
    if((ch[i]>='0') && (ch[i]<='9')) {
      temp[j]=ch[i]; 
      j++;

      // change here
      if(i == strlen(ch) - 1) {
        n=convert(temp, j);
        s+=n;
      }
    }
    else {
      // change here
      n=convert(temp, j);
      s+=n;

      if(temp[0]== '[=10=]') {
    continue;
      }

      temp[0]= '[=10=]';
      j=0;
    }
  }
  printf("%d\n",s);
  return 0;
}

//change here
int convert(char s[], int size) {
  int n=0;
  for(int i=0;i<size;i++) {
    n= n * 10 + s[i] - '0';
  }
  return n;
}