旧编译器的基于范围的循环到旧样式
Ranged based loop to old style for old compilers
最近我在尝试使用此代码从字符串生成 MD5。
string SecureInfrastructure::Generate_MD5_FromString(const string &data)
{
unsigned char result[MD5_DIGEST_LENGTH];
MD5((unsigned char*)data.c_str(), data.size(), result);
std::ostringstream sout;
sout<<std::hex<<std::setfill('0');
for(long long c: result)
{
sout<<std::setw(2)<<(long long)c;
}
return sout.str();
}
但是,我使用的编译器不支持基于范围的 for 循环,我尝试使用下面的代码将此代码转换为传统的 for(...;...;...)
循环。
string SecureInfrastructure::Generate_MD5_FromString(const string &data)
{
unsigned char result[MD5_DIGEST_LENGTH];
MD5((unsigned char*)data.c_str(), data.size(), result);
std::ostringstream sout;
sout<<std::hex<<std::setfill('0');
for(long long c; c<sizeof(result); c++) // long long c: result
{
sout<<std::setw(2)<<(long long)c;
}
return sout.str();
}
什么时候,我测试它不起作用,因为我得到一个空字符串。我很难找到错误所在。我应该如何用传统的for循环重新实现第一段代码?
这里使用c
未初始化,开始单步执行。这会导致未定义的行为:
for(long long c; c<sizeof(result); c++)
应该这样做:
for(size_t i = 0; i < MD5_DIGEST_LENGTH; ++i) {
sout << std::setw(2) << (unsigned) result[i];
}
当你有
for(long long c: result)
{
sout<<std::setw(2)<<(long long)c;
}
for(long long c: result)
说:对于 result
中的每个元素,将其分配给名为 c
的类型 long long
的变量。然后循环体使用 c
。要在常规 for 循环中获得相同的行为,您需要做相同的事情。告诉编译器遍历你需要的所有元素
for(size_t i = 0; i < MD5_DIGEST_LENGTH; i++)
您可以直接在循环中使用该元素,而不是创建变量。那看起来像
sout<<std::setw(2)<<(long long)result[index_of_element];
将它们结合起来得到
for(size_t i = 0; i < MD5_DIGEST_LENGTH; i++)
{
sout<<std::setw(2)<<(long long)result[i];
}
问题是你没有初始化 c 并且你也没有在任何地方引用结果数组
for(long long c = 0; /*Initialize*/ c<sizeof(result); c++) // long long c: result
{
//use result[c]
}
使用 MD5_DIGEST_LENGTH
而不是 sizeof(result)
。而且 "c" 我认为没有初始值 0。
最近我在尝试使用此代码从字符串生成 MD5。
string SecureInfrastructure::Generate_MD5_FromString(const string &data)
{
unsigned char result[MD5_DIGEST_LENGTH];
MD5((unsigned char*)data.c_str(), data.size(), result);
std::ostringstream sout;
sout<<std::hex<<std::setfill('0');
for(long long c: result)
{
sout<<std::setw(2)<<(long long)c;
}
return sout.str();
}
但是,我使用的编译器不支持基于范围的 for 循环,我尝试使用下面的代码将此代码转换为传统的 for(...;...;...)
循环。
string SecureInfrastructure::Generate_MD5_FromString(const string &data)
{
unsigned char result[MD5_DIGEST_LENGTH];
MD5((unsigned char*)data.c_str(), data.size(), result);
std::ostringstream sout;
sout<<std::hex<<std::setfill('0');
for(long long c; c<sizeof(result); c++) // long long c: result
{
sout<<std::setw(2)<<(long long)c;
}
return sout.str();
}
什么时候,我测试它不起作用,因为我得到一个空字符串。我很难找到错误所在。我应该如何用传统的for循环重新实现第一段代码?
这里使用c
未初始化,开始单步执行。这会导致未定义的行为:
for(long long c; c<sizeof(result); c++)
应该这样做:
for(size_t i = 0; i < MD5_DIGEST_LENGTH; ++i) {
sout << std::setw(2) << (unsigned) result[i];
}
当你有
for(long long c: result)
{
sout<<std::setw(2)<<(long long)c;
}
for(long long c: result)
说:对于 result
中的每个元素,将其分配给名为 c
的类型 long long
的变量。然后循环体使用 c
。要在常规 for 循环中获得相同的行为,您需要做相同的事情。告诉编译器遍历你需要的所有元素
for(size_t i = 0; i < MD5_DIGEST_LENGTH; i++)
您可以直接在循环中使用该元素,而不是创建变量。那看起来像
sout<<std::setw(2)<<(long long)result[index_of_element];
将它们结合起来得到
for(size_t i = 0; i < MD5_DIGEST_LENGTH; i++)
{
sout<<std::setw(2)<<(long long)result[i];
}
问题是你没有初始化 c 并且你也没有在任何地方引用结果数组
for(long long c = 0; /*Initialize*/ c<sizeof(result); c++) // long long c: result
{
//use result[c]
}
使用 MD5_DIGEST_LENGTH
而不是 sizeof(result)
。而且 "c" 我认为没有初始值 0。