简体   繁体   中英

How to replace the text into a particular location of a file by passing the argument via command line argument

My intention is to read the second element in the 1st row and replace it with the value which we pass as an command line argument and replace it in the input.txt file

Input file:logic.txt

one=1234

two=3456

I want my file to be changed like this after compiling the code.

./a.out 1567

Currently i am getting output like this

./filelogic 1567

1567=1234

two=5678

Expected Output file should be modified like this after the compilation

logic.txt

one=1567

two=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);
       }

Could someone guide me to resolve this issue?Thanks in advance

You can make replacements to a file in-place , but you should not do this in practice. You will likely corrupt the file if you attempt to replace characters and do not make an exact one-to-one replacement of characters already in the file.

To safely change the contents of a file, read the entire file contents into memory, make the changes needed, and then truncate the current file and write the new contents to the truncated file. (if the file is too large for in-memory operations, then use a temporary file)

You do not want to use atoi to convert the string "1567" to an integer. You are replacing characters in a file, not integer values in a binary file, so work with characters instead.

Your project is complicated by only wanting to replace the text after the first '=' sign. This may or may not be on the first line of the file, so you will need some flag to indicate when the first '=' is found and the replacement is made. (once the replacement is made, you can simply break your read loop and close the file -- but below the example output all lines for convenience)

Any time you close a file after writing to it, you should validate the return of fclose to catch any stream errors, or errors that occurred on the last write that will not be apparent until the next file operation.

With those cautions and caveats in mind, you could do something similar to:

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

Using your file logic.txt as an example input, and naming the executable filelogic as you have, the use and operation of the code above yields:

logic.txt File Before

$ cat logic.txt
one=1234

two=3456

Example Use/Output

$ ./filelogic
one=1567

two=3456

logic.txt File After

$ cat logic.txt
one=1567

two=3456

Again, this is fine for a learning endeavor, but in practice, avoid making changes to files in-place as the risk of inadvertent file corruption far outweighs writing a new file with the changes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM