如何将ASCII转换为十六进制值并增加char指针?

时间:2013-06-11 18:54:39

标签: c++ pointers hex

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;
}

我正在读取文件中的数据值,它们以ASCII格式显示。如何制作它以便我可以将值视为十六进制值?

我的第二个问题是如何增加char指针以逐个增加,以便它一次读取一个值,就像我在代码中尝试做的那样?

3 个答案:

答案 0 :(得分:8)

这可能会让你开始。带注释的代码:

#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;
    }
}

用法示例:

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

参考文献:


关于如何迭代字符数组的另一个问题,你有几个选择。请参阅此代码示例:

#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";
}

请注意,您可以(并且应该)使用std::vector<char>作为缓冲区。这有一些优点。最大的:无法传入和传出函数,您总是可以调用缓冲区的size(),并且内存管理由标准库完成。

例如(未经测试的代码):

{
    // 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

更多参考资料:

答案 1 :(得分:0)

除了十六进制转换之外,我认为你的循环应该如下所示(参见注释):

    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;
    }

根据十六进制数字的格式,如果你想逐位输出(例如将'A'变成10,等等,这是一个非常基本的方法:

    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
    }

另一种方法,使用sscanf将是:

// 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);

答案 2 :(得分:0)

#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;
}