0

I have to write a program that converts an user input (which is a string) to an Integer. In the same time it should check, if the user input really is a number. And also everything in one method.

and NO LIBRARY FUNCTIONS allowed.

I can't figure any idea how to do it. All I got for the beginning is just this pathetic structure

#include <stdio.h>

void main()
{
  char input[100];
  int i;
  int sum = 0;
  printf("Type a String which will be converted to an Integer: ");
  scanf("%c, &input");

  for (i = 0; i < 100; i++)
   {

   }
}

I appreciate any help, thanks

DeathToxic
  • 157
  • 1
  • 7
  • Take a look at this as a first step: http://www.cplusplus.com/reference/cstdlib/atol/ – kazbeel Jan 13 '16 at 13:05
  • How would you do on paper? btw use `scanf("%s", input)` – Ed Heal Jan 13 '16 at 13:06
  • You should start checking if inserted char is `>='0'` (0x30) and `<='9'` (0x39) – LPs Jan 13 '16 at 13:06
  • sorry I edited it now, I am not allowed to use any library functions – DeathToxic Jan 13 '16 at 13:07
  • what you mean by String will be converted to an integer? Means you want like this: (input-Death and output will be 68 101 97 116 104).? – Sagar Patel Jan 13 '16 at 13:26
  • sorry for the misunderstanding, I meant like: the user types in 2A8B Then it checks if there are only numbers, and of course 2A8B is not a real number. So the user has to write 28 as example. after he wrote it, the program converts the string "28" into an full integer 28. – DeathToxic Jan 13 '16 at 13:30

7 Answers7

3

The conversion is the easy part...

But if you must not use library functions,

  • there is only one way to take a string, and that is argv;
  • there is only one way to give an integer, and that is the exit code of the program.

So, without much ado:

int main( int argc, char * argv[] )
{
    int rc = 0;
    if ( argc == 2 ) // one, and only one parameter given
    {
        unsigned i = 0;
        // C guarantees that '0'-'9' have consecutive values
        while ( argv[1][i] >= '0' && argv[1][i] <= '9' )
        {
            rc *= 10;
            rc += argv[1][i] - '0';
            ++i;
        }
    }
    return rc;
}

I did not implement checking for '+' or '-', and did not come up with a way to signal "input is not a number". I also just stop parsing at the first non-digit. All this could probably be improved upon, but this should give you an idea of how to work around the "no library functions" restriction.

(Since this sounds like a homework, you should have to write some code of your own. I already gave you three big spoons of helping regarding argv, the '0'-'9', and the conversion itself.)


Call as:

<program name> <value>

(E.g. ./myprogram 28)

Check return code with (for Linux shell):

echo $?

On Windows it's something about echo %ERRORLEVEL% or somesuch... perhaps a helpful Windows user will drop a comment about this.


Source for the "'0'-'9' consecutive" claim: ISO/IEC 9899:1999 5.2.1 Character sets, paragraph 3:

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.

I'm sure this is preserved in C11, but I only have the older C99 paper available.

DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • and this works without library function? well I am gonna try it later, thanks – DeathToxic Jan 13 '16 at 13:25
  • @DeathToxic: Well, what happened to you trying it? The accepted answer does not fit your requirements (program with no library functions). None of the other answers do. This one does. – DevSolar Jan 13 '16 at 13:44
  • If I try to run it it doesn't show anything, it's just an empty console – DeathToxic Jan 13 '16 at 13:51
  • @DeathToxic: But you do know what a return code is? If you don't, please read the answer again. There is no way to print to the console without using library functions. (Unless I'd start hacking the hardware addresses or use the BIOS in text mode. :-D ) – DevSolar Jan 13 '16 at 13:52
  • oh okay well I was told that the only one I could use would be the function since I heard there are some header informations, that's why I accepted the other one, but so basically this one would be comepletely without header function? – DeathToxic Jan 13 '16 at 13:55
  • @DeathToxic: Indeed. And if you're allowed to use `` (why didn't you tell us?), `scanf( "%d", &number )` would be *much* easier. Tell your instructor hi from me, and his assignments could use some thinking through. ;-) – DevSolar Jan 13 '16 at 13:55
  • good to know, I always wondered how it would look like without header informations, I am just not sure what the argv does – DeathToxic Jan 13 '16 at 13:58
  • @DeathToxic: Oh, gosh... you haven't been told? You can define `int main()` and not take any arguments from the command line. Or you define `int main( int argc, char * argv[] )`, and get the *number* of command-line arguments in `argc`, and (if `argc` is not zero for some reason) a list of the argument strings in `argv` (the first being the name of the program itself, which might be empty). The value of `argv[argc]` is always a null pointer. The name of the variables doesn't actually matter, but it is canonical to call them `argc` and `argv`. – DevSolar Jan 13 '16 at 14:02
  • actually all my teachers do are just telling me to go look in the internet. bad school here, well. But thanks got a better picture of that now. – DeathToxic Jan 13 '16 at 14:11
  • @DeathToxic: I strongly suggest getting [a good C book](http://stackoverflow.com/questions/562303). About 90% of the code you will see "on the internet" displays pretty dismal coding style, and usually next to no (or, worse, downright wrong) explanations. – DevSolar Jan 13 '16 at 14:13
  • yeah I thought this too, but I almost don't have time for this. Like I had to learn php, I saw php for first time, all they told me was that you define a variable with the $ symbol and then I had 10 hours time in the lession to create a whole blog site... I only use this site here if I really can't go further anymore – DeathToxic Jan 13 '16 at 14:20
  • It is in C11. §5.2.1 3 – chux - Reinstate Monica Jan 13 '16 at 15:40
2

Take hightes digit and add it to number, multiply the number by 10 and add the next digit. And so on:

#include <stdio.h> // scanf, printf

void main()
{
    char input[100];
    printf("Type a String which will be converted to an Integer: ");
    scanf("%s", input);

    int number = 0;
    int neg = input[0] == '-';
    int i = neg ? 1 : 0;
    while ( input[i] >= '0' && input[i] <= '9' )
    {
      number *= 10;             // multiply number by 10
      number += input[i] - '0'; // convet ASCII '0'..'9' to digit 0..9 and add it to number           
      i ++;                     // step one digit forward
    }
    if ( neg )
       number *= -1;

    printf( "string %s -> number %d", input, number );
}

input[i] - '0' works, because ASCII characters '0'..'9' have ascending ASCII codes from 48 to 57.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
0

Lot of things which are missed. Firstly taking a string in is done by scanf("%s",input); By the way in which you are receiving it, it only stores a character, secondly run the loop till the length of the string recieved. Check the below code.

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

void main()
{
    char input[100];
    int i;
    int sum = 0;
    printf("Type a String which will be converted to an Integer: ");
    scanf("%s", input);

    for (i = 0; i < strlen(input); i++)
    {
        if(input[i]>=48 && input[i]<=57)
        {
             //do something, it is a digit
             printf("%d",input[i]-48);
             //48 is ascii value of 0
    }
}  
sameera sy
  • 1,708
  • 13
  • 19
0

So basically you want to know how something like the standard library atoi works. In order to do this, you need to consider how strings represent numbers.

Basically, a string (that represents a number) is a list o digits from 0 to 9. The string abcd (where a, b, c, d are placeholders for any digit) represents the number a*10 ^ 3 + b*10^2 + c * 10 + d (considering base 10 here, similar for other bases). So basically you need to decompose the string as shown above and perform the required arhitmetic operations:

// s - the string to convert
int result = 0;
for (int index = 0; index < strlen(s); index++) {
    result = result * 10 + s[index] - '0';
}

The operation s[index] - '0' converts the character that represent a digit to its value.

Paul92
  • 8,827
  • 1
  • 23
  • 37
0
//  the function returns true for success , and false for failure
// the result is stored in result parameter
// nb: overflow not handled

int charToInt(char *buff,int *result){
    *result=0;
    char c;
    while(c=*buff++){
        if((c < '0') || (c >'9')) // accept only digits;
            return 0;
        *result *= 10;
        *result += c-'0';
    }
    return 1;
}
milevyo
  • 2,165
  • 1
  • 13
  • 18
-1

Try it:

#include <stdio.h>

void main()
{
  char input[100];
  int i,j;
  int val = 0;
  printf("Type a String which will be converted to an Integer: ");
  scanf("%s",input);

    for(j=0; input[j] != '\0'; j++); // find string size
    for (i = 0; i < j; i++)
    {
        val = val * 10 + input[i] - 48;
    }   
}
msc
  • 33,420
  • 29
  • 119
  • 214
-1

If you want your code to be portable to systems that don't use ASCII, you'll have to loop over your char array and compare each individual character in the source against each possible number character, like so:

int digit;
switch(arr[i]) {
    case '0':
        digit=0; break;
    case '1':
        digit=1; break;
    // etc
    default:
        // error handling
}

Then, add the digit to your result variable (after multiplying it by 10).

If you can assume ASCII, you can replace the whole switch statement by this:

if(isdigit(arr[i])) {
    digit=arr[i] - '0';
} else {
    // error handling
}

This works because in the ASCII table, all digits are found in a single range, in ascending order. By subtracting the ordinal value of the zero character, you get the value of that digit. By adding the isdigit() macro, you additionally ensure that only digit characters are converted in this manner.

Wouter Verhelst
  • 1,269
  • 1
  • 12
  • 27