Войти
ФлеймФорумПрограммирование

Замена строки в текстовом файле

Страницы: 1 2 Следующая »
#0
6:59, 25 янв 2023

В текстовом файле нужно установить курсор на определенную строку и перезаписать ее, не изменяя другие строки.
С удивлением не смог нагуглить вменяемого способа, без костылей, это сделать.
Плохо гуглил?

#1
(Правка: 7:18) 7:17, 25 янв 2023

MikeNew
> С удивлением не смог нагуглить вменяемого способа, без костылей, это сделать.
а чё за костыли хоть нашёл?

MikeNew
> Плохо гуглил?
вообще есть функция

void replaceLineInFile( ...params... )

она делает как раз то, что тебе нужно

#2
7:29, 25 янв 2023

skalogryz
> а чё за костыли хоть нашёл?
Сначала открыть файл для чтения, считать строки, так определить нужную позицию, потом снова открыть файл уже для записи....
Или рекомендуют вообще сначала считать файл в память, сделать нужные изменения и потом перезаписать полностью.

#3
7:30, 25 янв 2023

оба решения хороши. Особенно если твой файл не привысит 2 гигов размером.

#4
7:31, 25 янв 2023

skalogryz
> void replaceLineInFile( ...params... )
Мне для C++ нужно.

#5
(Правка: 7:33) 7:32, 25 янв 2023

MikeNew
> Мне для C++ нужно.
а там нет replaceLineInFile()?
может ты, просто, эту функцию не написал ещё?

#6
(Правка: 7:34) 7:34, 25 янв 2023

skalogryz
> а там нет replaceLineInFile()?
> может ты, просто, эту функцию не написал ещё?

Гениально. :))

#7
(Правка: 7:43) 7:39, 25 янв 2023

MikeNew
> Гениально. :))
возьми любой из двух костылей и реализуй.
можешь ещё такой костыль взять:

  • открываешь файл на чтение-запись.
  • ищешь нужную строчку (её начало)
  • переписываешь её содержимое на нужное, и всё содержимое после конца строчки. (главное не запороть данные которые идут после неё)
  • важно (вызывать setFileSize по окончанию перезаписи, если содержимое "укоротилось")
  • Из бонусов:
  • расход пямяти минимальный
  • операция открытия файла, единственная
  • Из недостатков:

  • не будет работать если доступ к файлу только последовательный (магнитная лента, кассеты), а определение нужной строчки требует не её номер, а читать содержимое.
  • Можно, кстати, ChatGPT напрячь! его, как раз, пилили, чтобы такие задачки решать

    #8
    7:42, 25 янв 2023

    MikeNew
    > В текстовом файле нужно установить курсор на определенную строку и перезаписать
    > ее, не изменяя другие строки.
    > С удивлением не смог нагуглить вменяемого способа, без костылей, это сделать.
    > Плохо гуглил?
    Текстовый файл - это иллюзия. На самом диске, все файлы - бинарные.

    Соответственно, замена подстроки в текстовом файле - это то же самое, что удалить кусок из байтового вектора и вставить на его место новый.

    Если старый и новый кусок имеют разную длину - то всё, что идёт после куска, придётся сдвигать копированием. Как в векторе, так и в файле.

    В общем, я бы сделал такой алгоритм:
    1. Открыть исходный файл на чтение.
    2. Создать новый пустой файл и открыть его на запись.
    3. Скопировать replacementOffset байт из исходного файла в новый поблочно.
    4. Пропустить length(oldText) байт в исходном файле.
    5. Записать newText в новый файл.
    6. Скопировать всё оставшееся содержимое исходного файла в новый поблочно.
    7. Удалить исходный файл.
    8. Переименовать новый файл на место исходного.

    #9
    7:49, 25 янв 2023

    Если файл небольшой - пузырим его в память. Производим вставку необходимого текста. Открываем файл на запись - пишем в него ранее измененный буффер. Закрываем файл.

    Если файл большой и память юзать жалко то можно сделать так - создаем временный файл, пишем туда в него что надо. Потом заменяем оригинальный на временный (старый удаляем, новый переименовываем именем старого).

    #10
    8:02, 25 янв 2023

    gambit_oz
    > Если файл большой и память юзать жалко то можно сделать так - создаем временный
    > файл, пишем туда в него что надо. Потом заменяем оригинальный на временный
    > (старый удаляем, новый переименовываем именем старого).
    Это делается по разному для винды и для юникса. В юниксе не надо ничего переименовывать, сразу создаем файл с нужным именем. Там можно удалять открытый файл и он остается живым пока открыт, чем и пользуются для модификации.

    #11
    8:28, 25 янв 2023

    Осознал, исчерпывающая информация. Всем спасибо.

    #12
    (Правка: 11:10) 11:06, 25 янв 2023

    А что, регулярные выражения не подходят?
    Для чего эти пляски с бубном?
    По моему они именно для этого сделаны.

    #13
    11:59, 25 янв 2023

    Zab
    > Это делается по разному для винды и для юникса. В юниксе не надо ничего
    > переименовывать, сразу создаем файл с нужным именем. Там можно удалять открытый
    > файл и он остается живым пока открыт, чем и пользуются для модификации.
    Так никто не делает, потому что в случае, если программа зависнет, крашнется, или пользователь дёрнет провод, если при этом не останется ни старого, ни нового файла - это ультра зашквар.

    #14
    17:07, 25 янв 2023

    Зачем писать программу, если можно воспользоваться sed?

    Страницы: 1 2 Следующая »
    ФлеймФорумПрограммирование

    Тема закрыта.