0

I am trying to write a linux command called replace which will replace characters in a file. I hope to call it like so:

$./replace I XY test.txt 

In this example, test.txt contains the words "THIS IS A TEST FILE"

How can I replace the character 'I' with "XY". I have tried to use a buffer such as the code given below, but due to the fact that the buffer and argv are declared differently, it produces an error. Furthermore, 'I' is stored in one array element, whereas "XY" requires two. Does there exist a workaround for this?

Consider the text.txt example:

[T][H][I][S][ ][I][S][ ][A][ ][T][E][S][T][ ][F][I][L][E]

In this example, the third index (which contains 'I') must be replaced with "XY"

Here's my code, which has the issue described above:

#define BUFFERSIZE 4096

/*replace i xy data.txt */
int main(int ac, char *av[])
{
    int in_fd, out_fd, n_chars, BufElement,j;
    char buf[BUFFERSIZE];
    in_fd=open(av[3], O_RDWR);

    /*Read characters from file to buffer*/
    while ( (nread = read(in_fd , buf, BUFFERSIZE)) > 0 )
    {
        for (BufElement=0;BufElement < nread;BufElement++)
        {
            for (j=0; j < strlen(av[1]); j++)
            {
                if (buf[BufElement] == av[1][j])
                    buf[BufElement] = av[2]; /*ERROR*/
            }/*for*/
        }/*for*/
    }/*while*/
}/*main*/
Lavaman65
  • 863
  • 1
  • 12
  • 22

1 Answers1

1

buf[BufElement] is a character and av[2] is a string( character pointer specifically ). You cannot equate the two like you've done( buf[BufElement] = av[2];) Also, even it was possible, you cant simple replace 1 byte with 2 bytes in a buffer easily in C. It will overwrite the next character.

You need to copy the file contents till the match is found in a temp buffer, append your replace string to this temp buffer and then copy the remaining contents of the file.

Pavan Manjunath
  • 27,404
  • 12
  • 99
  • 125
  • so just to verify. I copy "this is a test file" character by character to a buffer. WHILE I am copying, I check if argv[2] == i. If there is a match, then put X Y into buffer and copy the rest of the file into buffer. But then I have to specifically say if argv[2] == 'i' then put XY. The user should be able to replace any character with his choice of characters – Pk Granville Apr 20 '12 at 06:41
  • Yes, correct, something on these lines.if( buffer[i]==argv[1][0]), then buffer[i]='X', buffer[i+1]='Y' and then continue like buffer[i]=fgetc(fp) – Pavan Manjunath Apr 20 '12 at 06:43
  • thanks for your reply sir. Is there any general way of doing this? buffer[i]='X'. For example, if user enters $./replace I ZS test.txt then I should be replaced by Z and S. Hence, why I put buffer[i] = argv[2] (but of course this is error) – Pk Granville Apr 20 '12 at 06:48
  • you can do simply do `strncpy(buffer+i,argv[2],BUFFERSIZE-i)`. Note that `buffer+i` is a pointer but `buffer[i]` is a character. Then you can continue by readjusting the value of `i` like `i+=strlen(argv[2])` – Pavan Manjunath Apr 20 '12 at 06:54