c - strcpy() 删除其他所有内容

标签 c

我需要读取一个文件并查找一个单词并替换为一个新单词,但它没有按预期工作:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main() {

FILE * f = fopen("text" , "rb" );
if(f == NULL ){
   perror("error ");
   return 1;
}
char chain[100];
while(!feof(f)){
    fgets(chain, 100 , f);

}
printf("%s", chain);
fclose(f);
printf("\n \n ;D \n");
return 0;
}

这就是我替换旧词的方式:

char str[] ="This is a hiall samplesss friends string";
char * pch;
pch = strstr (str,"hiall");
strncpy (pch,"sam",5);
puts (str);

谢谢

最佳答案

strncpy 正在将 5 个字符从 "sam" 复制到 pch 中。但请注意,"sam" 只有 3 个字符,因此它会复制这三个字符加上 \0 终止符。这就是为什么它“删除”字符串的其余部分:它在“sam”之后添加一个终止符,因此您将在输出中得到 This is a sam

如果您仅 strncpy 3 个字符,您将得到以下结果:

这是一个小样本好友字符串

如果您想要的是类似查找和替换的内容(即将“hiall”替换为“sam”并获取这是一个 sam Sampless 好友字符串),则需要移动其余的字符串向后。简单的 strncpy 将不起作用,因为目标内存与目标重叠。为此,您可以使用 memmove,或使用辅助缓冲区:

char str[] = "This is a hiall samplesss friends string";
char* pch;
char* old_word = "hiall";
char* new_word = "sam";
size_t len_old = strlen(old_word);
size_t len_new = strlen(new_word);
pch = strstr(str, old_word);
assert(len_new <= len_old);
if (pch) {
   char* rest = pch + len_old;
   size_t len_rest = strlen(rest);
   char* aux = malloc(len_rest + 1);
   strncpy(aux, rest, len_rest + 1);
   strncpy(pch, new_word, len_new);
   strncpy(pch + len_new, aux, len_rest + 1);
   free(aux);
   puts(str);
}

请注意,只有当 new_word 的大小等于或小于 old_word 时,此方法才有效。如果 new_word 较长,您将无法就地编辑(在字符串 str 本身中),除非原始字符串有额外的内存(例如,如果您使用 str[1000] 声明它,以保证您可以足够大地增加其大小 - 那么上面的代码就可以工作)。如果您无法提前计划 new_word 的大小,最安全的方法是分配一个新字符串:

char str[] ="This is a hiall samplesss friends string";
char* pch;
char* old_word = "hiall";
char* new_word = "sam";
pch = strstr(str, old_word);
size_t len_str = strlen(str);
size_t len_new = strlen(new_word);
size_t len_old = strlen(old_word);
if (pch) {
   char* new_str = malloc(len_str - len_old + len_new + 1);
   ptrdiff_t pos_word = pch - str;
   strncpy(new_str, str, pos_word);
   strncpy(new_str + pos_word, new_word, len_new);
   strncpy(new_str + pos_word + len_new, pch + len_old, 
                                         len_str - pos_word - len_old + 1);
   puts(new_str);
}

(编辑:解决了 David Bowling 在评论中指出的问题。)

关于c - strcpy() 删除其他所有内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42264660/

相关文章:

c++ - 在Linux上使用C中的输入功能,无需按Enter键

c++ - 在父窗口中限制可拖动的子窗口?

在 C 中复制文件

c - C 中的阶乘函数

c++ - 静态变量和常量变量有什么区别?

c - 读取文件时 "bypass"如何控制字符?

C++:一般来说,我应该使用字符串还是字符数组?

c - 如何获得零的 VSX 值?

c - 关闭文件后丢失文件数据

c++ - 为什么必须在 C 中向后读取指针声明?