使用带向量的静态字符串

时间:2011-01-29 16:54:46

标签: c++ string vector

我的编程历史是在C和CPython中。请在这里忍受我。

为了帮助我学习C ++,我正在将一个旧的C程序转换为使用C ++ OOP,但它并没有像我希望的那样工作。我不关心速度。我只关心学习。

这是我想要放入Checksum类的旧C代码:

    //This is the standard CRC32 implementation
    //"rollingChecksum" is used so the caller can maintain the current 
    //checksum between function calls
    unsigned int CalculateChecksum(unsigned char* eachBlock, int* sbox, long lengthOfBlock, unsigned int rollingChecksum)
    {
       int IndexLookup;
       int blockPos;

       for(blockPos = 0; blockPos < lengthOfBlock; blockPos++)
       {
         IndexLookup = (rollingChecksum >> 0x18) ^ eachBlock[blockPos];
         rollingChecksum = (rollingChecksum << 0x08) ^ sbox[IndexLookup];
       }
       return rollingChecksum;
    }

所以这就是我将它翻译成更多C ++'ey代码的方式:

 void Checksum::UpdateStream(std::vector<unsigned char> binaryData)
 {
   unsigned int indexLookup;
   unsigned int blockPos;

   for(blockPos = 0; blockPos < binaryData.size(); blockPos++)
   {
      indexLookup = (this->checksum >> 0x18) ^ binaryData[blockPos];
      this->checksum = (this->checksum << 0x08) ^ this->sbox[indexLookup];
   }
 }

但是当我尝试使用它时:

int main(int argc, char* argv[])
{
 Checksum Test;
 Test.UpdateStream("foo bar foobar");
 std::cout << Test.getChecksum() << std::endl;
}

我收到此错误:

1>main.cpp(7) : error C2664: 'Checksum::UpdateStream' : cannot convert parameter 1 from 'const char [15]' to 'std::vector<_Ty>'
1>        with
1>        [
1>            _Ty=unsigned char
1>        ]
1>        No constructor could take the source type, or constructor overload resolution was ambiguous

由于how this question turned out on StackOverflow我决定使用上面的向量容器而不是字符串类,因为我想在这里使用二进制数据。

渴望的结果:如何将字符串和二进制数据传递给此方法来计算其校验和?我需要重载它还是在main中对字符串进行类型转换?我完全迷失了。

4 个答案:

答案 0 :(得分:3)

您可以使用charstd::copy数组内容复制到矢量中:

std::vector< char > vector;
char str[] = "foo bar foobar";
vector.resize( sizeof(str)-1 ); // thanks to Alf (see comments)
std::copy( str, str+sizeof(str)-1, vector.begin() );

甚至更好地使用std::vector构造函数:

char str[] = "foo bar foobar";
std::vector< char > vector( str, str+sizeof(str)-1 );

请注意,此代码将复制整个字符串终止\0(再次,请参阅注释以获取更多详细信息)。

答案 1 :(得分:1)

您的校验和类处理来自任何地方的原始字节数据,因此基本接口不应强制转换为例如std::vector

即。原始C代码的unsigned char const*形式参数类型是正常的。

但是,您可以为常见的调用者类型提供更高级别的包装,例如字符串文字,std::vector,您可以为其命名。

如果你绝对想要std::vector作为基本函数的形式参数类型,那么你可以按如下方式将字符串文字复制到它:

char const  s[] = "blah blah";
std::vector<unsigned char> const v( s, s + strlen( s ) );

干杯&amp;第h。,

答案 2 :(得分:0)

您无法使用字符串文字创建向量。好吧,至少不是直接的。这应该有效:

std::string tmp = "foo bar foobar"
Test.UpdateStream(std::vector<unsigned char>(tmp.begin(), tmp.end()));

您还可以更新UpdateStream签名以使用(const std::vector<unsigned char>& binaryData)来避免复制,因为您无需修改​​它。

要缩短代码,可以为字符串提供UpdateStream的重载:

void Checksum::UpdateStream(const std::string& str) {
    UpdateStream(std::vector<unsigned char>(str.begin(), str.end()));
}

答案 3 :(得分:0)

在C ++中,该上下文中的字符串文字将衰减为指向第一个char的char指针,并且没有隐式构造函数从char指针中生成向量。 unsigned charchar也是不同的类型,虽然它们之间存在隐式转换规则,但在指向unsigned char的指针和指向char的指针之间没有转换规则。

我的建议不是尝试通过实验来学习C ++,因为C ++是一种具有长期演变历史的复杂语言......它由许多不同的思想甚至正式委员会设计。在许多地方,C ++远非直觉或逻辑,因为有些规则是进化,委员会效应或与现在不再存在的事物的向后兼容的结果。

除此之外,当你在C ++中犯错时,你很容易得到UB守护进程而不是运行时错误天使,你会明白实验只是错误的C ++路径。无论有多聪明,都无法用逻辑推理来推断历史。必须研究历史。

帮自己一个忙,抓住“C ++编程语言”并将其翻译成封面:一旦你把它们放在一个框架中,有很多东西对于那些具有强大C背景的人来说很容易理解和背景。我非常喜欢的其他书籍,IMO也很容易阅读,是Marshall Cline的“C ++ FAQs”和Scott Meyers的“Effective”系列。

C ++是一门很好的语言,但如果从错误的角度来看,它很容易成为你最糟糕的噩梦。