1

我编写了多个简单的C++函数来将字节序列转换为字符串表示。

这是非常直接的,我确信我的逻辑是正确的,我认为这非常容易,直到我开始打印字符串,我发现输出是垃圾:

#包括<iostream>#包括<string>#包含<矢量>使用std::vector;typedef向量<uint8_t>字节;使用std::string;使用std::cout;使用命名空间std::literals;string DIGITS=“0123456789abcdef”s;静态内联字符串十六进制(字节arr){字符串repr=“”s;for(auto-chr:arr){repr+=“”+数字[(chr&240)>>4]+数字[chr&15];}报告擦除(0,1);退货代表;}字节文本={84, 111, 32, 98, 101, 32,111, 114, 32, 110, 111, 116,32, 116, 111, 32, 98, 101};//生存还是毁灭整型main(){cout<<十六进制(文本);}
2÷82÷82÷82÷

为什么会发生这种情况?

我知道我的逻辑是正确的,下面是直接翻译到Python的:

数字=“0123456789abcdef”定义字节字符串(数据):s=“”对于数据中的i:s+=“”+数字[(i&240)>>4]+数字[i&15]返回s[1:]

它的工作原理是:

>>>bytes_string(b“生存还是毁灭”)“第54页,共62页”

但为什么它在C++中不起作用呢?

我使用的是Visual Studio 2022 V17.9.7,编译器标志:

/permissive-/ifcOutput“hexlif_test\x64\Release\”/GS/GL/W3/Gy/Zc:wchar_t/Zi/Gm-/O2/sdl/Fd“hexLif_test\ x64\ Release\vc143.pdb”/Zc:inline/fp:precise/D“NDEBUG”/D“_CONSOLE”/D”_UNICODE“/D”UNICODE“/error报告:prompt/WX-/Zc:forScope/std:c17/Gd/Oi/MD/std:c+20/FC/Fa“hexlifytest\x64\释放”/EHsc/nologo/Fo“hexlifytest\x64\Release\”/Ot/Fp“hexLif_test\x46\Release \hexlife_test.pch”/diagnostics:column

我刚刚发现垃圾输出只发生在执行修复程序后的Debug模式下,我以调试模式下的C++20为目标,不知怎么的,代码导致了Debug方式下的垃圾输出,切换到发布模式解决了这个问题。在修复程序实现之前,我在发布模式下进行了编译,但出现了这个问题。

6
  • 2
    什么是调试器?. 评论 5月23日11:35
  • 以下是Python的直接翻译:--C++不是python。在编写C++时使用python(或任何其他语言)作为模型将导致1)程序错误,2)程序效率低下,3)程序在C++程序员看来很奇怪。典型案例:repr+=“”+数字[(chr&240)>>4]+数字[chr&15];--您希望这行C++代码做什么?你在期待吗+进行串联? 评论 5月23日11:42
  • 2
    一些编译器会警告您wandbox.org/permlink/4o56Uv8t5HUALExE网站 评论 5月23日11:45
  • 问题没有解决--无法复制即使这样,如果打印空格,代码也会更有效最后的,不是第一个。然后在循环的末尾报告pop_back()删除末尾的多余空间。打电话擦除由于整个字符串必须“左移”一个空格,因此第一个元素的效率很低。 评论 5月23日11:58
  • 也许您没有重新构建应用程序,而是运行了相同的错误版本? 评论 5月23日12:04

2个答案2

重置为默认值
4

如评论中所述(同时在这里),这里的问题是在字符串连接处或附近。以下代码不进行串联:

“”+数字[(chr&240)>>4]

从字符串中提取字符时DIGTS公司,它有类型烧焦-用于单个字符的专用类型。出于历史原因(与C兼容)+运算符解释字符串文字" "作为指针和数字字符作为整数,并做一些无用的指针运算。

要进行串联,请使用类型为的字符串文字标准::字符串,就像您在代码中的其他地方所做的那样:

“”s+数字[(chr&240)>>4]

在这里,操作员+遇到正确的类型标准::字符串烧焦,所以它工作正常。


C++中进行字符串连接的适当习惯用法是字符串流。

#包括<sstream>...std::ostingstream流;//“输出字符串流”流<<“”<<DIGITS[…]<<DIGETS[…];...return stream.str();

这个串流类针对字符串的增量构建进行了优化。代码完成所有连接后,它将流转换为常规流标准::字符串类型,这是通用的。

0

除了公认的答案外,还可以使用您的逻辑,但语法不是Pythonic。一个字节总是两个十六进制数字,所以知道原始字符串的长度,就知道结果的长度。wwway最好是预先分配,而不是将单个字符输出到流或串联字符串中,然后将字符串用作数组,并与之对齐:

std::string hexify(常量字节&buf){std::字符串结果;自动长度=buf.size()*2;result.resize(长度);对于(int i=0,j=0;i<长度;i++,j++){自动c=buf[i];结果[j++]=(c&0xF)[“0123456789abcdef”];结果[j]=(c>>4)[“0123456789abcdef”];}返回结果;}

数学有一些不好的假设,可以进行优化,但很容易看出母语中的“最佳实践”与预分配所有内容并为您完成所有“肮脏”工作的解释器有何不同。

第页。(c&0xF)[“0123456789abcdef”]与相同“0123456789abcdef”[c&0xF]但有些编译器更经常在括号内发现常量。

不是你想要的答案吗?浏览标记的其他问题问自己的问题.