整数到字符串的转换问题
Integer to string conversion issues
我在使用Crypto++的Integer
类时遇到了一些问题。我使用的是最新版本 5.6.2。
我正在尝试使用以下代码将整数转换为字符串:
CryptoPP::Integer i("12345678900987654321");
std::ostrstream oss;
oss << i;
std::string s(oss.str());
LOGDEBUG(oss.str()); // Pumps log to console and log file
输出似乎有额外的垃圾数据:
12345678900987654321.ÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««îþîþ
当我直接输出到控制台时,我得到同样的事情:
std::cout << "Dec: " << i << std::endl; // Same result
此外,我无法获得精度或科学记数法。以下内容将输出相同的结果:
std::cout.precision(5); // Does nothing with CryptoPP::Integer
std::cout << "Dec: " << std::setprecision(1) << std::dec << i << std::endl;
std::cout << "Sci: " << std::setprecision(5) << std::scientific << i << std::endl;
最重要的是,足够大的数字打破了整个事情。
CryptoPP::Integer i("12345");
// Calculate i^16
for (int x = 0; x < 16; x++)
{
i *= i;
}
std::cout << i << std::endl; // Will never finish
最终,我试图得到一些可以处理大Integer
数字的东西,并且可以以科学记数法输出字符串。我在提取Integer
库或根据需要对其进行修改方面没有问题,但我更喜欢使用稳定的代码。
我做错了什么,还是有办法让它正常工作?
我正在尝试使用以下代码将整数转换为字符串:
CryptoPP::Integer i("12345678900987654321"); std::ostrstream oss; oss << i; std::string s(oss.str()); LOGDEBUG(oss.str()); // Pumps log to console and log file
输出似乎有额外的垃圾数据:
12345678900987654321.ÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««îþîþ
我无法在Visual Studio 2010上使用Crypto++ 5.6.2重现这一点。损坏的输出可能是其他问题的结果,而不是 Crypto++ 中的错误。如果您还没有这样做,我建议您尝试仅使用CryptoPP::Integer
和std::cout
在最小的程序中重现它,而不是其他应用程序代码,以消除所有其他可能的问题。如果它不能在微不足道的独立测试中工作(这会令人惊讶),则库的构建方式可能存在问题(例如,它可能使用与您的应用程序使用的不同C++运行时或编译器版本构建)。如果你的独立测试通过,你可以添加其他字符串操作、日志记录代码等,直到找到罪魁祸首。
我确实注意到您正在使用已弃用std::ostrstream
。您可能希望改用std::ostringstream
。这个堆栈溢出对"为什么 std::strstream 被弃用?"这个问题的回答可能会很有趣,甚至可能是该答案中提到的问题导致了你的问题。
此外,我无法获得精度或科学记数法。 以下内容将输出相同的结果:
std::cout.precision(5); // Does nothing with CryptoPP::Integer std::cout << "Dec: " << std::setprecision(1) << std::dec << i << std::endl; std::cout << "Sci: " << std::setprecision(5) << std::scientific << i << std::endl;
std::setprecision
和std::scientific
修改浮点输入/输出。因此,对于int
或long long
等C++常规整数类型,这也行不通(但我可以看到,特别是对于像CryptoPP:Integer
这样的任意长度整数,能够以指定的精度以科学记数法输出是有意义的)。
即使C++没有这样定义它,Crypto++的实现仍然需要注意这些标志。通过查看std::ostream& operator<<(std::ostream& out, const Integer &a)
的 Crypto++ 实现,我可以看到它识别的唯一 iostream 标志是std::ios::oct
和std::ios::hex
(分别用于八进制和十六进制格式的数字)。
如果你想要科学记数法,你必须自己格式化输出(或使用不同的库)。
最重要的是,足够大的数字打破了整个 东西。
CryptoPP::Integer i("12345"); // Calculate i^16 for (int x = 0; x < 16; x++) { i *= i; } std::cout << i << std::endl; // Will never finish
这实际上将计算i^(2^16) = i^65536
,而不是i^16
,因为在每个循环中,您将i
乘以其新的中间值,而不是其原始值。这段代码的实际结果将是 268,140 位长,所以我预计 Crypto++ 需要很长时间才能产生该输出。
以下是为产生正确结果而调整的代码:
CryptoPP::Integer i("12345");
CryptoPP::Integer i_to_16(1);
// Calculate i^16
for (int x = 0; x < 16; x++)
{
i_to_16 *= i;
}
std::cout << i_to_16 << std::endl;
LOGDEBUG(oss.str()); // Pumps log to console and log file
输出似乎有额外的垃圾数据:
12345678900987654321.ÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««îþîþ
我怀疑你呈现的内容与你在现实生活中所做的略有简化。我相信这个问题与LOGDEBUG
和ostringstream
有关。我相信你输出的是char*
的,而不是string
的(尽管我们还没有看到你的记录器的代码)。
从oss.str()
返回的std::string
是暂时的。所以这个:
LOGDEBUG(oss.str());
与此略有不同:
string t(oss.str());
LOGDEBUG(t);
当您打算使用它时,您应该始终在ostringstream
中复制string
。或者确保用法包含在一个语句中。
我发现的最好的方法是拥有:
// Note: reference, and the char* is used in one statement
void LOGDEBUG(const ostringstream& oss) {
cout << oss.str().c_str() << endl;
}
或
// Note: copy of the string below
void LOGDEBUG(string str) {
cout << str.c_str() << endl;
}
你甚至不能这样做(这个在生产中咬了我):
const char* msg = oss.str().c_str();
cout << msg << endl;
您无法这样做,因为从oss.str()
返回的string
是临时的。因此,语句执行后char*
是垃圾。
解决方法如下:
const string t(oss.str());
const char* msg = t.c_str();
cout << msg << endl;
如果您在程序上运行Valgrind,那么您可能会得到与您使用ostringstream
和strings
相关的看似无法解释的发现。
下面是一个类似的日志记录问题:字符串流临时 ostream 返回问题。另请参阅在单个语句中将临时字符串流转换为 c_str()。这是我遇到的一个:std:ostringstream 和 -std=c++11 的内存错误?
正如 Matt 在下面的评论中指出的那样,您应该使用ostringstream
,而不是ostrstream
。 自 C++98 年以来,ostrstream
已被弃用,您在使用它时应该会收到警告。
所以改用这个:
#include <sstream>
...
std::ostringstream oss;
...
但我相信问题的根源在于您在LOGDEBUG
函数或宏中使用std::string
的方式。
您与 Integer 相关的其他问题已在 Softwariness 的回答和相关评论中处理。所以我不会再重复它们了。
- 模板类转换问题 - 无法推断调用的函数
- 复制构造函数隐式转换问题
- 与模板 (c++) 相关的转换问题
- 将文件复制到自定义位置,存在字符串转换问题
- 从基指针到派生的强制转换问题
- JNI 日期值转换问题,在C++中获取不同的长整型值
- 类型转换问题
- 拆分 pybind11 模块和自动类型转换问题
- 类型转换问题:返回为整数而不是浮点/类型
- 如何解决ostream_iterator转换问题?
- C++转换问题
- 代码 c++ VS 2010 中的 LPCWSTR 到字符串转换问题
- 罗马数字C++编程转换问题
- C++十进制到时间的转换问题
- C++到 C 的转换问题
- C 复合分配和类型转换问题
- CPP预处理器到C预处理器转换问题
- 将数据类型从C#封送至C++的类型转换问题
- COM对象,并返回QVariant强制转换问题
- C 汇编器转换问题