我只是用c语言编写了一个简单的代码,该代码应该从文件中提取文本并用另一个替换一个词。但是,我不知道为什么,但是我的代码仅替换了第二个字母开头的单词。我究竟做错了什么? 这是我的代码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *f;
char sir[20];
if ((f=fopen("fis.txt","r"))==NULL)
{
printf("Not ok");
exit(1);
}
gets(sir);
fscanf(f, "%s",sir);
printf("Give the word you are looking for and the word to replace it with");
getchar();
char s1[10],s2[10];
gets(s1);
gets(s2);
char *p, aux[100];
while (p=strstr(sir,s1))
{
strcpy(aux,p+strlen(s1));
strcpy(p,s2);
strcpy(p+strlen(s2),aux);
puts(sir);
}
}
答案 0 :(得分:0)
我发现您的方法有点太复杂了,只需移动指针就可以简化得多。这是一个粗略的(1)草图:
ChoiceType
答案 1 :(得分:0)
从我的评论继续,永远不要使用gets()
,它是非常不安全的,并且会由于缓冲区溢出而被利用。相反,对于面向 line 的输入,请使用fgets
或POSIX getline
。
在读取文本文件作为输入时,您有99%的时间正确地看过行导向输入功能。在这里可以正常工作,但是您必须确保行缓冲区足以容纳您预期的最大行。
您也不应尝试通过“就地”修改正在搜索的文件。虽然“查找和替换”一词的长度可能完全相同,但是您必须小心,否则将损坏文件。写入新文件后,您可以随意将“查找”和“替换”字词的长度不同。
假设您的单词将完全包含在您阅读的行中(并且不带连字符或以其他方式分成多行),您可以简单地阅读每一行,将指针分配给该行中的起始字符,然后步行-指针向下移动,当字符与查找单词中的字符匹配时保留索引,并在字符不同时输出替换。您必须考虑如何处理重置索引和处理部分匹配的问题,但这只是一点儿算术。
例如,如果您有一个指向打开的文件流的指针(例如fp
),则将每一行读入buf
,并在find
中查找单词,并在{中查找替换字符串{1}},您可以执行以下操作:
repl
(您应该进一步检查每行的 lfind = strlen (find); /* length of replacement */
while (fgets (buf, MAXCH,fp)) { /* read each line in file */
p = buf; /* pointer to buf */
while (*p) {
if (*p == find[ndx]) /* if matches char in find */
ndx++; /* advance index */
else { /* otherwise */
if (ndx) { /* if find chars matched */
if (ndx == lfind) /* if full word found */
fputs (repl, stdout); /* output replacement */
else { /* otherwise */
int tmp = repl[ndx]; /* save char at ndx */
repl[ndx] = 0; /* nul-terminate repl */
fputs (repl, stdout); /* output replacement */
repl[ndx] = tmp; /* restore char at ndx */
}
ndx = 0; /* zero index */
}
putchar (*p); /* output current char */
}
p++;
}
}
fclose (fp); /* close file */
if (ndx) { /* if partial match at end of file */
repl[ndx] = 0; /* nul-terminate repl at index */
fputs (repl, stdout); /* output final chars */
}
以及它是否适合并且没有被截断,否则,您将要寻找的单词的不同部分置于两个不同的缓冲区中-剩下的风险给你)
还请注意,如果strlen
非零,则退出循环后进行检查以输出任何最终字符。
以一个简短的示例为例,该示例使用文件名来读取和查找/查找/替换字符串作为程序的参数1、2、3(或者如果未提供作为参数将提示查找/替换),则可以执行以下操作以下:
ndx
示例输入文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXCH 1024
#define MAXWD 128
void handle_args (int argc, char **argv, char *find, char *repl);
int main (int argc, char **argv) {
size_t lfind, ndx = 0;
char buf[MAXCH], find[MAXWD] = "", repl[MAXWD] = "", *p;
FILE *fp = NULL;
if (argc < 2 ) { /* validate at least one argument given */
fprintf (stderr, "error: insufficient input, usage: "
"%s filename [find, repl]\n", argv[0]);
return 1;
}
if (!(fp = fopen (argv[1], "r"))) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
handle_args (argc, argv, find, repl); /* set/prompt for find/repl */
lfind = strlen (find); /* length of replacement */
while (fgets (buf, MAXCH,fp)) { /* read each line in file */
p = buf; /* pointer to buf */
while (*p) {
if (*p == find[ndx]) /* if matches char in find */
ndx++; /* advance index */
else { /* otherwise */
if (ndx) { /* if find chars matched */
if (ndx == lfind) /* if full word found */
fputs (repl, stdout); /* output replacement */
else { /* otherwise */
int tmp = repl[ndx]; /* save char at ndx */
repl[ndx] = 0; /* nul-terminate repl */
fputs (repl, stdout); /* output replacement */
repl[ndx] = tmp; /* restore char at ndx */
}
ndx = 0; /* zero index */
}
putchar (*p); /* output current char */
}
p++;
}
}
fclose (fp); /* close file */
if (ndx) { /* if partial match at end of file */
repl[ndx] = 0; /* nul-terminate repl at index */
fputs (repl, stdout); /* output final chars */
}
return 0;
}
/* simple function to set find/repl from command line, or
* prompt for input if no arguments given.
*/
void handle_args (int argc, char **argv, char *find, char *repl)
{
if (argc < 3) {
fputs ("enter find word: ", stdout);
if (scanf ("%127s", find) != 1) {
fputs ("error: invalid input.\n", stderr);
exit (EXIT_FAILURE);
}
}
else {
size_t len = strlen (argv[2]);
if (len < MAXWD)
memcpy (find, argv[2], len + 1);
else {
fputs ("error: find argument too long.\n", stderr);
exit (EXIT_FAILURE);
}
}
if (argc < 4) {
fputs ("enter repl word: ", stdout);
if (scanf ("%127s", repl) != 1) {
fputs ("error: invalid input.\n", stderr);
exit (EXIT_FAILURE);
}
}
else {
size_t len = strlen (argv[3]);
if (len < MAXWD)
memcpy (repl, argv[3], len + 1);
else {
fputs ("error: repl argument too long.\n", stderr);
exit (EXIT_FAILURE);
}
}
}
使用/输出示例
$ cat ../dat/qbfox3.txt
A quick brown fox jumps over the lazy dog.
A slow green dog jumps on top of the blue cat.
A quick blue bird flew over the lazy dog too.
或者检查第一个和最后一个字符替换的特殊情况,例如
$ ./bin/file_replace_fgets_stdout ../dat/qbfox3.txt dog duck
A quick brown fox jumps over the lazy duck.
A slow green duck jumps on top of the blue cat.
A quick blue bird flew over the lazy duck too.
仔细检查一下,如果还有其他问题,请告诉我。