如何修复此代码,以便它可以测试字符旁边的整数?
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_ptr
和 end_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_MAX
,errno
会设置为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,在您的情况下,该值必须是 1
(scanf()
制作)。
为了防止溢出,使用宽度说明符,如
scanf("%99s",ch);
而不是
scanf("%s",ch);
因为 100
是 ch
字符数组的大小,我们需要一个额外的字节来存储字符串分隔符([=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;
}
给定一个包含字母数字字符的字符串,计算该字符串中所有数字的总和。 我的代码的问题是它显示了字符之前的整数,但它没有对字符之后的整数求和。
在 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_ptr
和 end_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_MAX
,errno
会设置为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,在您的情况下,该值必须是 1
(scanf()
制作)。
为了防止溢出,使用宽度说明符,如
scanf("%99s",ch);
而不是
scanf("%s",ch);
因为 100
是 ch
字符数组的大小,我们需要一个额外的字节来存储字符串分隔符([=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;
}