我需要做的是获取一个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);
}
答案 0 :(得分:0)
您的代码中存在一些问题。但首先,我认为您需要修复最重要的内容
int step = lines/N;
如果您输入的文件少于N行,此处step
为0。这是因为lines
和N
都是整数,并且整数除法舍入。
答案 1 :(得分:0)
我不会修复您的代码,但会为您提供帮助。我有些改变 建议:
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)
最后,您的递归 Split 是-我们怎么说呢? - 一个噩梦。您的整个程序 应该是这样的:
open input
while getline input
if nlines % N == 0
create output filename with 1 + n/N
open output
write output
nlines++