Редактирование строки в текстовом файле с использованием временного файла C
Я пытаюсь отредактировать строку в текстовом файле, но у меня неожиданное поведение при редактировании файла. Что я хочу сделать, это настроить конкретную строку (точки: 100) текста, который выглядит. В функции я передаю аргументы по значению новые монеты, которые нужно отрегулировать, и смещение файла с помощью ftell->user_point. То, что я получаю в качестве вывода, странно. Я пытаюсь скопировать оставшуюся часть файла во временную папку с отредактированной строкой, а затем скопировать ее обратно в исходный файл из точки, которую я скопировал во временную папку (это смещение user_point с помощью ftell). Вот оригинальный файл с такими записями:
...
_______________________________________
nickname : geo
password : cuvctq
Name : george
Surname : papas
points : 100
participated :
past draws : 0
Chosen No. :
future draws : 0
Registered : Sun Feb 05 19:23:50 2012
...
Что я получаю после 2-го прогона редактирования:
...
_______________________________________
nickname : geo
password : cuvctq
Name : george
Surname : papaspoints : 98
participated :
past draws : 0
Chosen No. :
future draws : 0
Registered : Sun Feb 05 19:23:50 2012
...
At the end of the text i get one extra \n after i edit the
file whch is something i dont want :/
и поэтому дальнейшее редактирование испортит текст... Я также получаю ДОПОЛНИТЕЛЬНО \ n в конце строки, что, по крайней мере, то, что я так думаю, связано с "r+"
режим, который я тоже не хочу...
void coins_adjust(int coins_new,int user_point)
{
int lines,i,ln_point_copy;
char buffer[50],buff_copied[50];
FILE *lottary,*temp;
memset(buff_copied,'\0',sizeof(char)*50);
lottary=fopen("customers.txt","r");
temp=fopen("temp.txt","w");
fseek(lottary,user_point,SEEK_SET);
for (lines=0;lines<5;lines++)
{
memset(buffer,'\0',sizeof(char)*50);
if (lines==5)
ln_point_copy=ftell(lottary); //from TEMP to CUSTOMERS
fgets (buffer ,50 , lottary);
}
coins_new+=atoi(buffer+15);
strncpy(buff_copied,buffer,15); //copy 15 chars and fill with null
memset(buffer,'\0',sizeof(char)*50);
itoa (coins_new,buffer,10); //fix the new line to be entered
strcat(buff_copied,buffer); //the edited line is as it is supposed
strcat(buff_copied,"\n"); //to be with \n at the end.
puts(buff_copied);
printf("%s",buff_copied);fflush(stdout);
fprintf(temp,"%s",buff_copied);
for(i=getc(lottary); i!=EOF; i=getc(lottary)) //copy to temp
{
putc(i, temp);
}
fclose(lottary);
fclose(temp);
temp=fopen("temp.txt","r");
lottary=fopen("customers.txt","r+");
fseek(lottary,ln_point_copy,SEEK_SET);
for(i=getc(temp); i!=EOF; i=getc(temp)) //copy until eof
{
putc(i, lottary);
}
fclose(lottary);fclose(temp);
}
Я отладил программу, и все, кажется, работает, по крайней мере, на том, какие значения передаются в массивы, где я храню строковые символы, но я не могу понять, почему он игнорирует \n
предыдущей строки, когда я пытаюсь скопировать его обратно в оригинал... Кажется, есть \r
символ, от которого я не могу избавиться, пока копирую обратно в оригинал... Заранее спасибо.
1 ответ
Я больше думал о чем-то вроде этого:
void change_points(int new_points)
{
FILE *input = fopen("customers.txt", "r");
FILE *output = fopen("temp.txt", "w");
char buffer[256];
while (fgets(buffer, sizeof(buffer), input))
{
/* Look for the correct line */
/* Can also use e.g. "if (strncmp(buffer, "points", 6) == 0)"
* if it's at the start of the line
*/
if (strstr(buffer, "points") != NULL)
{
int old_points;
sscanf(buffer, "%*s : %d ", &old_points);
/* Format how you like it */
fprintf(output, "%-13s: %d\n", "points", new_points + old_points);
}
else
fputs(buffer, output);
}
fclose(output);
fclose(input);
/* The file "temp.txt" now contains the modifeed text */
/* Copy either using "fgets"/"fputs", or using "fread"/"fwrite" */
input = fopen("temp.txt", "r");
output = fopen("customers.txt", "w");
while (fgets(buffer, sizeof(buffer), input))
fputs(buffer, output);
fclose(output);
fclose(input);
}
Это короче, проще, возможно, более эффективно (циклически перебирая строку за строкой, а не символ за символом), и искомая строка может находиться в любом месте файла, не зная его точную позицию.