替换文件中的字符串 - C.

时间:2011-04-22 10:31:49

标签: c string file replace

我正在尝试制作一个替换文件中字符串的程序。

我得到了下面的程序,它替换了文件中所有出现的字符串,但现在我需要进行扩展,以便它将替换多个字符串。

琐碎的方法是多次运行程序,每次使用不同的字符串作为输入,但我正在寻找更有效的方法来实现它。

我的输入可以是:

  1. 要替换的字符串集(每个字符串出现一次)。
  2. 要按外观顺序替换的字符串列表(字符串可以在列表中多次)但不知道它们的偏移量。
  3. 感谢您的帮助。

    #include <stdio.h>
    #include <string.h>
    #define LINE_LEN     128
    
    int main(){
    char fileOrig[32] = "orig.txt";
    char fileRepl[32] = "new.txt";
    char text2find[80];
    char text2repl[80];
    printf("enter text to replace in the file:");
    scanf ("%s",text2find);
    sprintf(text2repl,"%s%s%s","<b><font color=\"#FF0000\">",text2find,"</font></b>");
    char buffer[LINE_LEN+2];
    char *buff_ptr, *find_ptr;
    FILE *fp1, *fp2;
    int buff_int;
    size_t find_len = strlen(text2find);
    
    fp1 = fopen(fileOrig,"r");
    fp2 = fopen(fileRepl,"w");
    buff_int=(int)buffer;
    while(fgets(buffer,LINE_LEN+2,fp1)){
        buff_ptr = buffer;
        while ((find_ptr = strstr(buff_ptr,text2find))){
            while(buff_ptr < find_ptr)
                fputc((int)*buff_ptr++,fp2);
            fputs(text2repl,fp2);
            buff_ptr += find_len;
        }
        fputs(buff_ptr,fp2);
    }
    fclose(fp2);
    fclose(fp1);
    return 0;
    }
    

4 个答案:

答案 0 :(得分:1)

有时事情会变得复杂。假设您有要替换为{ab,ba}的字符串,它们将分别替换为{xy,yx}。假设你有输入文件包含&#34; aba&#34;。现在输出变得依赖于顺序。

如果替换一个字符串导致另一个字符串形成属于要替换的字符串列表,则会发生类似的混淆。

IMO,您应该在这种情况下定义您想要做的事情,然后使用类似于您已经完成的方法。

顺便说一句,您可以通过使用基于有限自动机的方法或使用一些现有的最先进算法(如KMPBoyer-Moore)来更好地进行字符串匹配。这样您就可以一次搜索多个字符串。

答案 1 :(得分:0)

我不确定您的想法是否可行,但您可能需要调查string search algorithms以使算法的搜索部分更加优化。根据维基百科,天真的搜索算法具有复杂度Θ((n-m+1) m)n文本的长度和m搜索字符串的长度。看看链接,你可以做得更好。

一旦你要替换所有字符串的偏移量,实际的替换似乎相当简单。

对不起,我无法完全回答你的问题,但我认为这可能会给你一些优化的想法。

答案 2 :(得分:0)

我认为这会对你有所帮助。请使用以下代码搜索&amp;替换字符串。

从Top lavel函数调用此函数,如下所示:

replaceIPAddress(“System.cfg”,“172.16.116.157”,“127.0.0.1”);


void replaceIPAddress(char * confFileName,char * text_to_find,char * text_to_replace) {

FILE *input = fopen(confFileName, "r");

FILE *output = fopen("temp.txt", "w");

char buffer[512];


while (fgets(buffer, sizeof(buffer), input) != NULL)
{
    char *pos = strstr(buffer, text_to_find);
    if (pos != NULL)
    {
        /* Allocate memory for temporary buffer */
        char *temp = calloc(
                strlen(buffer) - strlen(text_to_find) + strlen(text_to_replace) + 1, 1);

        /* Copy the text before the text to replace */
        memcpy(temp, buffer, pos - buffer);

        /* Copy in the replacement text */
        memcpy(temp + (pos - buffer), text_to_replace, strlen(text_to_replace));

        /* Copy the remaining text from after the replace text */
        memcpy(temp + (pos - buffer) + strlen(text_to_replace),
                pos + strlen(text_to_find),
                1 + strlen(buffer) - ((pos - buffer) + strlen(text_to_find)));

        fputs(temp, output);

        free(temp);
    }
    else
        fputs(buffer, output);
}

fclose(output);
fclose(input);

/* Rename the temporary file to the original file */
rename("temp.txt", confFileName);

}

答案 3 :(得分:-1)

//
// Find and replace data in a file
//
// This is not as straightforward a problem as it initially appears,
// because if you have the text
//
// "Jack is a pirate"
//
// And you wish to replace "is" with "was", the string needs to be longer,
// or else you end up with the following:
//
// "Jack wasapirate"
//
// This becomes more of a problem for larger text.  For example, if we wanted
// to replace "Jack" with "Rumpelstiltskin", we'd end up with:
//
// "Rumpelstiltskin"
//
// Which completely overwrites our original text!!!
//
// In order to do this correctly, we wither need to:
// 
// 1. Read the entire file into a in-memory buffer
// 2. Write to a temporary file, then replace the original file
//
// Option #2 is easier to implement, and should work for your coursework.
// 


#include <stdio.h>


int main(int argc, char** argv)
{
    // We need a buffer to read in data
    const int BufferSize = 0x1000;
    char      Buffer[BufferSize];
    char     *InputFileName     = "input.txt";
    char     *TemporaryFileName = "temp.txt";


    // Open the file for reading.  'rt' means that it must already exist, for reading.
    FILE     *Input = fopen(InputFileName, "rt");

    // Our output file.  'w+' means to create the file if it doesnt exist, for writing.
    FILE     *Output = fopen(TemporaryFileName, "w+");

    // Our find and replace arguments
    char     *Find = "is";
    char     *Replace = "was";

    if(NULL == Input)
    {
        printf("Could not open file");
        return 1;
    }

    printf("Find:    %s\n", Find);
    printf("Replace: %s\n", Replace);

    // For each line...
    while(NULL != fgets(Buffer, BufferSize, Input))
    {
        // For each incidence of "is"
        char *Stop = NULL;    // Where to stop copying (at 'is')
        char *Start = Buffer; // Start at the beginning of the line, and after each match

        printf("Line: %s\n", Buffer);

        while(1)
        {
            // Find next match
            Stop = strstr(Start, Find);

            if(NULL == Stop)
            {
                // Print the remaining text in the line
                fwrite(Start, 1, strlen(Start), Output);
                break;
            }

            // Write out everything between the end of the previous match, and the 
            // beginning of the current match.
            //
            // For example:
            //
            // "Jack is a pirate who is cool"
            //
            // Has two instances to replace.  In order, we'd find them as such:
            //
            // "Jack is a pirate who is cool"
            //       ^
            //                        ^
            // What we want to do is write:
            // - "Jack "
            // - "was"
            // - "a pirate who "
            // - "was"
            // - "cool"
            printf("Match starts at: %s\n", Stop);

            // We have found a match!  Copy everything from [Start, Stop)
            fwrite(Start, 1, Stop - Start, Output);

            // Write our replacement text
            fwrite(Replace, 1, strlen(Replace), Output);

            // Next time, we want to start searching after our 'match'        
            Start = Stop + strlen(Find);

            printf("Search resumes at: %s\n", Start);
        };
    }

    // Close our files
    fclose(Input);
    fclose(Output);

    // If desired, rename the Output file to the Input file
    rename(TemporaryFileName, InputFileName);

    return 0;
}