2011-01-29 37 views
0

我的编程历史记录是C和CPython。请在这里忍受我。使用带有矢量的静态字符串

为了帮助我学习C++,我将其中一个旧的C程序转换为使用C++ OOP,但它并不按照我希望的方式工作。我不在乎速度。我只关心学习。

这里是我的旧的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++“安永代码:

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,我决定使用上面的矢量容器而不是字符串类,因为我想在这里使用二进制数据。

DESIRED RESULT:如何将字符串和二进制数据传递给此方法来计算其校验和?我是否需要重载它或者在主类型中声明字符串?我完全失去了。

回答

3

你可以使用std::copy复制char阵列的内容到载体中:

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

...和也许覆盖校验:: UpdateStream,它需要一个字符数组,将其转换为一个std ::矢量和与调用校验:: UpdateStream(标准::矢量<无符号字符> binaryData)。 – thbusch 2011-01-29 17:04:25

+0

我刚刚提出这个建议。 +1。 – 2011-01-29 17:04:31

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

你的校验类的交易,可以来自任何地方,让基本接口不应该强加转换为例如std::vector

I.e.原始C代码的形式参数类型是并且很好。

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

如果你绝对想拥有一个std::vector作为正式参数类型为根本功能,那么您可以按如下复制一个字符串给它:

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

干杯&心连心,

0

在C++中一个字符串在这方面将衰减到一个字符指针到第一炭和没有隐式构造使得一个向量出了字符指针的。还unsigned charchar是不同的类型和同时有隐式转换规则在它们之间有一个指向unsigned char和字符指针之间没有转换规则。

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

此外,如果在C++中犯了错误,则可以轻松获得UB守护进程而不是运行时错误天使,并且您会明白实验仅仅是C++的错误路径。无论有多聪明,都无法通过逻辑推理来推断历史。必须研究历史。

帮你一个忙,抓住“C++编程语言”并阅读其封面:对于具有强大C背景的人来说,一旦你把它们放在一个容易理解的地方框架和背景。其他很多我喜欢的书籍,包括国际海事组织也很容易阅读的是马歇尔克莱恩的“C++常见问题解答”和斯科特迈耶斯的“有效”系列。

C++是一个很好的语言,但很容易成为你的噩梦,如果你从错误的侧面接近它。