检查下一行

时间:2014-11-04 15:05:24

标签: c file io

我的文件包含多个客户记录,格式如下:

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

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

如果是,如何在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文件概念的新手。

3 个答案:

答案 0 :(得分:0)

您可以使用一种方法来读取文件,然后搜索CUSTOMER(或其他任何内容)的结果行:

1)获取文件大小(使用fseek()/ftell()),或使用示例1 获取行数和最长行。
2)为字符串数组创建和分配内存,char **buffer;参见 example 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;):

注意: 调用函数创建和调用的示例:

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;
}

答案 1 :(得分: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了解标准函数库&#39;

答案 2 :(得分:0)

无法将所有行写到选定的行;至少不是直接的。您的代码必须&#34;做两次工作&#34;:在确定两个输出文件中每个输出文件中的客户行数后,必须重新开始,逐行读取,并将每行输出到所需的文件中

计算客户记录:

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];

但是,为此目的使用大常量本质上是不安全的(打开程序以应对意外错误和黑客攻击),但我想你不想在这个阶段考虑它。