我的文件包含多个客户记录,格式如下:
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文件概念的新手。
答案 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];
但是,为此目的使用大常量本质上是不安全的(打开程序以应对意外错误和黑客攻击),但我想你不想在这个阶段考虑它。