首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建一个函数,该函数需要char*防止异常

创建一个函数,该函数需要char*防止异常
EN

Code Review用户
提问于 2013-12-27 18:26:49
回答 1查看 340关注 0票数 3

在这个问题的开头,我应该说我是一个从事我的第一个C++应用程序的Java程序员,所以可能有一些我不知道的显而易见的事情。

有关这个问题的一些背景资料:

我们的应用程序将数据从存储在字符数组中的套接字中读取,该字符数组是一个固定长度的消息头,包含各种固定长度字段,即:

代码语言:javascript
复制
char[15] data;

现场位置为0-5,6-7,8-10,11-13 (最后一个字符是分隔符).包装此标头的类提供了方便的函数来检索每个字段的值:

代码语言:javascript
复制
    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对象。

它们调用了这个构造函数:

代码语言:javascript
复制
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)构造函数的字符串。

我重新设计了代码以提高效率:

代码语言:javascript
复制
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数组的部分。问题是,这段代码要求无法检测用户是否传递了startlength的坏值。(我不太确定如果用户将长度传递到数组之外会发生什么情况。在我的单元测试中,我刚刚看到它得到了一个未初始化的值)。

怎样才能使这段代码更好地证明异常呢?

我的一些想法是:

  • 如果*index不在有效范围内('0‘到'9'),则退出循环。
  • 和上面一样,除了抛出一个Exception (它至少让用户知道出了什么问题)。
  • 只需记录这个方法就可以告诉用户,如果值不好,行为就是“未定义的”(我已经看到一些方法是这样记录的)。

处理这个问题的最好的C++方法是什么?或者,是否有一种完全不同的方法应该用于此功能?

EN

回答 1

Code Review用户

回答已采纳

发布于 2013-12-27 23:54:32

首先,有一个问题:为什么您关心正在创建一个额外的字符串?这个功能经常使用吗。如果没有,我认为没有必要改变。

但除此之外,尽管我不知道C++是否聪明,您的替换功能是否更高效呢?您正在重复调用pow,并使用浮点数执行整数工作。这里有一个更便宜的替代方案。它在成功时返回0,在失败时返回1(坏字符串),所需的数字在result中输出。注意,stringconst

代码语言:javascript
复制
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参数并使用

代码语言:javascript
复制
my_atoi(string+start, length, &res);
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/38189

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档