将 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。dec2base
和 base2dec
不在那里。代码不是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*