我的代码没有正确地用另一个词替换一个词

时间:2019-01-20 22:38:29

标签: c string replace word

我只是用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);


}


}

2 个答案:

答案 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.

仔细检查一下,如果还有其他问题,请告诉我。