Как разбить текстовый файл на несколько частей в c - PullRequest
0 голосов
/ 05 декабря 2018

Что мне нужно сделать, это взять файл из n строк, и для каждых x строк создать новый файл со строками исходного файла.Примером может быть:

Исходный файл:

stefano

angela

giuseppe

lucrezia

В этом случае, если x == 2, будет создан 3 файла, в следующем порядке:

Первый файл:

stefano

angela

Второй файл:

giuseppe

lucrezia

Третий файл:

lorenzo

Что я сделал до сих пор, так это:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define  N 10

int getlines(FILE *fp)
{
  int c = 0;
  int ch;
  do{
  ch = fgetc(fp);
    if(ch == '\n')
    {
      c++;
    }
  }while(ch != EOF);
  fseek(fp, 0 , SEEK_SET);
  return c;
}

int ix = 0;

void Split(FILE *fp, FILE **fpo, int step, int lines, int *mem)
{
FILE **fpo2 = NULL;
char * filename = malloc(sizeof(char)*64);
char * ext = ".txt";
char  number[2];
for(int i = ix; i < *mem; i++)
{
  itoa(i+1, number,10);
  strcpy(filename, "temp");
  strcat(filename, number);
  strcat(filename, ext);

if(!(fpo[i] = fopen(filename, "w")))
{
  fprintf(stderr, "Error in writing\n");
  exit(EXIT_FAILURE);
}

}
  char ch;
  int  c = 0;
  do{
    ch = fgetc(fp);
    printf("%c", ch);
    if(ch == '\n')
    {
      c++;
    }
    if(c >= step)
    {
      c = 0;
      ix++;
      if(ix >= *mem && (ix*step) <= lines)
      {
      *mem = *mem + 1;
      fpo2 = realloc(fpo, sizeof(FILE*)*(*mem));
      Split(fp, fpo2, step, lines, mem);
      }
    }
    putc(ch, fpo[ix]);
  }while(ch != EOF);

}



int main()
{
FILE * fp;
if(!(fp = fopen("file.txt", "r")))
{
  fprintf(stderr, "Error in opening file\n");
  exit(EXIT_FAILURE);
}
int mem = N;
int lines = getlines(fp);
int step = lines/N;

FILE **fpo = malloc(sizeof(FILE *)*N);

Split(fp, fpo, step, lines, &mem);


exit(EXIT_SUCCESS);
}

У меня стек с ошибкой сегментации, я не смог найти ошибку, выполняющую

gdb myprogram

run

bt

Я очень ценю любую помощь.

РЕДАКТИРОВАТЬ:

Я изменил некоторые вещи, и теперь это работает, но он создает дополнительный файлкоторый содержит странные символы.Мне все еще нужно отрегулировать некоторые вещи:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define  N 10

int getlines(FILE *fp)
{
  int c = 0;
  int ch;
  do{
  ch = fgetc(fp);
    if(ch == '\n')
    {
      c++;
    }
  }while(ch != EOF);
  fseek(fp, 0 , SEEK_SET);
  return c;
}

int ix = 0;

void Split(FILE *fp, FILE **fpo, int step, int lines, int *mem)
{
FILE **fpo2 = NULL;
char * ext = ".txt";
for(int i = ix; i < *mem; i++)
{
  char * filename = malloc(sizeof(char)*64);
  char * number = malloc(sizeof(char)*64);

  itoa(i+1, number,10);
  strcpy(filename, "temp");
  strcat(filename, number);
  strcat(filename, ext);

if(!(fpo[i] = fopen(filename, "w")))
{
  fprintf(stderr, "Error in writing\n");
  exit(EXIT_FAILURE);
}
free(number);
free(filename);
}
  char ch;
  int  c = 0;
  do{
    ch = fgetc(fp);
    printf("%c", ch);
    if(ch == '\n')
    {
      c++;
    }
    if(c >= step)
    {
      c = 0;
      ix++;
      if(ix >= *mem && ((ix-1)*step) <= lines)
      {
      *mem = *mem + 1;
      fpo2 = realloc(fpo, sizeof(FILE*)*(*mem));
      Split(fp, fpo2, step, lines, mem);
      }
    }
    putc(ch, fpo[ix]);
  }while(ch != EOF);

}



int main()
{
FILE * fp;
if(!(fp = fopen("file.txt", "r")))
{
  fprintf(stderr, "Error in opening file\n");
  exit(EXIT_FAILURE);
}
int mem = N;
int lines = getlines(fp);
int step = lines/N;

FILE **fpo = malloc(sizeof(FILE *)*N);

Split(fp, fpo, step, lines, &mem);


exit(EXIT_SUCCESS);
}

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Я не буду исправлять твой код, но я помогу тебе с этим.Некоторые изменения, которые я предлагаю:

  • Вместо getlines , используйте getline (3) из стандартной библиотеки.
  • fseek(fp, 0 , SEEK_SET) isбессмысленно.
  • В char * filename = malloc(sizeof(char)*64) обратите внимание, что оба аргумента для malloc являются постоянными, а размер - произвольным.В наши дни можно безопасно размещать буферы имен файлов статически, либо в стеке, либо с помощью static : char filename[PATH_MAX].Вы можете использовать limits.h для получения этой константы.
  • Точно так же вам не нужно динамически размещать указатели FILE.
  • Вместо

    itoa(i+1, number,10); strcpy(filename, "temp"); strcat(filename, number); strcat(filename, ext);

    используйте sprintf(filename, "temp%d%s", i+1, ext)

  • познакомьтесь с err (3) и друзей, для вашего удобства.

Наконец, ваш рекурсив Split - как мы это скажем?-- кошмар.Вся ваша программа должна выглядеть примерно так:

open input
while getline input
  if nlines % N == 0
      create output filename with 1 + n/N
      open output
  write output
  nlines++    
0 голосов
/ 05 декабря 2018

В вашем коде есть несколько проблем.Но сначала я думаю, что вам нужно исправить самую важную вещь

int step = lines/N;

Здесь step равно 0, если ваш входной файл содержит менее N строк текста.Это потому, что lines и N оба являются целочисленными, а целочисленное деление округляется в меньшую сторону.

...