【问题标题】:How to replace the text into a particular location of a file by passing the argument via command line argument如何通过命令行参数传递参数将文本替换到文件的特定位置
【发布时间】:2018-07-13 03:56:49
【问题描述】:

我的意图是读取第一行中的第二个元素并将其替换为我们作为命令行参数传递的值并在 input.txt 文件中替换它

输入文件:logic.txt

一个=1234

两个=3456

我希望我的文件在编译完代码后可以这样更改。

./a.out 1567

目前我得到这样的输出

./filelogic 1567

1567=1234

两个=5678

编译后预期的输出文件应该这样修改

逻辑.txt

一个=1567

两个=5678

        char buf[MAXSIZE] = {};
        int num = 0;
        int i = 0;

        num = atoi(argv[1]);

        printf("%d",num);

       FILE *fp1;
              fp1 = fopen("logic.txt","r");//currently reading the file.
       if(fp1 != NULL)
       {

                 fseek(fp1,3,0);//Need to Move the pointer to the 3rd position where i need to replace the num(fseek(fp1,??,0))-->how we can achieve that.

                 //Using which method i can replace the num value into a file (means need to replace 1234 inplace of 1567)

               //Once the changes are done need to replace in the same file.

                fread(buf, 1, MAXSIZE, fp1);

                printf("%s\n",buf);

                 fclose(fp1);


       }else {
                printf("Cannot open file"");
                    exit(1);
       }

有人可以指导我解决这个问题吗?提前致谢

【问题讨论】:

  • 文件中的替换(也称为覆盖)要求新旧内容具有完全相同的长度。否则,您必须读取旧文件并写入新文件,从而替换您想要的文件,或者将文件读入内存缓冲区,替换内容(可能会移动部分缓冲区内容)并从内存缓冲区重写文件。当然,对于后者,缓冲区必须有足够的大小来容纳替换前后的文件内容。

标签: c


【解决方案1】:

可以对文件就地进行替换,但您不应该在实践中这样做。如果您尝试替换字符并且没​​有对文件中已有的字符进行精确的一对一替换,您可能会损坏文件

要安全地更改文件的内容,请将整个文件内容读入内存,进行所需的更改,然后截断当前文件并将新内容写入截断的文件。 (如果文件太大而无法进行内存操作,则使用临时文件)

您不想使用atoi 将字符串"1567" 转换为整数。您要替换文件中的 字符,而不是二进制文件中的整数值,因此请改用字符。

您的项目很复杂,只想替换第一个 '=' 符号后的文本。这可能在文件的第一行,也可能不在文件的第一行,因此您需要一些标志来指示何时找到第一个 '=' 并进行替换。 (替换完成后,您可以简单地中断读取循环并关闭文件——但为方便起见,在示例下方输出所有行)

当您在写入文件后关闭文件时,您应该验证fclosereturn 以捕获任何流错误或上次发生的错误直到下一次文件操作才会出现。

考虑到这些注意事项和注意事项,您可以执行以下类似操作:

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

#define MAXSIZE 64          /* max line/buffer size */
#define FNAME "logic.txt"   /* default file name */
#define REPLACE "1567"      /* default replacement text */

int main (int argc, char **argv) {

    char buf[MAXSIZE] = "";         /* line buffer */
    const char *str = argc > 1 ? argv[1] : REPLACE; /* replacement string */
    int replaced = 0;               /* flag indicating replacement made */
    FILE *fp = fopen (FNAME, "r+"); /* open file reading/writing */

    if (!fp) {  /* validate file open for reading/writing */
        perror ("fopen-FNAME");
        return 1;
    }

    while (fgets (buf, MAXSIZE, fp)) {  /* read each line in file */
        if (!replaced) {                /* if replacement not yet made */
            char *p = strchr (buf, '=');    /* search for '=' in line */
            if (p) {                        /* if found */
                size_t plen = 0;            /* var for length to end */
                p++;                        /* advance past '=' sign */
                plen = strlen (p);          /* get length to end  */

                if (plen < strlen (str)) {  /* check avail length */
                    fprintf (stderr, "error: not enough space in line.\n");
                    return 1;
                }
                strcpy (p, str);                    /* copy str to p */
                if (fseek (fp, -plen, SEEK_CUR)) {  /* backup plen chars */
                    perror ("fseek(fp)");
                    return 1;
                }
                fputs (p, fp);  /* overwite contents with replacement */
                replaced = 1;   /* set flag indicating replacement   */
            }                   /* (you can break, and remove output */
        }                       /*  here if not writing to stdout)   */
        fputs (buf, stdout);    /* output lines to stdout (optional) */
    }
    if (fclose (fp) == EOF)     /* always validate close-after-write */
        perror ("fclose-FNAME");

    return 0;
}

使用您的文件logic.txt 作为示例输入,并将可执行文件命名为您所拥有的filelogic,以上代码的使用和操作产生:

logic.txt 文件之前

$ cat logic.txt
one=1234

two=3456

使用/输出示例

$ ./filelogic
one=1567

two=3456

之后的logic.txt文件

$ cat logic.txt
one=1567

two=3456

再次重申,这对于学习工作来说很好,但在实践中,请避免对文件进行就地更改,因为意外文件损坏的风险远远超过使用更改写入新文件的风险。

【讨论】:

  • 非常感谢 Rankin...逻辑真的很好
  • 很高兴为您提供帮助。这些都是很好的学习练习,因为它们迫使您戴上会计帽子并考虑行中是否有足够的空间来进行替换(您应该以同样的注意力来处理所有内存使用和 I/O 字节)。祝你编码顺利。
  • 需要您对实现以下功能的建议
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-29
  • 1970-01-01
  • 1970-01-01
  • 2012-06-19
  • 2017-04-20
  • 2011-09-28
  • 1970-01-01
相关资源
最近更新 更多