将 C++ 字符串操作转换为 C 的问题 [关闭]

Posted

技术标签:

【中文标题】将 C++ 字符串操作转换为 C 的问题 [关闭]【英文标题】:Issues translating C++ string manipulation to C [closed] 【发布时间】: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 获得适当的转换帮助。 【参考方案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。

以上是关于将 C++ 字符串操作转换为 C 的问题 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

c++ 不使用 C 标准库将字符串和 int 转换为 char*

将字符串转换为整数部分 C++ [关闭]

字符串函数不返回字符串? c++ [关闭]

将字符串转换为数学评估 [关闭]

使用 ostringstream 或 stringstream 将 C++ Int 转换为字符串

如何将 C++ sscanf_s() 函数转换为 C# [关闭]