【问题标题】:Issue reading in a char array using sscanf in octal using either C or C++使用 C 或 C++ 在八进制中使用 sscanf 在 char 数组中读取问题
【发布时间】:2017-04-03 06:48:36
【问题描述】:

当尝试将“24”的八进制值读入无符号整数时,我得到 0。只需将十进制值作为 char 数组传入即可。

我需要一个 32 位无符号整数的最终值。初始值是从二进制文件中读入的。

MCVE

simple.cpp

#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    char count[4] = "\030\000\000"; // Just "24" works
    __uint32_t value;
    sscanf(count, "%x", &value);
    fprintf(stderr, "%x", value);
    return 0;
}

编译并使用

$ g++ simple.cpp -g
$ ./a.out
0
$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609

【问题讨论】:

  • 你确实需要检查来自系统函数的返回值,比如sscanf(),如果发布的代码已经检查了返回值,很明显对sscanf()的调用失败了。代码中的任何其他问题都是次要的

标签: c++ c bits octal


【解决方案1】:

八进制值030 是一个单个字符,表示ASCII encoding 中的特殊“CAN”(取消)控制字符(这是英文字母、数字和标点符号的最常见编码)。

当您使用scanf (or its sibling sscanf) 时,它会尝试读取数字,在ASCII 编码中是060071 的值(对于数字09,包括在内)。

要能够使用sscanf 读取数字24,您需要两个字符'2''4'。 IE。 "24"(或"\062\064")。


如果您想将单个字符 '\030' 转换为整数值 24,则只需执行例如

value = count[0];

【讨论】:

  • @kshikama 不,scanf(及其兄弟)读取文本编码的字符串。
  • @kshikama 八进制 30 是十进制 24 是十六进制 18。如果你想要十六进制 24,你需要十进制 36、八进制 44 或字符 '$'
  • @kshikama 您似乎误解了字符串是什么,以及它是如何表示的。字符串是字符的序列。八进制值057574 是一个整数 值。如果要在字符串中表示整数,则需要使用单独的数字字符。
  • @kshikama 您似乎也误解了将字符串解析为数字的工作原理。如果你有字符串"057574",它可以转换成整数057574,与十六进制0x5f7c相同,与十进制值24444相同。如果您尝试将字符串 "057574" 解析为十六进制 if 将是十六进制值 0x57574,即八进制值 01272564 或十进制值 357748
  • @kshikama 你似乎拥有的不是一个字符串,而是一个小整数数组。虽然它们非常相似(因为它们都可以表示为char 的数组),但在语义上它们却非常不同。您需要将其视为一个小整数数组而不是字符串(使用uint8_tint8_t 会使其更加明确)。
【解决方案2】:

我假设您在来自二进制文件的记录中获得 4 个字节,并且您希望将这 4 个字节转换为 uint32_t 值。我还假设字节带有预期的字节序。

进行转换的最简单(也是最符合标准的方式)是将字节表示复制到变量中:

#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    char count[4] = "\030\000\000"; // Just "24" works
    __uint32_t value;
    memcpy(&value, count, sizeof(value));
    fprintf(stderr, "%d", value);
    return 0;
}

将按预期返回24

【讨论】:

  • 啊,是的!提交了一些小的更改,但这确实有效。
【解决方案3】:

这是您的代码版本,用于检查调用 scanf() 时是否出错

注意:不需要的 C++ 头文件被注释掉。

//#include <iostream>
//#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main( void )
{
    char count[4] = "\030\000\000"; // Just "24" works
    uint32_t value;
    if( 1 != sscanf(count, "%x", &value) )
    {
        fprintf( stderr, "sscanf failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, sscanf successful

    printf( "%x", value);
    return 0;
}

这是结果输出:

sscanf failed

【讨论】:

    猜你喜欢
    • 2020-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 2019-05-28
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    相关资源
    最近更新 更多