Изменение содержимого текстового файла в C

Я понимаю, что в C, если у меня есть существующий текстовый файл «test.txt», вызов fopen («test.txt», «w») перезапишет существующее содержимое «test.txt».

Я пытаюсь найти эффективный способ решить мою проблему: предположим, что у меня есть 10 строк в test.txt, каждая из которых содержит число. test.txt может ссылаться на значения входных данных для решателя PDE, который у меня есть. Я хочу провести анализ чувствительности по последним 3 параметрам, т.е. оставить фиксированными первые 7 чисел в test.txt, я хочу попробовать разные значения для последних 3 строк. Следовательно, я буду писать в test.txt в цикле for, но я намерен менять только значения последних 3 строк на каждой итерации. Приложение fopen у меня не работает. Есть ли более эффективный способ сделать это, чем сохранять первые семь значений в массиве и переписывать эти значения в цикле for через fopen?

Предложения приветствуются.


person user1237300    schedule 07.07.2017    source источник
comment
Как правило, это плохая идея — пытаться изменить файл на месте, перезаписывая данные в его середине, потому что вы рискуете перезаписать более поздние данные, а таким образом очень легко повредить файл (вы не можете вставлять данные в файл между двумя файлами). байт: вам нужно сначала скопировать данные, что может быть очень неэффективно). Если файл невелик, вы можете прочитать его целиком в память как связанный список, манипулировать им в памяти, а затем обрезать и перезаписать файл.   -  person Dai    schedule 08.07.2017
comment
Это правда, @Dai, но в этом случае OP намеревается потерять исходные данные в конце файла. Это более легкий случай, чем вставка в середину.   -  person John Bollinger    schedule 08.07.2017
comment
Предположим, что у меня есть 10 строк в test.txt — сохраните их в памяти, возможно, в массиве, обновите значения в памяти и выполните окончательную запись, когда закончите.   -  person David C. Rankin    schedule 08.07.2017


Ответы (1)


Следовательно, я буду писать в test.txt в цикле for, но я намерен менять только значения последних 3 строк на каждой итерации. Приложение fopen у меня не работает. Есть ли более эффективный способ сделать это, чем сохранять первые семь значений в массиве и переписывать эти значения в цикле for через fopen?

Похоже, вам все равно нужно будет прочитать и сохранить первые семь значений. Однако вы действительно можете избежать их переписывания. Сначала откройте файл в режиме чтения/записи без усечения:

FILE *input = fopen("test.txt", "r+");

Режим чтения/записи отличается от режима добавления ("a" или "a+") тем, что в первом случае файл изначально располагается в начале и записи всегда идут в текущую позицию файла, тогда как во втором случае файл изначально позиционируется в конце, и записи всегда идут в конец.

Открыв файл в соответствующем режиме, прочитайте его построчно, т.е. с fgets(). После седьмой строки используйте ftell(), чтобы записать текущую позицию в файле для дальнейшего использования. Чтобы перезаписать последние строки, используйте fseek(), чтобы вернуться к записанной позиции, и просто напишите новые значения. Это может оставить мусор в конце файла после последней строки; если это будет проблемой, вы можете перезаписать хвост (например, пробелами). POSIX также имеет ftruncate(), который вы можете использовать для обрезки любого хвоста, но это не является частью стандарта C.

person John Bollinger    schedule 07.07.2017
comment
Хм, если не считать создания нового файла, есть ли стандартный способ сделать файл короче, чем 0? - person chux - Reinstate Monica; 08.07.2017
comment
@chux, я смотрел, но ftruncate() был ближе всего, что я мог найти. На самом деле я был немного удивлен этим, поэтому, если вы знаете стандартную функцию C, которая служит этой цели, обязательно поделитесь ею. - person John Bollinger; 08.07.2017
comment
я таких не знаю. IAC, мой обычный подход заключается в том, чтобы сначала создать еще один результирующий файл и удалить оригинал. - person chux - Reinstate Monica; 08.07.2017
comment
Спасибо, Джон. Но что вы имеете в виду под «Это может оставить мусор в конце файла»? Вы имеете в виду, что файл может состоять, скажем, из 11 строк? Это нежелательно для меня. - person user1237300; 09.07.2017
comment
Оставление мусора в конце означает, что запись в середину файла не усекает последующее содержимое. Все, что вы не перезаписываете, остается, и да, при некоторых обстоятельствах это может быть интерпретировано как дополнительная строка. Ответ уже касается того, как этого избежать при перезаписи файла на месте. Проблема не существует, если вы усекаете и перезаписываете весь файл. - person John Bollinger; 10.07.2017