将C ++字符串操作转换为C

时间:2016-09-08 04:29:36

标签: c++ c string

所以我的程序的一小部分正在进行基本转换。在这种情况下,从字节缓冲区(基数256)到基数58。

我正在尝试将此部分转换为C,因此当我需要编写其他实现时,我可以重用相同的代码。

从最初的C ++:

static unsigned int divide_58(string& x)  {
    const size_t length = x.length();
    size_t pos = 0;
    char *quotient = new char[length];

    for (size_t i = 0; i < length; ++i) {
        const size_t j = i + 1 + x.length() - length;
        if (x.length() < j)
            break;

        const unsigned int value = base2dec(x.c_str(), j);  //defined elsewhere; consistent in both

        quotient[pos] = (unsigned char)(value / 58);
        if (pos != 0 || quotient[pos] != ascii[0])
            pos++;

        size_t len = 4;
        char *temp_str = dec2base(value % 58, len);  //defined elsewhere; consistent in both
        x.replace(0, j, temp_str, len);  //Replace the contents at 0 thru j with the whole contents of temp_str, moving things appropriately
        free(temp_str);
    }

    // calculate remainder
    const unsigned int remainder = base2dec(x.c_str(), x.length());  //defined elsewhere; consistent in both

    // remove leading "zeros" from quotient and store in 'x'
    x.assign(quotient, quotient + pos);

    return remainder;
}

我把它翻译成C的下一位:

static unsigned int divide_58(char *x, size_t &length)  {
    const size_t const_length = length;
    size_t pos = 0;
    char *quotient = (char*) malloc(sizeof(char) * const_length);

    for (size_t i = 0; i < const_length; ++i) {
        const size_t j = i + 1 + length - const_length;
        if (length < j)
            break;

        const unsigned int value = base2dec(x, j);  //defined elsewhere; consistent in both

        quotient[pos] = (unsigned char)(value / 58);
        if (pos != 0 || quotient[pos] != ascii[0])
            pos++;

        size_t len = 4;
        char *temp_str = dec2base(value % 58, len);  //defined elsewhere; consistent in both
        memcpy(x, temp_str, len);
        free(temp_str);

        memmove(x + len, x + j, length - j);
        length -= j;
        length += len;
    }

    // calculate remainder
    const unsigned int remainder = base2dec(x, length);  //defined elsewhere; consistent in both

    // remove leading "zeros" from quotient and store in 'x'
    memcpy(x, quotient, pos);
    free(quotient);
    length = pos;

    return remainder;
}

这几乎适用于所有情况,但是在我的Linux测试环境(并且没有我的本地机器)上,尽管同意输入是正确的,但它会产生错误的答案。

失败示例:https://app.shippable.com/runs/57cf7ae56f908e0e00c5e451/1/console(build_ci - &gt; make cpytest cov = true)

工作示例:https://travis-ci.org/gappleto97/p2p-project/jobs/158036360#L392

我知道标准是提供问题的最简短的例子,但尽管我可以告诉这个最短的例子。你们都可以帮帮我吗?

对于MCVE人员,您可以通过我的git repo自行验证。

git clone https://github.com/gappleto97/p2p-project
cd p2p-project
git checkout develop
make cpytest
git checkout c_issue
rm -r build
make cpytest

第一次调用make将会有失败的测试。第二个不会。第二个是使用这里提供的C ++代码,第一个是使用这里提供的C代码。为了便于测试,它已被提升到Python,但我已将其缩小到这个功能。这可能是无用的,因为我只能复制Shippable上的错误。

1 个答案:

答案 0 :(得分:1)

您已翻译此C ++行:

    x.replace(0, j, temp_str, len);

进入这个C代码:

    memcpy(x, temp_str, len);
    memmove(x + len, x + j, length - j);
    length -= j;
    length += len;

这不是等效的代码。

有一件事是你永远不会向x添加零终止。

另一件事是,当j小于4时,代码会产生完全不同的字符串。

看看这个C ++代码:

#include <iostream>
#include <string>
#include <string.h>
using namespace std;

int main() {
    string s = "abcdefgh";
    char t[10] = "01234567";
    cout << "Original: " << s << endl;

    int j = 2;

    // The c++ way
    s.replace(0, j, t, 4);
    cout << "C++: " << s << endl;

    // Your C way
    char x[10] = "abcdefgh";
    size_t length = strlen(x);
    memcpy(x, t, 4);
    memmove(x + 4, x + j, length - j);
    cout << "C  : " << x << endl;

    return 0;
}
  

输出:

     

原文:abcdefgh

     

C ++:0123cdefgh

     

C:012323efgh

j = 6相同的代码:

  

输出:

     

原文:abcdefgh

     

C ++:0123gh

     

C:0123ghgh

结论您的C ++替换C代码无效。