使用scanf()将数字解析为数字

时间:2014-04-10 11:49:37

标签: c scanf

我想输入一个10位数的数字,然后将数字放入数组中。但由于某种原因,我得到这个随机的2位数字似乎与我的输入无关(??)。

char number[10];            //number containing 10 digits
scanf("%s",number);         //store digits of number
printf("%d\n",number[0]);   //print the 1st digit in the number
printf("%d\n",number[1]);   //print the 2nd digit in the number

这是我得到的:

Input:
1234567890

Output:
49
50

实际上,49应该是1,而50应该是2.

5 个答案:

答案 0 :(得分:3)

您将获得字符12的ASCII值。使用%c说明符打印数字。

printf("%c\n",number[0]);

答案 1 :(得分:2)

警告!您的代码可能会调用undefined behaviour!

但我们稍后会谈到它。让我们先解决您的实际问题。

以下是对正在发生的事情的逐步说明。您需要知道的第一件事是C中的每个字符文字实际上都是编译器的整数。

试试这段代码。

#include <stdio.h>

int main()
{
    printf("%d\n", sizeof '1');
    return 0;
}

输出结果为:

4

这表明编译器将字符文字'1'表示为4字节整数。现在,让我们看看'1'的这个4字节整数在这里使用下一个代码。

#include <stdio.h>

int main()
{
    int a = '1';
    printf("a when intepreted as int : %d\n", a);
    printf("a when intepreted as char: %c\n", a);
    return 0;
}

编译并运行它。你会看到这个输出。

a when intepreted as int : 49
a when intepreted as char: 1

我们学到了什么?

字符'1'在我的系统上表示为整数49。这对您的系统也是如此。那是因为在我的系统和你的系统中,编译器使用ASCII码代表'1'为49,'2'为50,'A'为65,'B'为66,依此类推。请注意,对于另一个系统,字符到这些代码的映射可能不同。您永远不应该依赖这些整数代码来识别字符。

因此,当我尝试将此值打印为整数(使用%d作为格式说明符)时,打印的是'1'的整数值49。但是,如果我们将此值打印为字符(使用%c作为格式说明符),则打印的是整数代码为49的字符。换句话说,1将被打印。

现在尝试使用此代码。

#include <stdio.h>

int main()
{
    char s[] = "ABC123";
    int i;
    printf("char  %%d  %%c\n");
    printf("----  --  --\n");
    for (i = 0; i < 6; i++) {
        printf("s[%d]  %d  %c\n", i, s[i], s[i]);
    }
    return 0;
}

现在您应该看到此输出。

char  %d  %c
----  --  --
s[0]  65  A
s[1]  66  B
s[2]  67  C
s[3]  49  1
s[4]  50  2
s[5]  51  3

现在有意义吗?要打印字符时,需要使用%c格式说明符。仅当您想要查看表示该字符的整数代码时,才应使用%d

最后,让我们回到您的代码。这就是你解决它的方法。

#include <stdio.h>

int main()
{
    char number[10];
    scanf("%9[^\n]", number);
    printf("%c\n", number[0]);
    printf("%c\n", number[1]);
    return 0;
}

有两点需要注意。

  • 我使用%c作为格式说明符来打印读取的数字的字符表示。
  • 我已将scanf的格式说明符更改为仅在字符不是换行符的情况下最多接受9个字符。这是为了确保用户不会通过输入远远超过9个字符的字符串来使程序崩溃。为什么9而不是10?因为我们需要将数组的一个单元格留空以用于空终止符。较长的输入会覆盖number数组分配的10个字节之外的内存位置。这样的缓冲区溢出导致调用undefined behaviour的代码,这可能导致崩溃或杀死你的猫。

答案 2 :(得分:0)

printf("%c\n",number[0]);   //print the 1st digit in the number
printf("%c\n",number[1]);   

应该为你做的工作,你看到的是ascii值。

答案 3 :(得分:0)

你的number数组是一个char数组,因此它的每个元素都是一个char。 当你输入:
printf("%d\n",number[0]);
您将字符打印为整数,因此您可以获得每个字符的ASCII代码。

将您的陈述更改为printf("%c\n",number[0]);以将字符打印为字符而非字母

答案 4 :(得分:-3)

警告!您的代码会调用undefined behaviour!

char number[10];     // Can only store 9 digits and nul character
scanf("%s",number);  // Inputting 1234567890 (11 chars) will overflow the array!

改为使用fgets

#define MAX_LEN 10
char number[MAX_LEN];
if(fgets(number, MAX_LEN, stdin)) {
     // all went ok
}

修复此问题后,您可以解决打印问题。您正在打印字符代码(数字),而不是实际字符。使用不同的类型说明符:

printf("%c\n",number[0]);