在这个问题的开头,我应该说我是一个从事我的第一个C++应用程序的Java程序员,所以可能有一些我不知道的显而易见的事情。
有关这个问题的一些背景资料:
我们的应用程序将数据从存储在字符数组中的套接字中读取,该字符数组是一个固定长度的消息头,包含各种固定长度字段,即:
char[15] data;现场位置为0-5,6-7,8-10,11-13 (最后一个字符是分隔符).包装此标头的类提供了方便的函数来检索每个字段的值:
int ApiHeader::msg_size(void)
{
return std::atoi(std::string(data, 6).c_str());
}
int ApiHeader::msg_type(void)
{
return std::atoi(std::string(data,6,2).c_str());
}
int ApiHeader::msg_subtype(void)
{
return std::atoi(std::string(data,8,3).c_str());
}
int ApiHeader::seqno(void)
{
return std::atoi(std::string(data,11,3).c_str());
}我试图利用需要c-字符串的std::atoi,但我需要将字符数组“切片”到包含每个单独字段的子数组中,这是通过为每个字段从data数组中的位置构建一个字符串来实现的。
代码运行良好,但是一个正在做一些代码分析的用户指出,msg_subtype()函数(以及其他两个类似的函数)实际上是无意中创建了一个额外的string对象。
它们调用了这个构造函数:
basic_string(const basic_string& other,
size_type pos,
size_type count = std::basic_string::npos,
const Allocator& alloc = Allocator() );因此,代码首先构造一个新字符串,将char[]转换为string&,然后构造另一个调用string(string&, int, int)构造函数的字符串。
我重新设计了代码以提高效率:
int atoi(char* string, int start, int length)
{
double result = 0;
char* index = string + start*sizeof(char);
for(int i=length;i>0; i--)
{
result += (*index++ - '0') * pow((float) 10, (float) (i-1));
}
return (int) result;
}没有构造字符串,它只迭代指定的data数组的部分。问题是,这段代码要求无法检测用户是否传递了start和length的坏值。(我不太确定如果用户将长度传递到数组之外会发生什么情况。在我的单元测试中,我刚刚看到它得到了一个未初始化的值)。
怎样才能使这段代码更好地证明异常呢?
我的一些想法是:
*index不在有效范围内('0‘到'9'),则退出循环。Exception (它至少让用户知道出了什么问题)。处理这个问题的最好的C++方法是什么?或者,是否有一种完全不同的方法应该用于此功能?
发布于 2013-12-27 23:54:32
首先,有一个问题:为什么您关心正在创建一个额外的字符串?这个功能经常使用吗。如果没有,我认为没有必要改变。
但除此之外,尽管我不知道C++是否聪明,您的替换功能是否更高效呢?您正在重复调用pow,并使用浮点数执行整数工作。这里有一个更便宜的替代方案。它在成功时返回0,在失败时返回1(坏字符串),所需的数字在result中输出。注意,string是const。
int my_atoi(const char* string, int start, int length, long *result)
{
char copy[length+1];
memcpy(copy, string + start, length);
copy[length] = '\0';
char *end;
*result = strtol(copy, &end, 0);
return (*end != '\0');
}您还可以省略start参数并使用
my_atoi(string+start, length, &res);https://codereview.stackexchange.com/questions/38189
复制相似问题