2

So i have this loop the check user input:

int ch, num;

while ((ch = getchar()) != '\n')
{
    if (isdigit(ch))
    {
        num = ch - 48;   
    }
}

So according this table:

Character   Decimal Value
0           48
1           49
2           50
3           51
4           52
5           53
6           54
7           55
8           56
9           57

I am using this way to get my number: num = ch - 48; And if for example i want to multiple my number by 10 ?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
Dana Yeger
  • 617
  • 3
  • 9
  • 26
  • What line you are using for user input? Can you post that here. – Pavan Vora Nov 24 '17 at 07:27
  • input is for example 2 3 1 4 5 until the new line – Dana Yeger Nov 24 '17 at 07:28
  • why dont you take integer inputs using scanf() – Pras Nov 24 '17 at 07:30
  • I think the way you are doing is not correct let me give answer for this. the best way. :) – Pavan Vora Nov 24 '17 at 07:32
  • Note that `getchar()` returns `EOF` in the uncommon event of a read error in the function call, which could lead to an infinite loop in the posted code. Best to always check for `EOF` when controlling loops with `getchar()`. – ad absurdum Nov 24 '17 at 08:29
  • Instead of `num = ch - 48` use `num = ch - '0'`. This is guaranteed to work with all existing standardised character sets (numeric digits are a contiguous set, starting with `'0'`) and doesn't rely on `'0'` having a numeric value of `48` (e.g. a character set that is not compatible with ANSI). – Peter Nov 24 '17 at 10:46

4 Answers4

2

how to get normal value of int without using value - 48?

Like this:

num = ch - '0';

Read more in How to convert char to integer in C?


In both cases, you then just do:

num *= 10;

since num is of type int.


Warning: Others suggest int atoi (const char * str); to get the number, which expects as an input a string, not a character! So if you pass a character to that function (thus a non-null-terminated string, you will invoke Undefined Behavior).

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • This answer is solid, with one caveat: it assumes that digits in the character-set are contiguous and ascending. As far as I know, every character-set presently defined satisfies this assumption, so it's probably not an issue...but you could use a `switch(ch) {case '0': ...}` construction if you're paranoid. – lockcmpxchg8b Nov 24 '17 at 07:53
  • 3
    @lockcmpxchg8b: The C standard insists on this being the case. No need to be paranoid; just follow the standard. – Bathsheba Nov 24 '17 at 08:02
  • 1
    Oh, yep. Per n1750, S5.2.1: "In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous." – lockcmpxchg8b Nov 24 '17 at 08:08
2

You should always use the idiomatic

num = ch - '0';

The reason being that this works for any encoding supported by C: C mandates that the digits 0 to 9 appear contiguously and in ascending order. If you hardcode the value of '0' to 48 say, you are not, strictly speaking, writing portable C.

Note that the expression ch - '0' is an int type in C due to the rules of argument promotion ('0' is an int type in C). You are therefore free to multiply this by 10 in the same way as you would apply arithmetic operations to any int type.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

Here's the best way to read input from user till the new line. I'm posting one example you can go through it and implement your code as you need.

This example will read for user input in integer untill newLine(\n). Make sure you are not giving space at last.

Sample Code:

#include <stdio.h>
int main(void) {
    int i=0,size,arr[10000];
    char temp; 
    do{
        scanf("%d%c", &arr[i], &temp); 
        i++; 
        } while(temp!= '\n');

    size=i; 

    for(i=0;i<size;i++){ 
        printf("%d ",arr[i]); 
    } 
return 0;
}
Pavan Vora
  • 1,634
  • 14
  • 19
  • This approach is more flexible in that it will accept multi-digit numbers, but scanf won't return when a single digit is entered. The user will have to hit enter to signal that they're done typing. This answer accepts several numbers separated by non-digit characters, which is not in the OP's problem. – lockcmpxchg8b Nov 24 '17 at 08:01
  • it will return when single digit is entered. – Pavan Vora Nov 24 '17 at 08:05
  • If for example i do not want to insert the current int inside the array but do with it something else: the current number inside the loop is &temp ? – Dana Yeger Nov 24 '17 at 08:05
  • I pasted this code into a source file and compiled it. The `scanf` call does not return upon typing a single digit. The user must also hit , unlike the OP's getchar() case. – lockcmpxchg8b Nov 24 '17 at 08:10
  • Ya but after giving input anyway he needs to press enter. – Pavan Vora Nov 24 '17 at 08:17
  • @DanaYeger no, &temp holds the non-digit character the user entered after the number (will be '\n' for the last number). If you don't want the array, just replace `&arr[i]` in the `scanf` call with `&someInt` – lockcmpxchg8b Nov 24 '17 at 08:18
  • ohk got that. :) – Pavan Vora Nov 24 '17 at 08:19
0

You can use atoi() function here.You are getting ch as input from user. You can convert it into string as follows-

char number[2] ="";
number[0]=ch;
number[1]='\0'

num = atoi(number);

This will solve your problem.

Ganeshdip
  • 389
  • 2
  • 10
  • I try int n = atoi(ch); but this crash – Dana Yeger Nov 24 '17 at 07:29
  • @DanaYeger it will crash, because `atoi()` expects a string, not a char! Check my answer please. – gsamaras Nov 24 '17 at 07:37
  • @gsamaras Hist updated answer passes a string as expected. – Gerhardh Nov 24 '17 at 07:39
  • @DanaYeger - Please see my updated answer as I have converted the character into string and then passed it to atoi(). – Ganeshdip Nov 24 '17 at 07:39
  • You mean yours. =) Now the updated answer makes too many unnecessairy steps though. I mean these extra steps are not needed, since @DanaYeger doesn't need to call that function. – gsamaras Nov 24 '17 at 07:40
  • @Ganeshdip -- why not use an initializer for this:`char number[] = { ch, '\0' };`? Or even a compound literal: `num = atoi((char []){ ch, '\0' });`? Still, there is no need to go to such lengths when `num = ch - '0';` is guaranteed to work. – ad absurdum Nov 24 '17 at 08:21