c++loopsmd5ranged-loops

Ranged based loop to old style for old compilers


Recently I was trying to use this code to generate a MD5 from a String.

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();
}

However, the compiler that I am using does not support range based for loops and I tried to convert this code into the traditional for(...;...;...) loop with the code presented below.

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();
}

When, I tested it did not work because I am getting an empty string. I am having difficulties in find where the error is. How should I reimplement the first code with the traditional for-loop?


Solution

  • When you have

    for(long long c: result)
    {
        sout<<std::setw(2)<<(long long)c;
    }
    

    the for(long long c: result) says: for each element in result assign it to a variable of type long long named c. The body of the loop then uses c. To get that same behavior in a regular for loop you need to do the same thing. To tell the compiler to loop through all the elements you need

    for(size_t i = 0; i < MD5_DIGEST_LENGTH; i++)
    

    instead of creating a variable you can just use the element directly in the loop. That would look like

    sout<<std::setw(2)<<(long long)result[index_of_element];
    

    and combining that together you get

    for(size_t i = 0; i < MD5_DIGEST_LENGTH; i++)
    {
        sout<<std::setw(2)<<(long long)result[i];
    }