我的程序没有正确操作字符串的值

时间:2016-11-14 18:15:34

标签: c

我需要编写一个获取字符串输入值的程序,然后忽略不是数字的字符,并使用字符串中的数字创建一个整数并显示它。 here are some strings turned into integers as stated in the exercise

我想通过向量遍历字符串,然后使用isdigit(s [i])测试每个位置是否为数字,然后将这些值放在另一个使用数字创建数字的向量中。最后,它应该输出数字。我不能为它的生活找出错误,请帮忙。

#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main()
{
    char *s;
    scanf("%s", s);
    printf("%s\n", s);

    int i, n=0, v[100], nr=0;
    for(i=0; i<strlen(s); i++)
    {
        if (isdigit(s[i]) == 1)
        {
            v[i] = s[i];
            n++;
        }
    }
    for(i=0;i<n;i++)
    {
        printf("%c\n", v[i]);
    }

    for(i=0; i<n; i++)
    {
        nr = nr * 10;
        nr = nr + v[i];
    }
    printf("%d", nr);
    return 0;
}

4 个答案:

答案 0 :(得分:2)

指针s是未初始化的,这是您的主要问题。但也有其他问题。

    记录
  • isdigit()返回非零返回码,该码不一定是1。

  • isdigit()的参数需要转换为unsigned char以避免潜在的未定义行为。

  • 您的数组v也在使用相同的索引变量i - 这是不对的。存储数字时,请使用其他变量为v编制索引。

  • 您需要减去'0'以获得每个数字整数等值。

  • scanf()的格式%s无法处理带空格的输入(以及其他问题)。因此,请使用fgets()

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

int main(void)
{
char s[256];
fgets(s, sizeof s, stdin);
s[strcspn(s, "\n")] = 0; /* remove trailing newline if present */
printf("%s\n", s);

int i, n = 0, v[100], nr = 0;
size_t j = 0;
for(i = 0; i < s[i]; i++)
{
    if (isdigit((unsigned char)s[i]))
    {
        v[j++] = s[i];
        n++;
    }
}
for(i = 0;i < j; i++)
{
    printf("%c\n", v[i]);
}

if (j) { /* No digit was seen */
    int multiply = 1;
    for(i= j-1 ; i >= 0; i--) {
        nr = nr + (v[i] - '0') * multiply;
        multiply *= 10;
    }
}

printf("%d", nr);
return 0;
}

此外,如果您的输入包含太多数字,请注意nr(和/或multiply)的整数溢出无法保持。

另一个潜在的问题来源是,如果您输入超过100位数字,那么它将溢出数组v,从而导致undefined behaviour

答案 1 :(得分:0)

非常感谢你的帮助,我听从了别人的建议并取代了   v [i] = s [i] - &gt; v [n] = s [i]并用char s [100]更改了char * s 现在它工作得很好,我摆脱了变量nr只输出数字而不通过\ n分开它们。感谢调试器评论,我不知道我可以有效地使用它。

答案 2 :(得分:0)

首先,你没有分配任何内存,我将其更改为固定数组。

您对scanf的使用将在第一个空格处停止(如第一个示例输入中所示)。

接下来,在编写数字int v[]时,您没有使用正确的数组索引。但是我删除了所有这些并简单地使用了任何数字。

您没有阅读isdigit的手册页。它没有返回1一个数字。它返回非零值,因此我删除了显式测试并将其保留为非0结果的隐式测试。

我将字符串长度和循环类型更改为size_t,移动循环的多个strlen调用。

您还没有看到数字&#39;字符值不是整数值,因此我已减去'0'以使其成为现实。

最后,我将目标类型更改为unsigned,因为您将忽略任何减号。

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

int main(void)
{
    char s[100];                              // allocate memory
    unsigned nr = 0;                          // you never check a `-` sign
    size_t i, len;                            // correct types
    if(fgets(s, sizeof s, stdin) != NULL) {   // scanf stops at `space` in you example
        len = strlen(s);                      // outside of the loop
        for(i=0; i<len; i++) {
            if(isdigit(s[i])) {               // do not test specifically == 1 
                nr = nr * 10;
                nr = nr + s[i] - '0';         // character adjustment
            }
        }
        printf("%u\n", nr);                 // unsigned
    }
    return 0;
}

计划会议:

a2c3   8*5+=
2385

答案 3 :(得分:0)

请使用此

#include <stdio.h>
#include <ctype.h>

int main()
{
    int c;
    while ((c = getchar()) != EOF) {
        switch (c) {
        case '0': case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8': case '9':
        case '\n':
            putchar(c); break;
        }
    }
    return 0;
} /* main */

这是一个示例执行:

$ pru_$$
aspj pjsd psajf pasdjfpaojfdapsjd 2 4 1
241
1089u 0u 309u1309u98u 093u82 40981u2 982u4 09832u4901u 409u 019u019u 0u3 0ue 
10890309130998093824098129824098324901409019019030

非常优雅! :)