有一次我在 C 中得到需要清理的 char 值。
这里我有一些示例,我可以在其中执行 phrase2(char);
。
在这里,它在一行中清理了所有内容。
但现在我有 XX.site.com
字符。
我怎样才能执行 phrase2
以删除第一个 .
前面的所有内容并只保留 site.com
?
void phrase2(char *buffer) {
char foo[1024];
int len;
bzero(foo, sizeof(foo));
for (len = 0; len != strlen(buffer); len++) {
if (buffer[len] == 10 || buffer[len] == 13) {
sprintf(foo, "%s", foo);
} else {
sprintf(foo, "%s%c", foo, buffer[len]);
}
}
bzero(buffer, sizeof(buffer));
strcpy(buffer, foo);
return;
}
您可以在不更改原始字符串内容的情况下左修剪字符串,只需使用不指向字符串中第一个字符但指向第一个点之后的字符的指针:
const char *prefixed = "www.site.com";
printf("'%s'\n", prefixed); // 'www.site.com'
printf("'%s'\n", &prefixed[4]); // 'site.com'
printf("'%s'\n", prefixed + 4); // ditto
在 C 语法中,最后两行是等价的。当然,您通常不知道第一个点之前的文字有多长。您甚至根本不知道字符串中是否有一个点。函数 strchr
来自 <string.h>
查找字符串中某个字符的第一次出现,因此:
const char *trimmed;
const char *p;
p = strchr(prefixed, '.');
trimmed = p ? p + 1 : prefixed;
printf("'%s'\n", trimmed); // 'site.com'
修剪后的字符串以 p + 1
开头, 因为您希望它在点之后开始一个字符。
您也可以就地修剪字符串,但请注意,您需要一个真正的字符数组,您可以修改它,而上面的内容也适用于只读字符串。
函数memcpy
复制原始数据,但你不能在这里使用它,因为源缓冲区和目标缓冲区可能重叠。 (出于同样的原因,sprintf(foo, "%s", foo);
是未定义的行为,正如 Sourav 所指出的那样。)使用函数 memmove
相反,它将安全地处理重叠缓冲区。
char str[] = "www.site.com";
const char *p;
p = strchr(str, '.');
if (p) {
int offset = p - str + 1;
int len = strlen(str);
memmove(str, str + offset, len - offset + 1);
}
printf("'%s'\n", str);
这个操作比较昂贵,因为它涉及复制数据。确保在将字符串尾部复制到前面时考虑到终止空字符,以便生成的字符串是正确终止的 C 字符串。
您会看到点的位置是通过减去两个指针计算出来的。这称为指针算术。熟悉它。