заменить символы в текстовом файле - логическая ошибка?

пользовательские типы $./replace i xy data.txt
data.txt содержит слова "это тестовый файл, только тестовый файл". Поэтому все i будут заменены на xy, т.е. thxys xys тестовый fxyle, только тестовый fxyle

Думаю, я совсем близко. Однако вместо замены i на xy мой код просто заменяет i на x. Я думаю, что ошибка в строке 38 strcpy. Однако верна ли логика в строках с 30 по 40? пытаюсь сказать....

Для каждого элемента в первом буфере (buf)
скопировать элемент buf в другой буфер (temp) по одному символу за раз
если элемент buf == 'i'
скопировать 'xy' в 'i'

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h> 


#define BUFFERSIZE 4096

/*replace i xy data.txt */

int main(int ac, char *av[])
{

    int in_fd, out_fd, n_chars, BufElement,j,x;
    ssize_t nread,nwrite;
    off_t newpos;
    char buf[BUFFERSIZE],temp[300];


        /*Open file containing original data*/
        if ( (in_fd=open(av[3], O_RDWR)) == -1 )
        {
            printf("Cannot open %s\n", av[3]);
            exit(1);
        }


        /*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++)
                {
                    temp[BufElement] = buf[BufElement];
                    if (buf[BufElement] == av[1][j])
                        strncpy(temp+BufElement,av[2],strlen(av[2])); /*ERROR*/

                }

            }
        }

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

            newpos = lseek(in_fd, 0, SEEK_SET); 

            nwrite = write(in_fd,temp,36); 

            close(in_fd);
        }

}

person Pk Granville    schedule 20.04.2012    source источник
comment
Зачем изобретать велосипед? Вы смотрели на sed и использование временного файла?   -  person Ed Heal    schedule 20.04.2012
comment
да, но я хотел бы написать свою собственную команду   -  person Pk Granville    schedule 20.04.2012
comment
Вы можете поместить строку temp[BufElement] = buf[BufElement]; вне самого внутреннего цикла.   -  person Some programmer dude    schedule 20.04.2012
comment
ваш темп[300]; мой будет слишком мал, если я позвоню ./replace x yyyyyy... 400times..yyyy data.txt   -  person Peter Miehle    schedule 20.04.2012


Ответы (2)


у вас есть только одно приращение BufElement, но поскольку ваш буфер назначения может становиться больше или меньше, чем ввод, у вас должно быть два счетчика/указателя; один для следующего места для записи в ваш буфер назначения, а другой напоминает буфер ввода.

EDIT: псевдокод:

while src[i]
  if match
    dest[j] = replacement
    j += strlen(replacement)
    i += 1
  else
    dest[j] = src[i];
    i += 1
    j += 1
person Peter Miehle    schedule 20.04.2012

Ваша i была заменена на xy, но затем y заменяется буквой в вашем первом buf(buf) на temp[BufElement] = buf[BufElement].

Как сказал Петер Миле, вам нужен счетчик, чтобы отмечать смену каждый раз, когда вы делаете замену:

strncpy(temp+BufElement,av[2],strlen(av[2]))
person SyberToto    schedule 20.04.2012
comment
Что-то вроде этого ? while ( (nread = read(in_fd, buf, BUFFERSIZE)) › 0 ) { for (BufElement=0;BufElement ‹ nread;BufElement++) { for (j=0; j ‹ strlen(av[1]); j++) { temp[x] = buf[BufElement]; if (buf[BufElement] == ​​av[1][j]){ strncpy(temp+x,av[2],strlen(av[2])); х = BufElement + 1; } } } } - person Pk Granville; 20.04.2012