Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Удаление в текстовом файле в заданной позиции заданного количества строк

37K
16 ноября 2010 года
Tolias28
48 / / 20.09.2010
Надо написать простеньку задачку на C. Программа должна удалять в текстовом файле "name.txt" заданное количество строк в заданной позиции. То есть, допустим, есть такой текстовый файл:
 
Код:
1111111
2222222
3333333
4444444
5555555

Если позиция равна 2, и количество строк тоже 2, то файл приобретет вид:
 
Код:
1111111
4444444
5555555

Сам пробовал писать. Что-то не получается:( . Вот мой код:
Код:
#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();
}


P.S. Функция удаления в моем коде под именем fdelete. Я просто не хотел играться, выкладывая сюда только тот код, который не работает, потому выложил весь cpp. Помогите пожалуйста. Задача ведь простенькая)
297
17 ноября 2010 года
koodeer
1.2K / / 02.05.2009
В алгоритм не вникал. Выскажу соображения общего плана.


В файле stdio.h объявлена константа FILENAME_MAX - используйте её вместо своей NAME_LEN.

Что-то я не вижу в вашем коде определения BUF_SIZE. В том же заголовочном файле есть константа BUFSIZ - имелась в виду она?

Не используйте функцию gets - её применение чревато переполнением буфера.

Код возврата 0 означает успешное завершение программы. Следовательно, при ошибках работы с файлом и с выделением памяти нужно в функции exit указывать значения отличные от нуля: на каждую ошибку свой код.

Один и тот же файл открывается несколько раз - почти в каждой функции. Это не нужно. Следует открыть его один раз, а потом ссылку на него передавать в другие функции.

Память, выделенную с помощью calloc следует потом освободить функцией free.

В функцию scanf нужно передавать ссылки на переменные. Не забывайте &.
37K
17 ноября 2010 года
Tolias28
48 / / 20.09.2010
Спасибо большое за замечания! Будем исправлять)
А по самому главному моему вопросу ничего не скажете?(
37K
17 ноября 2010 года
Tolias28
48 / / 20.09.2010
Ну пожалуйста, помогите((( вот уже второй день мучаюсь и не пойму, почему при таком коде в строки вообще ничего не записывается из файла.
Код:
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);
33K
17 ноября 2010 года
hivewarrior
205 / / 16.11.2010
Делать обязательно в чистом си?
Просто плюсами это делается с полпинка с помощью файловых потоков, например. Есть прекрасная функция readln (или readline, но маловероятно), которая считывает строки. Организуешь считывание в цикле с условием, мол не 2 строку и 2 раза игнорировать.
Можно читать файл в динамический массив равный длине основного файла, потом писать уже в него с самого начала, а в конец впихнуть EOF, например.
37K
21 ноября 2010 года
Tolias28
48 / / 20.09.2010
Всем спасибо за советы. Удаление заданных строк решил следующим способом:
Код:
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);
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог