我正在尝试从值为的字符arrary中删除第一个分号:
输入:
;测试:876033074,808989746,825766962,;测试1: 825766962,
代码:
char *cleaned = cleanResult(result);
printf("Returned BY CLEAN: %s\n",cleaned);
char *cleanResult(char *in)
{
printf("Cleaning this: %s\n",in);
char *firstOccur = strchr(in,';');
printf("CLEAN To Remove: %s\n",firstOccur);
char *restOfArray = firstOccur + 2;
printf("CLEAN To Remove: %s\n",restOfArray); //Correct Value Printed here
char *toRemove;
while ((toRemove = strstr(restOfArray + 2,", ;"))!=NULL)
{
printf("To Remove: %s\n",toRemove);
memmove (toRemove, toRemove + 2, strlen(toRemove + 2));
printf("Removed: %s\n",toRemove); //Correct Value Printed
}
return in;
}
输出(第一个分号仍在那里):
;测试:876033074, 808989746,825766962; Test1:825766962;
答案 0 :(得分:4)
关于sizeof(cleaned)
:使用sizeof
来获取数组的容量只有在参数是数组而不是指针时才有效:
char buffer[100];
const char *pointer = "something something dark side";
// Prints 100
printf("%zu\n", sizeof(buffer));
// Prints size of pointer itself, usually 4 or 8
printf("%zu\n", sizeof(pointer));
虽然本地数组和指针都可以下标,但它们在sizeof
时的行为却不同。因此,只有指向它的指针才能确定数组的容量。
另外,请记住:
void foo(char not_really_an_array[100])
{
// Prints size of pointer!
printf("%zu\n", sizeof(not_really_an_array));
// Compiles, since not_really_an_array is a regular pointer
not_really_an_array++;
}
虽然not_really_an_array
被声明为数组,但它是一个函数参数,所以实际上是一个指针。它完全相同:
void foo(char *not_really_an_array)
{
...
不太合乎逻辑,但我们坚持不懈。
关于你的问题。我不清楚你要做什么。只需删除字符串的第一个字符(就地)即可通过memmove完成:
memmove( buffer // destination
, buffer + 1 // source
, strlen(buffer) - 1 // number of bytes to copy
);
这需要线性时间,并假设buffer
不包含空字符串。
strcpy(buffer, buffer + 1)
不会这样做的原因是因为字符串重叠,所以这会产生未定义的行为。但是,memmove
明确允许源和目标重叠。
对于更复杂的字符过滤,您应该考虑使用“读取”指针和“写入”指针手动遍历字符串。只要确保写指针没有超出读指针,所以在读取时字符串不会被破坏。
void remove_semicolons(char *buffer)
{
const char *r = buffer;
char *w = buffer;
for (; *r != '\0'; r++)
{
if (*r != ';')
*w++ = *r;
}
*w = 0; // Terminate the string at its new length
}
答案 1 :(得分:3)
您正在使用带有重叠输入/输出缓冲区的strcpy,这会导致未定义的行为。
答案 2 :(得分:-1)
您正在搜索三个字符的序列(逗号空间分号),然后删除前两个字符(逗号和空格)。如果您也想删除分号,则需要删除所有三个字符(使用toRemove+3
代替toRemove+2
)。您还需要在strlen结果中添加1以说明终止字符串的NUL字节。
如果如你所说,你只想删除第一个分号而不是其他内容,则需要只搜索分号(可以使用strchr
进行分号):
if ((toRemove = strchr(in, ';')) // find a semicolon
memmove(toRemove, toRemove+1, strlen(toRemove+1)+1); // remove 1 char at that position