QTextStream格式化文本:位级表示 / 字节表示 / 内存地址

【写在前面】

最近在看《深入理解计算机系统 第二版》简称 CSAPP,这本书我是极力推荐的,深度和广度都有 ( 而且讲解得非常仔细 )。

然后自己是第二遍看了 ( 之前看的第一版,第二版有不少新东西 ),里面的题也是一直跟着做的,就顺手写了几个小函数来方便做题。

因为书里的一些题目很多时候需要查看变量的 【位级表示 / 字节表示 / 内存地址】,然而对简单打印出来的格式很不满意,所以想着 Qt 中比较好用的 QTextStream 来进行格式化输出 ( QDebug 也可以,但还不够方便)。

所以这里就简单分享一些小技巧吧。


【正文开始】 

先来看代码:

#include 
#include 

void show_addr(void *in, size_t size)
{
    QString result;
    QTextStream stream(&result);
    stream.setFieldWidth(12);
    stream.setFieldAlignment(QTextStream::AlignLeft);
    stream << "address: ";
    stream.setFieldAlignment(QTextStream::AlignRight);
    for (size_t i = 0; i < size; i++) {
        stream << static_cast(in) + i;
    }

    qDebug().noquote() << result;
}

void show_bits(void *in, size_t size)
{
    QString result;
    QTextStream stream(&result);
    stream.setFieldWidth(12);
    stream.setFieldAlignment(QTextStream::AlignLeft);
    stream << "bits: ";
    stream.setFieldAlignment(QTextStream::AlignRight);
    for (size_t i = 0; i < size; i++) {
        uchar uc = static_cast(in)[i];
        stream << QString::number(uc, 2).rightJustified(8, '0');
    }

    qDebug().noquote() << result;
}

void show_bytes(void *in, size_t size)
{
    QString result;
    QTextStream stream(&result);
    stream.setFieldWidth(12);
    stream.setFieldAlignment(QTextStream::AlignLeft);
    stream << "bytes: ";
    stream.setFieldAlignment(QTextStream::AlignRight);
    for (size_t i = 0; i < size; i++) {
        uchar uc = static_cast(in)[i];
        stream << QString::number(uc, 16).rightJustified(2, '0');
    }

    qDebug().noquote() << result;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    uint64_t mx = static_cast(-1);
    show_bits(&mx, sizeof(mx));
    show_bytes(&mx, sizeof(mx));
    show_addr(&mx, sizeof(mx));

    return a.exec();
}

输出如下 ( 注意: 我的电脑是小端字节序 ):

QTextStream格式化文本:位级表示 / 字节表示 / 内存地址_第1张图片

可以看到,格式化后的输出顺眼多了 。

其中,主要依靠这几个函数完成:

QString QString::number(long n, int base = 10):

将数数字(整数、浮点数、有符号、无符号等)转换为 QString 类型,而基数可以简单的理解为进制。

QString QString::rightJustified(int width, QChar fill = QLatin1Char(' '), bool truncate = false) const:

返回一个 size() 宽度的字符串,其中包含填充字符,后跟该字符串。 例如:

QString s =“apple”;

QString t = s.rightJustified(8,'.'); // t ==“ ...apple”

如果 truncate false 并且字符串的 size() 大于 width,则返回的字符串是该字符串的副本。

如果 truncate true,并且字符串的 size() 大于 width,则结果字符串在位置 width 处被截断。

QString str = “Pineapple”;

str = str.rightJustified(5,'.',true); // str ==“Pinea”

void QTextStream::setFieldWidth(int width):

将当前字段的宽度设置为 width 。 如果 width 为 0 ( 默认值 ),则字段宽度等于生成的文本的长度。

注意:字段宽度适用于调用此函数后附加到此流的每个元素 ( 例如,它也填充 endl )。 此行为不同于 STL 中的类似类,在 STL 中,字段宽度仅适用于下一个元素。

QTextStream :: setFieldAlignment(QTextStream :: FieldAlignment mode):

将字段对齐方式设置为 mode。 与 setFieldWidth() 一起使用时,此函数允许您生成格式化的输出,其中文本左对齐右对齐居中对齐。  

void QTextStream::setPadChar(QChar ch) :

 将填充字符设置为 ch。 默认值为 ASCII 空格字符 (' ') 或 QChar(0x20)。 生成文本时,此字符用于填充字段中的空格,即超过 fieldWidth() 的部分。


【结语】

实际上,另一种方法是使用 QTextStream bin() / hex() / setIntegerBase() 也能达到同样的效果,但是会麻烦许多。

最后再推荐一次《深入理解计算机系统 第二版》,话说第二版题目的答案都详细很多了,很赞 。

你可能感兴趣的:(Qt,杂谈)