我需要做的是,取一个n行的文件,每x行,用原始文件的行创建一个新文件。一个例子是:
原始文件:
stefano
angela
朱塞佩
苜蓿
在这种情况下,如果x==2,将创建3个文件,顺序为:
第一个文件:
stefano
angela
第二个FIle:
giuseppe
苜蓿
第三个文件:
洛伦佐
到目前为止我所做的是:
#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 writingn");
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 filen");
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 writingn");
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 filen");
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);
}
您的代码中存在一些问题。但首先我认为你需要解决最重要的问题
int step = lines/N;
如果输入文件的文本少于N行,则step
为0。这是因为lines
和N
都是整数,整数除法是向下取整的。
我不会修复你的代码,但我会帮助你建议:
- 使用标准中的getline(3(图书馆
fseek(fp, 0 , SEEK_SET)
毫无意义- 在
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++