简体   繁体   中英

C++ convert char to int

Sorry for my bad English. I need to build app which converts hex to rgb. I have file U1.txt with content inside:

2 3
008000
FF0000
FFFFFF
FFFF00
FF0000
FFFF00

And my codeblocks app:

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    int a;
    int b;
    string color;

    ifstream data("U1.txt");
    ofstream result("U1result.txt");

    data >> a;
    data >> b;

    for (int i = 0; i < a * b; i++) {
        data >> color;
        cout << color[0] * 16 + color[1] << endl;
    }

    data.close();
    result.close();

    return 0;
}

This gives me 816 . But it should be 0. I think color[0] is not an integer, but a char and it multiplies by ASCII number.. I've tried many ways with atoi, c_str() and it not working. PS do not suggest stoi(), because I need to do this homework with older C++. Thanks in advance and have a good day ;)

You can directly store the hexadecimal values in an int with std::hex .

int b;
ifstream data("U1.txt");
data >> std::hex >> b;

Since those encodings use 24 bits, you have to start out with an integer type that holds at least 24 bits. And for this kind of packing and unpacking, it really ought to be unsigned, so you don't get tangled up in sign bits. That means using std::uint_least32_t , which is the smallest unsigned type that can hold at least 32 bits. (Yes, 24 would fit better, but there is no least24 type; 32 is the best you can do).

If your compiler doesn't provide those fixed-width types ( std::uint_least32_t ), you can use unsigned long . It's required to be at least 32 bits wide. It could be larger, and the reason for using std::uint_least32_t is that your compiler might have, for example, a 32-bit integer, in which case unsigned int would be 32 bits wide. But you can't count on that, so either use the fixed-width type or use unsigned long to ensure that you have enough bits.

Since the character inputs are encoded in hexadecimal, you need to tell the input system to interpret them as hex values. So:

std::uint_least32_t value;
data >> std::hex >> value;

Now you've got the value in the low 24 bits of value . You need to pick out the individual R, G, and B parts of that value. That's straightforward. To get the low 8 bits, just mask out the higher ones:

std::cout << (value & 0xFF) << '\n';

To get the next 8 bits, shift and mask:

std::cout << ((value >> 8) & 0xFF) << '\n';

And, naturally, to get the upper 8 bits, shift and mask:

std::cout << ((value >> 16) & 0xFF) << '\n';

A rather unelegant but also working answer is to subtract all your chars by 48 as thats where numbers start in ASCII. This is also the reason why you get 816 as:

48*16+48 = 816

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