【问题标题】:Issues translating C++ string manipulation to C [closed]将 C++ 字符串操作转换为 C 的问题 [关闭]
【发布时间】:2016-09-08 04:29:35
【问题描述】:

所以我的程序中有一小部分正在进行基本转换。在这种情况下,从字节缓冲区(基数 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 -> 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 上复制错误。

【问题讨论】:

  • 没有 MCVE。 dec2basebase2dec 不在那里。代码不是C,需要C++编译器编译。 memcpy 在缓冲区内复制。使用memmove
  • ^ 在没有 MCVE 的情况下非常正确
  • 您确实需要改进有关没有 MCVE 的问题。其中包括问题的详细信息,例如您在调试时发现的问题
  • char *quotient = new char[const_length]; - 那是 C 代码吗?进一步 - 这不是内存泄漏吗?
  • 真的执行一次 malloc 和 free length 次,而不是将缓冲区传递给 base2dec ????此外,我要提醒您,C 不是 C++ 的子集,它是一门独立的语言,自 30 多年前诞生 C++ 以来,它一直沿着自己的轨道发展。这会让人们失望。老实说,你写的不是 C,而是糟糕的 C++。如果代码质量对您很重要,我鼓励您使用 codereview.stackexchange.com 获得适当的转换帮助。

标签: c++ c string


【解决方案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 代码不起作用。

【讨论】:

  • 感谢您的帮助。我会尝试更好地翻译 string::replace。
猜你喜欢
  • 2021-05-05
  • 1970-01-01
  • 1970-01-01
  • 2014-03-15
  • 2016-07-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-19
  • 1970-01-01
相关资源
最近更新 更多