我正在尝试在定义的位置添加字符。我创建了一个新函数,为另一个char分配了一个内存,在该位置之后保存了字符,然后在定义的位置添加了我的字符,现在我不知道如何在该位置之后删除字符以连接已保存的字符串。有解决办法吗?
这是我功能的开始:
void appendCharact(char *source, char carac, int position) {
source = realloc(source, strlen(source) * sizeof(char) + 1); //Get enough memory
char *temp = source.substr(position); //Save characters after my position
source[position] = carac; //Add the character
}
编辑: 我正在尝试实现另一种“野蛮”的解决方案,在调试模式下,我可以看到我的新字符串差不多,但是看起来我无法擦除旧的指针...
void appendCharact(char *source, char carac, int position) {
char *temp = (char *)malloc((strlen(source) + 2) * sizeof(char));
int i;
for(i = 0; i < position; i++) {
temp[i] = source[i];
}
temp[position] = carac;
for (i = position; i < strlen(source); i++) {
temp[i + 1] = source[i];
}
temp[strlen(temp) + 1] = '\0';
free(source);
source = temp;
}
答案 0 :(得分:5)
我提到我可以看到所示代码的五个问题(此处已复制以供参考)
void appendCharact(char * source, char carac , int position)
{
source = realloc(source, strlen(source) * sizeof(char) + 1); //Get enough memory
char * temp = source.substr(position); //Save characters after my position
source[position] = carac; //Add the charactere
}
问题是(没有特定的顺序):
strlen(source) * sizeof(char) + 1
等于(strlen(source) * sizeof(char)) + 1
。应该是(strlen(source) + 1) * sizeof(char)
。但是,这很好用,因为sizeof(char)
在C ++规范中定义为始终等于1
。
与以上内容相关:简单的char
字符串实际上称为 以空值结尾的 字节字符串。因此,它们必须以“空”字符('\0'
)结尾。这个空字符当然需要分配的字符串中有空格,并且strlen
not 不会计数。因此,要添加一个字符,您需要分配strlen(source) + 2
个字符。
请不要分配回传递给realloc
的指针。如果realloc
失败,它将返回空指针,使您失去原始内存,这是内存泄漏。
realloc
函数的返回类型为void*
。在C ++中,您需要将其强制转换为正确的指针类型以进行赋值。
您通过 value 传递source
,这意味着在函数内部您具有指针的本地副本。当您分配给source
时,您仅分配给本地副本,则不会修改调用中使用的原始指针。
以下是该代码的其他一些问题,或者它的可能用途:
关于空终止符,一旦为其分配了足够的内存,还需要将其添加到字符串中。
如果使用source
作为文字字符串或数组或先前调用malloc
,calloc
或{{ 1}},则无法将该指针传递给realloc
。
您无法使用realloc
,因为source.substr(position)
不是对象,因此没有成员函数。
答案 1 :(得分:1)
int pos = 1;
char toInsert = '-';
std::string text = "hallo";
std::stringstream buffer;
buffer << text.substr(0,pos);
buffer << toInsert;
buffer << text.substr(pos);
text = buffer.str();
答案 2 :(得分:1)
尝试使用类似的东西:
#include <string>
void appendCharAt(std::string& src, char c , int pos)
{
std::string front(src.begin(), src.begin() + pos - 1 ); // use iterators
std::string back(src.begin() + pos, src.end() );
src = front + c + back; // concat together +-operator is overloaded for strings
}
不是100%确定位置正确。也许前面不必是src.begin()+ pos,而后面是src.begin()+ pos +1。只需尝试一下即可。
答案 3 :(得分:1)
此版本的C版本必须处理重新分配失败的情况,在这种情况下,原始字符串将保留。成功后,只应使用从realloc返回的指针覆盖旧指针。
它可能看起来像这样:
view.addSubview(networkStatusView)
UIView.animate(withDuration: 0.5) {
networkStatusView.frame.size.height = 50
view.layoutIfNeeded()
}
用法:
bool append_ch (char** str, char ch, size_t pos)
{
size_t prev_size = strlen(*str) + 1;
char* tmp = realloc(*str, prev_size+1);
if(tmp == NULL)
{
return false;
}
memmove(&tmp[pos+1], &tmp[pos], prev_size-pos);
tmp[pos] = ch;
*str = tmp;
return true;
}
答案 4 :(得分:1)
您的新解决方案更接近工作功能,但仍然存在一些问题:
<?php $args = array(
'post_type' => 'membercontent',
'meta_query' => array(
array(
'key' => 'tt_freemium',
'value' => 'true',
),
'orderby' => 'post_date',
'order' => 'DESC',
'posts_per_page' => '200' );
$ourposts = new WP_Query( $args );?>
是否失败。malloc()
是不正确的,因为temp[strlen(temp) + 1] = '\0';
还不是正确的C字符串,并且temp
仍然指向已分配的块之外,您应该只写strlen(temp) + 1
temp[i + 1] = '\0';
参数返回给调用方。这是更正的版本:
char **