简体   繁体   中英

C++ Turning Character types into int type

So I read and was taught that subtracting '0' from my given character turns it into an int, however my Visual Studio isn't recognizing that here, saying a value of type "const char*" cannot be used to initialize an entity of type int in C++ programming here.

bigint::bigint(const char* number) : bigint() {


int number1 = number - '0'; // error code
for (int i = 0; number1 != 0 ; ++i)
{
    digits[i] = number1 % 10;
    number1 /= 10;
    digits[i] = number1;
}
}

The goal of the first half is to simply turn the given number into a type int. The second half is outputting that number backwards with no leading zeroes. Please note this function is apart of the class declared given in a header file here:

 class bigint {
    
    public:
      static const int MAX_DIGITS = 50;
    
    private:
      int digits[MAX_DIGITS];
    
    public:
    
      // constructors
      bigint();
      bigint(int number);
      bigint(const char * number);
}
  

Is there any way to convert the char parameter to an int so I can then output an int? Without using the std library or strlen, since I know there is a way to use the '0' char but I can't seem to be doing it right.

You can turn a single character in the range '0'..'9' into a single digit 0..9 by subtracting '0' , but you cannot turn a string of characters into a number by subtracting '0' . You need a parsing function like std::stoi() to do the conversion work character-by-character.

But that's not what you need here. If you convert the string to a number, you then have to take the number apart. The string is already in pieces, so:

bigint::bigint(const char* number) : bigint() {
    while (number) // keep looping until we hit the string's null terminator
    {
        digits[i] = number - '0'; // store the digit for the current character
        number++; // advance the string to the next character
    }
}

There could be some extra work involved in a more advanced version, such as sizing digits appropriately to fit the number of digits in number . Currently we have no way to know how many slots are actually in use in digits , and this will lead to problems later when the program has to figure out where to stop reading digits.

I don't know what your understanding is, so I will go over everything I see in the code snippet.

First, what you're passing to the function is a pointer to a char , with const keyword making the char immutable or "read only" if you prefer.

A char is actually a 8-bit sized 1 integer. It can store a numerical value in binary form, which can be also interpreted as a character.

Fundamental types - cppreference.com

Standard also expects char to be a "type for character representation". It could be represented in ASCII code, but it could be something else like EBCDIC maybe, I'm not sure. For future reference just remember that ASCII is not guaranteed, although you're likely to never use a system where it's no ASCII (if I'm correct). But it's not so much that char is somehow enforcing encoding - it's the functions that you pass those chars and char pointers to, that interpret their content as characters in ASCII encoding, while on some obscure or legacy platforms they could actually interpret them as characters in some less common encoding. Standard however demands that encoding used has this property: codes for characters '0' to '9' are subsequent, and thus '9' - '0' means: subtract code of '0' from code of '9'. The result is 9, because code for '9' is 9 positions from code for '0' in ASCII. Ranges 'a'-'z' and 'A'-'Z' have this quality as well, in case you need that, but it's a little bit trickier if your input is in base higher than 10, like a popular base of 16 called hexadecimal.

A pointer stores an address, so the most basic functionality for it is to "point" to a variable. But it can be used in various ways, one of which, very frequent in C, is to store address of the beginning of an array of variables of the same type. Those could be chars. We could interpret such an array as a line of text, or a string (a concept, not to be confused with C++ specific string class).

Since a pointer does not contain information on length or end of such an array, we need to get that information across to the function we pass the pointer to. Sometimes we can just provide the length, sometimes we provide the end pointer. When dealing with "lines of text" or c-style strings, we use (and c standard library functions expect) what is callled a null-terminated string . In such a string, the first char after the last one used for a line is a null , which is, to simplify, basically a 0. A 0, but not a '0'.

So what you're passing to the function, and what you interpret as, say 416, is actually a pointer to a place in memory where '4' is econded and stored as a number, followed by '1' and then '6', taking up three bytes. And depending on how you obtained this line of text, '6' is probably followed by a NULL, that is - a zero. NULL - cppreference.com

Conversion of such a string to a number first requires a data type able to hold it. In case of 416 it could be anything from short upwards. If you wanted to do that on your own, you would need to iterate over entire line of text and add the numbers multiplied by proper powers of 10, take care of signedness too and maybe check if there are any edge cases. You could however use a standard function like int atoi (const char * str); atoi - cplusplus.com

Now, that would be nice of course, but you're trying to work with "bigints". However you define them, it means your class' purpose is to deal with numbers to big to be stored in built-in types. So there is no way you can convert them just like that.

What you're trying to do right now seems to be a constructor that creates a bigint out of number represented as a c style string. How shall I put it... you want to store your bigint internally as an array of it's digits in base 10 (a good choice for code simplicity, readability and maintainability, as well as interoperation with base 10 textual representation, but it doesn't make efficient use of memory and processing power.) and your input is also an array of digits in base 10, except internally you're storing numbers as numbers, while your input is encoded characters. You need to:

  1. sanitize the input (you need criteria for what kind of input is acceptable, fe. if there can be any leading or trailing whitespace, can the number be followed by any non-numerical characters to be discarded, how to represent signedness, is + for positive numbers optional or forbidden etc., throw exception if the input is invalid.
  2. convert whatever standard you enforce for your input into whatever uniform standard you employ internally, fe. strip leading whitespace, remove + sign if it's optional and you don't use it internally etc.
  3. when you know which positions in your internal array correspond with which positions in the input string, you can iterate over it and copy every number, decoding it first from ASCII.

A side note - I can't be sure as to what exactly it is that you expect your input to be, because it's only likely that it is a textual representation - as it could just as easily be an array of unencoded chars. Of course it's obviously the former, which I know because of your post, but the function prototype (the line with return type and argument types) does not assure anyone about that. Just another thing to be aware of. Hope this answer helped you understand what is happening there.

PS. I cannot emphasize strongly enough that the biggest problem with your code is that even if this line worked:

int number1 = number - '0'; // error code

You'd be trying to store a number on the order of 10^50 into a variable capable of holding on the order of 10^9

The crucial part in this problem, which I have a vague feeling you may have found on spoj.com is that you're handling BIGints. Integers too big to be stored in a trivial manner.

1 ) The standard does not actually require for char to be this size directly, but indirectly it requires for it to be at least 8 bits, possibly more on obscure platforms. And yes, I think there were some platforms where it was indeed over 8 bits. Same thing with pointers that may behave strange on obscure architectures.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM