写在最前
阅读文章需要的知识:文件指针 FILE* 。
C语言中也经常需要文件读取,但是怎么读取半结构化的数据,比如csv文件(以逗号分割的文件),网上好像有相应的方法可以直接用,不过比我写的问题还多,于是,自己瞎搞了一个读取这种半结构化数据的函数,当然,也会存在一些问题。这里的逗号分割符也可以根据自己喜好换成其他的。
我怎么读取
直接上代码:
#include <stdio.h>
#include <stdlib.h>
void fun(){
char strLine[1024];//读取一行内容
char item[30];//其中一个字段
int cnt = 0;//其中一个字段的字符偏移量
unsigned i = 0;//遍历strLine
FILE *fp = fopen("books.txt", "r");
while (!feof(fp)){
fgets(strLine, 1024, fp);//读到了一行数据
//对这行数据拆分
for (i = 0; i<strlen(strLine); i++){
if (strLine[i] == ','){//说明已经收集了一个字段,开始赋值,并进行下一个字段的采集
item[cnt] = '\0';//需要手动加一个结束符
printf("%s\t", item);
cnt = 0;
}
else{
item[cnt++] = strLine[i];
}
}
}
fclose(fp);
}
int main(){
fun();
return 0;
}
解读:
用fgets函数读取一行内容并且存在strLine数组中,item用来存放其中一个字段,也就是逗号之前需要拿出来的数据,我们每次只是对一行数据进行拆分。这里需要两个临时变量,i和cnt,i用来遍历整个strLine,cnt用来记录其中一个字段的偏移量。
这里需要思路清晰,最难的是cnt这个变量,定义的时候赋初值为0,这个时候开始读取strLine的内容,如果读到的字符不是",",也就是分割符号,那么直接赋给item,但是下标呢,这里应该是cnt,但是要立马+1,因为下次还要继续往里面添加,所以我这里简写为item[cnt++] = strLine[i],注意每次进行这个操作,item里面存了数据的下标其实只到了cnt-1,这个后面会用到,如果说strLine里碰到了一个",",说明一个字段已经收集完毕了,就可以对这个字段进行处理了,我这里是简单的打印输出。这个时候需要在item的最后面(存了数据的后面)手动赋一个’\0’,但是这个最后在item中的下标是哪个呢?注意前面经常说到,读取完一个字符后,cnt其实指向的是有数据的后面,就是我们需要手动赋值为’\0’的位置,所以这里直接是item[cnt]=’\0。表示这个字符数组的结尾,注意,这里cnt要马上赋值为0,因为还要进行下一个字段的收集了。到这里已经处理完毕了!
不足之处
不能读取汉字,因为char是一个字节,而汉字存储一般是2个字节,这个时候如果强行将这个拆成2个字符来读,显然我们已经不认识了。