#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <stdlib.h>
#define MAX_LEN 80
#define NAME_LEN 256
char* puts_r(char *str);
void r_printf(const char * fstr, ...);
FILE* fcreate(char*);
void fappend(FILE*);
void fprint(FILE*,char*);
FILE* fdelete(FILE*,char*,int,int);
int main()
{
FILE *f;
char filename[NAME_LEN];
puts_r("Введите имя файла:");
gets(filename);
f=fcreate(filename);
fprint(f,filename);
int pos,num;
puts_r("Введите позицию и количество строк, которые надо удалить:");
scanf("%d%d",pos,num);
fdelete(f,filename,pos,num);
fprint(f,filename);
return 0;
}
char* puts_r(char *str)
{
static char out_str[BUF_SIZE];
CharToOem(str,out_str);
puts(out_str);
return out_str;
}
void r_printf(const char * fstr, ...)
{
char buf[BUF_SIZE];
va_list va;
va_start(va,fstr);
vsnprintf(buf,sizeof(buf)-1,fstr,va);
va_end(va);
CharToOem(buf,buf);
printf(buf);
}
FILE* fcreate(char *filename)
{
FILE *f;
if(!(f=fopen(filename,"a")))
{
puts_r("Ошибка создания/открытия файла!");
getch();
exit(0);
}
return f;
}
void fprint(FILE *f,char *filename)
{
char string[MAX_LEN];
if(!(f=fopen(filename,"r")))
{
puts_r("Ошибка открытия файла!");
getch();
exit(0);
}
puts_r("Содержимое файла:");
while(!feof(f))
{
fgets(string,MAX_LEN,f);
printf("%s",string);
}
fclose(f);
getch();
}
FILE* fdelete(FILE *f,char *filename,int pos,int num)
{
char **temp,str[MAX_LEN];
int k=0;
pos=4;
num=2;
if(!(f=fopen(filename,"r+")))
{
puts_r("Ошибка создания файла!");
getch();
exit(0);
}
while(fgets(str,MAX_LEN,f)) k++;
if(!(pos>0)&&(pos<k))
{
puts_r("Неверная позиция");
exit(0);
}
if((temp=(char**)calloc(k,sizeof(char*)))==NULL)
{
puts_r("Ошибка выделения памяти");
exit(0);
}
for(int i=0;i<k;i++)
if((temp=(char*)calloc(MAX_LEN,sizeof(char)))==NULL)
{
puts_r("Ошибка выделения памяти");
exit(0);
}
int i,k1;
for(i=0;k1<=pos;k1++)
fgets(str,MAX_LEN,f);
for(i=0,k1=pos;k1!=k;k1++,i++)
fgets(temp,MAX_LEN,f);
for(i=0;k1<=pos;k1++)
fgets(str,MAX_LEN,f);
for(i=0,k1=pos;k1!=k;k1++,i++)
fputs(temp,f);
fclose(f);
fclose(f);
puts_r("Заданные строки удалены");
getch();
}
Удаление в текстовом файле в заданной позиции заданного количества строк
Код:
1111111
2222222
3333333
4444444
5555555
2222222
3333333
4444444
5555555
Если позиция равна 2, и количество строк тоже 2, то файл приобретет вид:
Код:
1111111
4444444
5555555
4444444
5555555
Сам пробовал писать. Что-то не получается:( . Вот мой код:
Код:
P.S. Функция удаления в моем коде под именем fdelete. Я просто не хотел играться, выкладывая сюда только тот код, который не работает, потому выложил весь cpp. Помогите пожалуйста. Задача ведь простенькая)
В файле stdio.h объявлена константа FILENAME_MAX - используйте её вместо своей NAME_LEN.
Что-то я не вижу в вашем коде определения BUF_SIZE. В том же заголовочном файле есть константа BUFSIZ - имелась в виду она?
Не используйте функцию gets - её применение чревато переполнением буфера.
Код возврата 0 означает успешное завершение программы. Следовательно, при ошибках работы с файлом и с выделением памяти нужно в функции exit указывать значения отличные от нуля: на каждую ошибку свой код.
Один и тот же файл открывается несколько раз - почти в каждой функции. Это не нужно. Следует открыть его один раз, а потом ссылку на него передавать в другие функции.
Память, выделенную с помощью calloc следует потом освободить функцией free.
В функцию scanf нужно передавать ссылки на переменные. Не забывайте &.
А по самому главному моему вопросу ничего не скажете?(
Код:
for(i=0;i<=pos;i++)
fgets(temp11,MAX_LEN,f);
for(k1=pos;k1<(pos+num);k1++)
fgets(str,MAX_LEN,f);
for(i=k1;k1<=k;k1++)
fgets(temp1[k1],MAX_LEN,f);
fclose(f);
if(!(f=fopen(filename,"w")))
{
puts_r("Error!");
getch();
exit(1);
}
for(i=0;i<k-num;i++)
fputs(temp1,f);
fgets(temp11,MAX_LEN,f);
for(k1=pos;k1<(pos+num);k1++)
fgets(str,MAX_LEN,f);
for(i=k1;k1<=k;k1++)
fgets(temp1[k1],MAX_LEN,f);
fclose(f);
if(!(f=fopen(filename,"w")))
{
puts_r("Error!");
getch();
exit(1);
}
for(i=0;i<k-num;i++)
fputs(temp1,f);
Просто плюсами это делается с полпинка с помощью файловых потоков, например. Есть прекрасная функция readln (или readline, но маловероятно), которая считывает строки. Организуешь считывание в цикле с условием, мол не 2 строку и 2 раза игнорировать.
Можно читать файл в динамический массив равный длине основного файла, потом писать уже в него с самого начала, а в конец впихнуть EOF, например.
Код:
void fdelete(char *filename,int pos,int num)
{
int filesize=0,nStrings=0,count=0;
char ch;
char *tmp;
FILE *f=NULL;
if(!(f=fopen(filename,"r")))
{
puts("Помилка вiдкриття файлу!");
getch();
exit(1);
}
fseek(f, 0, SEEK_END);
filesize = ftell(f);
fseek(f, 0, SEEK_SET);
while((ch=fgetc(f))!=EOF)
if(ch=='\n')nStrings++;
if(pos<0||pos>nStrings)
{
puts("Невiрна позицiя!");
getch();
exit(0);
}
if(!(tmp=(char*)calloc(filesize,sizeof(char))))
{
puts("Помилка видiлення пам'ятi!");
getch();
exit(0);
}
fseek(f,0,SEEK_SET);
for(int c=0; ;c++)
{
if((ch=getc(f))==EOF)
{
filesize=c;
break;
}
if(ch=='\n')
count++;
if(count>=pos-1 && count<=pos-2+num)
{
c--;
continue;
}
tmp[c]=ch;
}
fclose(f);
if(!(f=fopen(filename,"w")))
{
puts("Помилка вiдкриття файлу!");
getch();
exit(0);
}
if(fputs(tmp,f)) puts("Помилка запису");
else puts("Рядки успiшно видаленi.");
fclose(f);
}
{
int filesize=0,nStrings=0,count=0;
char ch;
char *tmp;
FILE *f=NULL;
if(!(f=fopen(filename,"r")))
{
puts("Помилка вiдкриття файлу!");
getch();
exit(1);
}
fseek(f, 0, SEEK_END);
filesize = ftell(f);
fseek(f, 0, SEEK_SET);
while((ch=fgetc(f))!=EOF)
if(ch=='\n')nStrings++;
if(pos<0||pos>nStrings)
{
puts("Невiрна позицiя!");
getch();
exit(0);
}
if(!(tmp=(char*)calloc(filesize,sizeof(char))))
{
puts("Помилка видiлення пам'ятi!");
getch();
exit(0);
}
fseek(f,0,SEEK_SET);
for(int c=0; ;c++)
{
if((ch=getc(f))==EOF)
{
filesize=c;
break;
}
if(ch=='\n')
count++;
if(count>=pos-1 && count<=pos-2+num)
{
c--;
continue;
}
tmp[c]=ch;
}
fclose(f);
if(!(f=fopen(filename,"w")))
{
puts("Помилка вiдкриття файлу!");
getch();
exit(0);
}
if(fputs(tmp,f)) puts("Помилка запису");
else puts("Рядки успiшно видаленi.");
fclose(f);
}