将char类型的'0'-'9'转换为int类型,然后用C语言打印到stdout。

时间:2021-06-19 00:05:44

I write a program to receive user input and print it out to screen.

我编写一个程序来接收用户输入并将其打印到屏幕上。

The sample input is abc 12 34.

样本输入是abc 1234。

The sample output is abc 12 34, but the 12 and 34 should be input as integer.

样例输出是abc 1234,但是12和34应该作为整数输入。

With sample input, my program always output as abc 122 344 . I have been working on it for a long time, but I still can't figure it out. Could help me check my code please? Thanks.

有了样例输入,我的程序总是输出abc 12344。我做这件事已经有很长时间了,但我还是弄不明白。能帮我检查一下我的代码吗?谢谢。

My gcc version is 4.1.2 .

我的gcc版本是4.1.2。

#include<stdio.h>
#include<stdlib.h>
int main()
{
    char c;
    char *str = NULL;
    str = (char *)malloc(20*sizeof(char)); /*just sample code, not robust*/
    memset(str,'\0',20*sizeof(char)); 

    if(str == NULL)
    {
        fprintf(stderr,"Error: failed to allocate memory.\n"); fflush(stderr);
        return 0;
    }

    /*store user input*/
    int index = 0;
    while((c=getchar()) != '\n')
    {
        *(str+index) = c;
        index++;
    }

    int digit = 0;
    for(index = 0; *(str+index)>0; index++)
    {
        if((*(str+index)>='a') &&( *(str+index)<='z'))
        {
            fprintf(stdout,"%c",*(str+index)); fflush(stdout);
        }

        else if((*(str+index)>='0') &&( *(str+index)<='9'))
        {
            /*handling the case that a number with more than one digit*/
                    if(*(str+index+1)>='0' && *(str+index+1)<='9')
            {
                digit=10*(digit+atoi(str+index));
            }
            else
            {
                digit += atoi(str+index);   
                fprintf(stdout,"%d",digit); fflush(stdout);
                digit = 0;
            }           
        }

        else
        {   
            fprintf(stdout,"%c",*(str+index)); fflush(stdout);
        }
    }
    printf("\n");
    free(str);
    return 0;
}

4 个解决方案

#1


2  

Two quick changes for you.

给你两个快速的改变。

First, as already noted, atoi() take a string and return an int. Since you're just doing 1 character (0-9) just subtract it from the character '0'.

首先,正如已经注意到的,atoi()取一个字符串并返回一个int,因为您只是在做一个字符(0-9),然后从字符'0'中减去它。

digit=10*(digit+(*(str+index)-'0')); //instead of atoi(str+index)

Why subtract '0'? It comes down to the ASCII value of numbers.

为什么要减去‘0’吗?它归结为数字的ASCII值。

The value of the character '0' is 3010, the value of '1' is 3110, so:

字符'0'的值是3010,'1'的值是3110,所以:

int a = '0' - '0'; // that's  30-30, or 0 as an int
int b = '1' - '0'; // that's  31-30, or 1 as an int

If you make this tweak in both places you're currently using atoi():

如果你在两个地方都做了这个调整,你现在使用的是atoi():

            ...
            digit=10*(digit+atoi(str+index));
        }
        else
        {
            digit += atoi(str+index); 
            ...

Changes to:

更改:

            ...
            digit=10*(digit+(*(str+index)-'0'));
        }
        else
        {
            digit += *(str+index)-'0';   
            ...

Your code will now work the way you want it to. One more point, you have an if/if else/else checking for a-z, 0-9, then anything else.

您的代码将按照您希望的方式工作。还有一点,你有一个if/if else/else /else检查a-z, 0-9,然后还有其他的。

Because your first if and your else are identical code it means there's a simplification that can be done there. Just removing the entire first if and changing your else if to just an if will give you the exact same thing as what you're doing.

因为你的第一个if和你的else都是相同的代码,这意味着有一个简化可以在那里完成。如果你把你的else if换成an,它就会给你和你所做的完全一样的东西。

#2


3  

You should not be using atoi: it converts a string to int, not a single char.

您不应该使用atoi:它将字符串转换为int,而不是单个char。

Here is what happens: when you see a two-digit number, say, 34, the first iteration pssses both digits to atoi, gets 34, and multiplies it by ten, making 340. The following iteration picks up 4, and happily adds it to 340, for the cumulative result of 344.

这里是发生的情况:当你看到一个两位数的数字,比如说,34,第一个迭代将两个数字都变成了atoi,得到34,然后乘以10,得到340。下面的迭代获得4,并愉快地将其添加到340,以获得344的累积结果。

If you would like to convert a single char that represents a digit to an int, use subtraction:

如果你想要转换一个字符,它表示一个数字到一个整数,使用减法:

digit = *str - '0';

Moreover, your code for handling multi-digit numbers is, well, unorthodox, making it hard to understand. Instead of multiplying the current value by ten when you see that the next character is a digit, you should multiply the prior value by ten when you see a digit. This works even for the first digit, when the prior value is 0, because ten times zero is still a zero.

此外,你处理多位数数字的代码是不正统的,让人难以理解。当你看到下一个字符是一个数字时,你应该把之前的值乘以10,而不是把当前值乘以10。这对于第一个数字是有效的,当之前的值是0时,因为10乘以0仍然是0。

You should eliminate the if(((*str+index+1)>='0') && (*str+index+1)<='9') and its then branch, and modify its else branch as follows:

您应该删除if((*str+index+1)>='0') && (*str+index+1)<='9')及其分支,并修改其else分支如下:

digit = 10*digit + *(str+index) - '0';
if (((*str+index+1)<'0') || (*str+index+1)>'9') {
    fprintf(stdout,"%d",digit); fflush(stdout);
    digit = 0;
}

#3


1  

How about just using sscanf for that ? like this:

就用sscanf吧?是这样的:

sscanf(str, "%s %d %d", str1, &num1, &num2);

If you can't use sscanf, for some reason, then you should at least use isalpha() and isdigit() to check for characters and numbers, respectively.

如果您不能使用sscanf,出于某种原因,那么您至少应该使用isalpha()和isdigit()来检查字符和数字。

So instead of using this:

所以不要用这个:

if((*(str+index)>='a') &&( *(str+index)<='z')) {
    .....
}

Use this:

用这个:

if (isalpha(*str+index)) {
    .....
}

#4


0  

One of the problems with your code was digit += atoi(str+index); this will take, for example "12" will convert to int, and print 12 than in the next iteration it will take "2" and print it again, therefore printing "122". An easy solution it to replace that line of code for this digit = str[index] - '0';, now it will convert char by char.

您的代码的一个问题是数字+= atoi(str+index);例如,“12”将转换为int,而打印12,而不是在下一个迭代中,它将采用“2”并再次打印,因此打印“122”。一个简单的解决方案,它将替换这一数字= str[索引]- '0'的代码行,现在它将通过char转换字符。

Instead of having so much if/ else, it preferable to use just one condition to check if it is or not a digit, like this code on the example below.

与其有太多的if/ else,不如只使用一个条件来检查它是否为一个数字,比如下面这个例子中的代码。

#include<stdio.h>
#include<stdlib.h>
int main()
{
    char c;
    char *str = NULL;
    str = (char *)malloc(20*sizeof(char)); /*just sample code, not robust*/
    memset(str,'\0',20*sizeof(char)); 

    if(str == NULL)
    {
        fprintf(stderr,"Error: failed to allocate memory.\n"); fflush(stderr);
        return 0;
    }

    /*store user input*/
    int index = 0;
    while((c=getchar()) != '\n')
    {
        *(str+index) = c;
        index++;
    }

    int digit = 0;
    for(index = 0; *(str+index)>0; index++)
    {

        if (isdigit(*(str+index)))
        {
        while (isdigit(*(str+index)))
        {
                digit = str[index] - '0';   
                fprintf(stdout,"%d",digit); fflush(stdout);
                digit = 0;
                index++;
        }
        index--;
        }
        else{ 
            fprintf(stdout,"%c",*(str+index)); fflush(stdout);
        }
    }
    printf("\n");
    free(str);
    return 0;
}

#1


2  

Two quick changes for you.

给你两个快速的改变。

First, as already noted, atoi() take a string and return an int. Since you're just doing 1 character (0-9) just subtract it from the character '0'.

首先,正如已经注意到的,atoi()取一个字符串并返回一个int,因为您只是在做一个字符(0-9),然后从字符'0'中减去它。

digit=10*(digit+(*(str+index)-'0')); //instead of atoi(str+index)

Why subtract '0'? It comes down to the ASCII value of numbers.

为什么要减去‘0’吗?它归结为数字的ASCII值。

The value of the character '0' is 3010, the value of '1' is 3110, so:

字符'0'的值是3010,'1'的值是3110,所以:

int a = '0' - '0'; // that's  30-30, or 0 as an int
int b = '1' - '0'; // that's  31-30, or 1 as an int

If you make this tweak in both places you're currently using atoi():

如果你在两个地方都做了这个调整,你现在使用的是atoi():

            ...
            digit=10*(digit+atoi(str+index));
        }
        else
        {
            digit += atoi(str+index); 
            ...

Changes to:

更改:

            ...
            digit=10*(digit+(*(str+index)-'0'));
        }
        else
        {
            digit += *(str+index)-'0';   
            ...

Your code will now work the way you want it to. One more point, you have an if/if else/else checking for a-z, 0-9, then anything else.

您的代码将按照您希望的方式工作。还有一点,你有一个if/if else/else /else检查a-z, 0-9,然后还有其他的。

Because your first if and your else are identical code it means there's a simplification that can be done there. Just removing the entire first if and changing your else if to just an if will give you the exact same thing as what you're doing.

因为你的第一个if和你的else都是相同的代码,这意味着有一个简化可以在那里完成。如果你把你的else if换成an,它就会给你和你所做的完全一样的东西。

#2


3  

You should not be using atoi: it converts a string to int, not a single char.

您不应该使用atoi:它将字符串转换为int,而不是单个char。

Here is what happens: when you see a two-digit number, say, 34, the first iteration pssses both digits to atoi, gets 34, and multiplies it by ten, making 340. The following iteration picks up 4, and happily adds it to 340, for the cumulative result of 344.

这里是发生的情况:当你看到一个两位数的数字,比如说,34,第一个迭代将两个数字都变成了atoi,得到34,然后乘以10,得到340。下面的迭代获得4,并愉快地将其添加到340,以获得344的累积结果。

If you would like to convert a single char that represents a digit to an int, use subtraction:

如果你想要转换一个字符,它表示一个数字到一个整数,使用减法:

digit = *str - '0';

Moreover, your code for handling multi-digit numbers is, well, unorthodox, making it hard to understand. Instead of multiplying the current value by ten when you see that the next character is a digit, you should multiply the prior value by ten when you see a digit. This works even for the first digit, when the prior value is 0, because ten times zero is still a zero.

此外,你处理多位数数字的代码是不正统的,让人难以理解。当你看到下一个字符是一个数字时,你应该把之前的值乘以10,而不是把当前值乘以10。这对于第一个数字是有效的,当之前的值是0时,因为10乘以0仍然是0。

You should eliminate the if(((*str+index+1)>='0') && (*str+index+1)<='9') and its then branch, and modify its else branch as follows:

您应该删除if((*str+index+1)>='0') && (*str+index+1)<='9')及其分支,并修改其else分支如下:

digit = 10*digit + *(str+index) - '0';
if (((*str+index+1)<'0') || (*str+index+1)>'9') {
    fprintf(stdout,"%d",digit); fflush(stdout);
    digit = 0;
}

#3


1  

How about just using sscanf for that ? like this:

就用sscanf吧?是这样的:

sscanf(str, "%s %d %d", str1, &num1, &num2);

If you can't use sscanf, for some reason, then you should at least use isalpha() and isdigit() to check for characters and numbers, respectively.

如果您不能使用sscanf,出于某种原因,那么您至少应该使用isalpha()和isdigit()来检查字符和数字。

So instead of using this:

所以不要用这个:

if((*(str+index)>='a') &&( *(str+index)<='z')) {
    .....
}

Use this:

用这个:

if (isalpha(*str+index)) {
    .....
}

#4


0  

One of the problems with your code was digit += atoi(str+index); this will take, for example "12" will convert to int, and print 12 than in the next iteration it will take "2" and print it again, therefore printing "122". An easy solution it to replace that line of code for this digit = str[index] - '0';, now it will convert char by char.

您的代码的一个问题是数字+= atoi(str+index);例如,“12”将转换为int,而打印12,而不是在下一个迭代中,它将采用“2”并再次打印,因此打印“122”。一个简单的解决方案,它将替换这一数字= str[索引]- '0'的代码行,现在它将通过char转换字符。

Instead of having so much if/ else, it preferable to use just one condition to check if it is or not a digit, like this code on the example below.

与其有太多的if/ else,不如只使用一个条件来检查它是否为一个数字,比如下面这个例子中的代码。

#include<stdio.h>
#include<stdlib.h>
int main()
{
    char c;
    char *str = NULL;
    str = (char *)malloc(20*sizeof(char)); /*just sample code, not robust*/
    memset(str,'\0',20*sizeof(char)); 

    if(str == NULL)
    {
        fprintf(stderr,"Error: failed to allocate memory.\n"); fflush(stderr);
        return 0;
    }

    /*store user input*/
    int index = 0;
    while((c=getchar()) != '\n')
    {
        *(str+index) = c;
        index++;
    }

    int digit = 0;
    for(index = 0; *(str+index)>0; index++)
    {

        if (isdigit(*(str+index)))
        {
        while (isdigit(*(str+index)))
        {
                digit = str[index] - '0';   
                fprintf(stdout,"%d",digit); fflush(stdout);
                digit = 0;
                index++;
        }
        index--;
        }
        else{ 
            fprintf(stdout,"%c",*(str+index)); fflush(stdout);
        }
    }
    printf("\n");
    free(str);
    return 0;
}