字符串函数返回奇怪的值

Posted

技术标签:

【中文标题】字符串函数返回奇怪的值【英文标题】:String function returns strange value 【发布时间】:2018-10-08 14:54:14 【问题描述】:

我有一个函数返回一个字节的二进制表示:

std::string ToBinary(unsigned char &Num)

    char str[8];
    char Symb = 0;
    int i = 0;
    while (i<8)
    
        _asm
        
            //push al
            shr byte[Num], 1
            mov al, 0
            adc al, 30h
            mov byte[Symb], al
            //pop al
        
        str[7-i] = Symb;
        i++;
    
    return std::string(str);

它的调用:

std::string BinOut = ToBinary(ByteValue);

问题在于,它返回的不是 8 字符字符串,而是 14 字符字符串。显然,函数 str 内部显示了正确的值。如何让它返回 8 个字符?

【问题讨论】:

阅读ericlippert.com/2014/03/05/how-to-debug-small-programs 了解调试代码的技巧。 return std::string(str, 8); 参见 (4) in: en.cppreference.com/w/cpp/string/basic_string/basic_string 不需要 NULL 终止并允许嵌入 NULL。 str 不是空终止的,所以你有 UB Silly mistake: forgot about null terminator 这是一个答案吗?如果是这样,请不要将其放入您的问题。相反,如果您对答案感到满意,请对一些说明错误并接受它的答案进行投票。 【参考方案1】:

std::string 的构造函数接受指向char 的指针,要求指向的字符串以空值结尾。您的 str 不是以 null 结尾的,因此程序的行为是未定义的。

你可以

使用char[9] 并将最后一个字符设置为'\0'。这仅在 str 不包含任何零字节时才有效,因为第一个字节将是终止符。 或者使用没有这个要求的构造函数std::string(char *s, std::size_t count)

【讨论】:

也可以保留char str[8];,然后使用return std::begin(str), std::end(str);列出初始化返回的字符串。【参考方案2】:

问题是因为您的字符数组不包含终止空字符。一种解决方案是分配一个带有一个额外字符的数组,以便您可以用 null 终止它:

char str[9]
//...
str[8] = '\0'

或者,您可以使用重载的字符串构造函数,该构造函数允许您从输入数组中传入要使用的字符数的参数:

std::string(str, 8);

【讨论】:

这太过分了。只需使用另一个重载std::string。在一般情况下它也不会正常工作(序列中会有空字节!) @SergeyA 是的,我假设前面的代码正确构建了 8 个非空字符的数组。

以上是关于字符串函数返回奇怪的值的主要内容,如果未能解决你的问题,请参考以下文章

DB2常用函数详解:字符串函数

strcmp函数怎么用的?

C语言getenv()函数的用法?(获取系统某个环境变量字符串名的值)

奇怪的 PHP 错误:'不能在写上下文中使用函数返回值'

PB中取字符串子串的函数是啥

PB中取字符串子串的函数是啥