2014-11-04 65 views
1

我有一个包含文件格式一样多的客户记录:检查下一行

CUSTOMER ... 
details... 
details... 
CUSTOMER... 
details... 
details... 
details... 
CUSTOMER... 
. 
. 

我需要将文件分割成两个。目前,我将文件中的所有行数除以2,然后检查该行是否以字符串CUSTOMER开头。

如果是这样,我如何才能在客户面前打印所有行?

如果没有,我怎么能检查,如果下一行与CUSTOMER开始?

我的代码:

int main(int argc, char *argv[]) 
{ 
    char ioarea[1000]; 
    int TotCustLines=0,i=0; 

    int reqLine=0; 
    int getLine=0; 

    if((inFile=fopen(argv[inFileName],"r"))==NULL) 
     printf("Failed to open input file"); 

    while(fgets(ioarea,BUFFER_SIZE,inFile)) 
    { 
     TotCustLines++; 
    } 
} 
if(TotCustLines/2==0) 
    reqLine=(TotCustLines/2); 
else 
    reqLine=(TotCustLines/2)+1; 
fseek(inFile,1,SEEK_SET); 
while(fgets(ioarea,BUFFER_SIZE,inFile)) 
{ 
    getLine++; 
    if(getLine==reqLine) 
    { 
     if(strncmp(getLine,"CUSTOMER RECORD",15)==0) 
     //How to write all the lines before customer record. 
     //If not how can i check next line. 
    } 
} 

请提出一个解决方案。我对C文件概念很陌生。

+1

缩进您的代码 – 2014-11-04 15:21:38

+0

'if(strncmp(getLine,“CUSTOMER RECORD”,15)== 0)' - >'if(strcmp(ioarea,“CUSTOMER RECORD \ n”)== 0)' – chux 2014-11-04 15:23:31

+0

你想创建2个新文件,并删除原始文件? – anatolyg 2014-11-04 16:47:31

回答

0

的方法,你可以用它来读取文件,然后通过对客户(或其他任何东西),导致线路搜索:

1)获取文件大小(用fseek()/ftell()),或使用例如1得到线数量和最长的线。
2)创建和字符串数组分配内存,char **buffer;例2
3)使用fgets(),通过buffer[index]索引你去读取文件到阵列。
4)数组缓冲区[]现在包含指数的文件中的行数。

您现在可以使用strstr()字符串比较函数在您存储的行中查找CUSTOMER。

实施例1种获得途径在文件中的行数,和长度最长行(用于创建存储器)

int cnt=0; 
int len=0; 
int keep=0; 
char line[260];// == MAX_PATH_LEN in windows, pick longer value if needed. 
while(fgets(line, 260, fp))//get each line in file 
{    
    len = strlen(line);//track length of each new line 
    if(len > keep) keep = len;//keep only longest line 
    cnt++;      
} //keep will have value for longest line, cnt will have number of lines 

实施例2对于C字符串数组创建存储器( char **string;):

注意: ex充足的调用函数创建和调用:

char **variable = {0}; 
int cnt, maxlen; 
variable = allocMemoryStr(variable, &cnt, &maxlen); 

........

char ** allocMemoryStr(char **strings, int numStrings, int maxLen) 
{ 
    int i; 
    strings = calloc(numStrings, sizeof(char*));// create pointers to arrays 
    for(i=0;i<numStrings; i++) 
    { 
     strings[i] = calloc(maxLen + 1, sizeof(char));// create memory for each array 
    } 
    return strings; 
} 
0

一种解决方案是使用临时文件中写入修改后的数据。

1) Read old file line by line 
2) Check (using strncmp())/modify data 
3) Write modified data to a new temp file 
4) After completing all the modification, simply replace temp file with your old file (using rename()). 

另一种更好的解决方案是使用一个库,如“标准函数库”,将数据存储在形式:

[CUSTOMER_ID] 
    Info1 = value1 
    Infon = "value n" 

看到http://legacy.imatix.com/html/sfl/index.htm为“标准函数库”

0

不可能将所有行写入选定的行;至少不是直接的。您的代码必须“执行两次工作”:在确定两个输出文件中的每个文件中的客户行数之后,它必须重新开始,逐行读取,并将每行输出到所需的文件中。

要计算客户记录:

while(fgets(ioarea,BUFFER_SIZE,inFile)) 
{ 
    if(strncmp(getLine,"CUSTOMER RECORD",15)==0) 
     TotCustLines++; 
} 

然后,打开两个文件写入:

FILE *file1; 
FILE *file2; 
FILE *file_req; 
int customer_counter = 0; 

... 

file1 = fopen("file1.out", "w"); 
file2 = fopen("file2.out", "w"); 
file_req = file1; // start outputting to the first file 

复位输入文件后,再做线路读取和客户计数循环,但这次增加了一些逻辑:

while(fgets(ioarea,BUFFER_SIZE,inFile)) 
{ 
    if(strncmp(getLine,"CUSTOMER RECORD",15)==0) 
     customer_counter++; 
    if (customer_counter == reqLine) 
     file_req = file2; // switch to the second file 
    fputs(ioarea, file_req); // write the line to whatever file it must go to 
} 

一些注意事项:

要从头开始读取文件,请使用rewind。您也可以使用fseek,查找位置为0(注意:不是1)。

rewind(file); // does the same as fseek 

要除以2的数,你并不需要检查它是否是被2整除:

reqLine = (TotCustLines + 1)/2; 

您有宏BUFFER_SIZE,大约决定您所期望的最长行的长度。您也应该将它用于缓冲区声明。如果您决定更改它,缓冲区的大小将自动调整。

char ioarea[BUFFER_SIZE]; 

然而,采用大常数为目的本质上是不安全的(打开你的程序意外的错误和漏洞的黑客),但我猜你不想去想它在这个阶段。