【问题标题】:Replacing strings in files - C替换文件中的字符串 - C
【发布时间】:2011-04-22 10:31:48
【问题描述】:

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

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

简单的方法是多次运行程序,每次输入不同的字符串,但我正在寻找更有效的方法。

我的输入可以是:

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

感谢您的帮助。

#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;
}

【问题讨论】:

  • 请注意,多次激活程序可能会导致错误答案。考虑以下几点:(1)用 bbbb 替换:aaaa 和(2)用 cccc 替换 bbbb,两次激活程序可能会为每个激活顺序提供不同的结果,我很确定这不是你需要的。
  • 你是对的,但我并不担心这个。正如您在我的代码中看到的那样,我并没有真正改变这个词,我只是在它周围添加了 html 标签

标签: c string file replace


【解决方案1】:

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

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

IMO,你应该定义在这种情况下你想做什么,然后使用类似于你已经做过的方法。

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

【讨论】:

    【解决方案2】:

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

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

    很抱歉我不能完全回答你的问题,但我想这可能会给你一些优化的想法。

    【讨论】:

      【解决方案3】:

      我认为这会对您有所帮助。请使用以下代码来搜索和替换字符串。

      像这样从 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);
      

      }

      【讨论】:

        【解决方案4】:
        //
        // 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;
        }
        

        【讨论】:

          猜你喜欢
          • 2011-05-19
          • 1970-01-01
          • 2011-10-20
          • 2023-03-21
          • 1970-01-01
          • 1970-01-01
          • 2014-07-30
          • 1970-01-01
          相关资源
          最近更新 更多