Вы можете внести замены в файл на месте , но вы не должны делать это на практике. Вероятно, вы повредите файл, если попытаетесь заменить символы и не будете делать точную замену символов один на один в файле.
Чтобы безопасно изменить содержимое файла, прочитайте все содержимое файла в памяти, внесите необходимые изменения и затем обрезайте текущий файл и запишите новое содержимое в усеченный файл. (если файл слишком велик для операций с памятью, затем используйте временный файл)
Вы не хотите использовать atoi
для преобразования строки "1567"
в целое число. Вы заменяете символы в файле, а не целочисленные значения в двоичном файле, поэтому работайте с символами.
Ваш проект осложнен только желанием заменить текст после первого '='
. Это может быть или не быть в первой строке файла, поэтому вам понадобится некоторый флаг, указывающий, когда будет найден первый '='
и будет произведена замена. (после того, как замена выполнена, вы можете просто сломать цикл чтения и закрыть файл, но ниже примера вывести все строки для удобства)
Каждый раз, когда вы закрываете файл после записи , вы должны проверить возврат fclose
, чтобы поймать любые ошибки потока или ошибки, возникшие при последней записи, которые не будут очевидны до следующей операции с файлом.
С этими предупреждениями и Предостережения, вы можете сделать что-то похожее на:
#include <stdio.h>
#include <string.h>
#define MAXSIZE 64 /* max line/buffer size */
#define FNAME "logic.txt" /* default file name */
#define REPLACE "1567" /* default replacement text */
int main (int argc, char **argv) {
char buf[MAXSIZE] = ""; /* line buffer */
const char *str = argc > 1 ? argv[1] : REPLACE; /* replacement string */
int replaced = 0; /* flag indicating replacement made */
FILE *fp = fopen (FNAME, "r+"); /* open file reading/writing */
if (!fp) { /* validate file open for reading/writing */
perror ("fopen-FNAME");
return 1;
}
while (fgets (buf, MAXSIZE, fp)) { /* read each line in file */
if (!replaced) { /* if replacement not yet made */
char *p = strchr (buf, '='); /* search for '=' in line */
if (p) { /* if found */
size_t plen = 0; /* var for length to end */
p++; /* advance past '=' sign */
plen = strlen (p); /* get length to end */
if (plen < strlen (str)) { /* check avail length */
fprintf (stderr, "error: not enough space in line.\n");
return 1;
}
strcpy (p, str); /* copy str to p */
if (fseek (fp, -plen, SEEK_CUR)) { /* backup plen chars */
perror ("fseek(fp)");
return 1;
}
fputs (p, fp); /* overwite contents with replacement */
replaced = 1; /* set flag indicating replacement */
} /* (you can break, and remove output */
} /* here if not writing to stdout) */
fputs (buf, stdout); /* output lines to stdout (optional) */
}
if (fclose (fp) == EOF) /* always validate close-after-write */
perror ("fclose-FNAME");
return 0;
}
Используя ваш файл logic.txt
в качестве примера ввода и назвав исполняемый файл filelogic
, как вы, использование и действие кода выше дает:
logic.txt Файл Before
$ cat logic.txt
one=1234
two=3456
Пример использования / вывода
$ ./filelogic
one=1567
two=3456
файл logic.txt После
$ cat logic.txt
one=1567
two=3456
Опять же, это хорошо для обучения, но на практике избегайте внесения изменений в файлы на месте , так как риск непреднамеренного повреждения файлов намного перевешивает запись нового файла с изменениями.