如何在C中将文本文件拆分为多个部分

时间:2018-12-05 18:20:55

标签: c segmentation-fault text-files realloc

我需要做的是获取一个n行的文件,对于每x行,使用原始文件的行创建一个新文件。一个例子是这样:

原始文件:

  

stefano

     

安格拉

     

朱塞佩

     

lucrezia

在这种情况下,如果x == 2,将依次创建3个文件:

第一个文件:

  

stefano

     

安格拉

第二个文件:

  

朱塞佩

     

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 :(得分:0)

您的代码中存在一些问题。但首先,我认为您需要修复最重要的内容

int step = lines/N;

如果您输入的文件少于N行,此处step为0。这是因为linesN都是整数,并且整数除法舍入。

答案 1 :(得分:0)

我不会修复您的代码,但会为您提供帮助。我有些改变 建议:

  • 代替标准的 getlines ,使用 getline (3) 库。
  • fseek(fp, 0 , SEEK_SET)是毫无意义的。
  • char * filename = malloc(sizeof(char)*64)中,请注意 malloc的两个参数都是常量,并且大小是任意的。 如今,静态分配文件名缓冲区是安全的, 在堆栈上或使用 static char filename[PATH_MAX]。 您将要使用limits.h来获取该常数。
  • 类似地,您无需动态分配文件 指针。
  • 代替

    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++