简体   繁体   中英

How do I convert from ASCII to hex values and also increment char pointers?

int main()
{
    ifstream infile;
    infile >> std::noskipws;
    size_t size = 0;
    infile.open("tworecords.dat", ios::binary);

    if(infile.is_open())
    {
        infile.seekg(0, ios::end);
        size = infile.tellg();
        infile.seekg(0, ios::beg);

        char *buffer = new char [size];
        infile.read(buffer, size);
        infile.close();

        for(int i=0; i <59; i++)
        {
            c1 = (*buffer);
            buffer++;
            cout << c1 << endl;
        }

        std::cout.write (buffer, size);
        cout << endl;
        delete[] buffer;
    }
    return 0;
}

I'm reading in the data values from the file, and they appear in ASCII format. How do I make it so that I can see the values as hex values?

My second question is how do I increment char pointers to increase 1 by one, so that it reads one value at a time, like I am attempting to do in the code?

This might get you started. Annotated code:

#include <iomanip>
#include <iostream>

int main() {
    // set integer output to uppercase-, hex-mode
    // with '0' as fill character for small byte values
    std::cout << std::hex << std::uppercase << std::setfill('0');
    // declare a buffer
    // note that you could use a std::vector<char> for your reads as well
    std::string input;
    // read a sequence of bytes (TODO: replace with reading from file)
    while(std::getline(std::cin, input)) {
        // iterate over the bytes as unsigned chars (not signed!)
        // to support characters in the negative byte value range (>7F)
        // (using C++11 range-based for loop)
        for (unsigned char i : input)
            // set width format for each value to 2 (00 to FF)
            // (setting is only active for the next insert operation)
            // insert the value as a multibyte integer
            // to get the proper basic_ostream::operator<< overload
            std::cout << std::setw(2) << static_cast<int>(i);
        std::cout << std::endl;
    }
}

Usage Example:

$ g++ test.cc -std=c++11
$ echo "Hello World" | ./a.out
48656C6C6F20576F726C64

References:


As for your other question about how to iterate a character array, you have a couple of options. See this code example:

#include <iostream>

int main() {
    // declare buffer and size
    // intentionally left out null-termination and sizeof()
    // for the purpose of this demonstration
    char buf[] = {'a','b','c','d','e'};
    std::size_t size = 5; 
    // iterate using array indexing
    for (std::size_t i = 0; i < size; i++) std::cout << buf[i];
    std::cout << "\n";
    // iterate using pointer
    for (char *p = buf; p != buf+size; p++) std::cout << *p;
    std::cout << "\n";
}

Note that you can (and should) use a std::vector<char> as a buffer. This has some advantages. Biggest ones: trivial to pass in and out of functions, you can always call for the size() of the buffer, and, memory management is done by the standard library.

For example (untested code):

{
    // declare buffer of the appropriate size
    std::vector<char> buffer(size);
    // read data into the buffer
    infile.read(&(buffer[0]), buffer.size());
    infile.close();
    // iterate the buffer using std::vector<char>::iterator
    for (auto it = buffer.begin(); it != buffer.end(), ++it) {
        // do your output operations
    }
} // <-- storage duration of buffer ends automatically where the scope ends

More references:

Aside from the hex-conversion I think your loop should be like the one below (see the comments):

    for(int i=0; i <size; i++)  // <-- size, not 59
    {
        c1 = buffer[i];         // copy the i'th element of buffer.  If you increment
                                // buffer (as in your example), you can't delete
                                //  it later because you lost the initial address
        cout << c1 << endl;
    }

Depending on the format of the hex numbers, if you want to output digit by digit (eg turn an 'A' into 10, etc. a very basic way is this:

    int dec; 
    if (c1>='0' && c1<='9') {
       dec= c1 - '0';   // e..g for '0' (ascii 48) it will make dec= (int)0.
    }
    else 
    if (c1>='A' && c1<='F') {
       dec= 10 + (c1 - 'A');   // e..g for 'A' (ascii 65) it will make dec= (int)10.
    }
    else {
         // should not happen or handle lower chase characters too
    }

Another way, using sscanf would be:

// convert one hex digit from c1 into a corresponding decimal number
char hex[2];
int dec;
hex[0]= c1;
hex[1]= '\0';
sscanf(hex, "%1x", &dec);
#include <iomanip>

for(int i=0; i <size; i++)  // <-- size, not 59
{
    c1 = buffer[i];         // copy the i'th element of buffer.  If you increment
                            // buffer (as in your example), you can't delete
                            //  it later because you lost the initial address
    cout << hex << c1 << dec << endl;
}

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