Запись и чтение из файла одновременно
Я пытался одновременно читать и писать из файла и пытаюсь заменить все вкладки в тексте text.txt на пробелы. Это мой код:
int main()
{
FILE* filePtr = fopen("text.txt", "w+");
char c;
c = fgetc(filePtr);
fpos_t num;
while(c != EOF)
{
if(c == '\t')
{
fgetpos(filePtr, &num);
num--;
fsetpos(filePtr, &num);
fputc(' ', filePtr);
}
c = fgetc(filePtr);
}
}
Содержимое text.txt таково:
Привет, мое \t имя \t is \t jack!
Когда я запускаю этот код, мой вывод в файле text.txt просто пустое место. Там нет персонажей там. Что я должен сделать, чтобы замены работали как задумано?
4 ответа
Есть три основные проблемы с вашим кодом:
Открытие файла в режиме
"w+"
обрезает файл (удаляет все содержимое). Вы можете как читать, так и писать, но оригинальное содержимое потеряно. Режим"r+"
откроет его для чтения и записи без изменения содержимого и с положением файла первоначально в начале файла.Не безопасно выполнять арифметику со значением типа
fpos_t
, Это в любом случае ненужно; Есть более простой способ переместить положение файла на относительную величину.Вы не закрываете файл, когда закончите.
Этот вариант вашего кода работает для меня:
#include <stdio.h>
int main(void)
{
FILE* filePtr = fopen("text.txt", "r+");
char c;
while((c = fgetc(filePtr)) != EOF)
{
if(c == '\t')
{
fseek(filePtr, -1, SEEK_CUR);
fputc(' ', filePtr);
}
}
fclose(filePtr);
return 0;
}
Цитируя cplusplus.com,
"w +" write / update: создайте пустой файл и откройте его для обновления (как для ввода, так и для вывода). Если файл с таким именем уже существует, его содержимое отбрасывается, и файл обрабатывается как новый пустой файл.
Вы должны использовать "r +".
"r +" чтение / обновление: открыть файл для обновления (как для ввода, так и для вывода). Файл должен существовать.
Здесь есть две основные проблемы с кодом:
- Режим "r+" должен использоваться здесь вместо "w+".
Режим "w +" удаляет все содержимое файла, если он был ранее, и затем записывает в файл, а режим "r+" позволяет вам использовать имеющиеся данные ранее.
- Функция установки положения должна использоваться при переключении с чтения на запись или с записи на чтение данных.
Из справочного файла Pelles C:
Когда файл открывается в режиме обновления ("+" в качестве второго или третьего символа в аргументе режима), ввод и вывод могут выполняться в связанном потоке. Однако за выводом не должен следовать прямой ввод без промежуточного вызова функции fflush или функции позиционирования файла (fseek, fsetpos или rewind), а за вводом не следует прямой вывод без промежуточного вызова позиционирования файла функция, если операция ввода не встречает конец файла.
Это код, который работал для меня:
int main(void)
{
FILE* filePtr = fopen("text.txt", "r+");
char c;
while( (c = fgetc(filePtr)) != EOF )
{
if(c == '\t')
{
fseek(filePtr, -1, SEEK_CUR);
fputc(' ', filePtr);
fseek(filePtr, 0, SEEK_CUR);
}
}
fclose(filePtr)
return 0;
}
Проблема в том, что вы используете w+
флаг Fopen и пытается уменьшить fpos_t
переменная, которая является сложным типом. Вы должны использовать r+
а затем уменьшить num.__pos
заставить его работать