C语言解析文件的几种方法
标准I/O——fopen
fopen通过逐行读的方式读取文件,适用于读取文本文件并且文件比较简单的方式,例如日志文件或者简单的配置文件。
#include <stdio.h>
int main() {
FILE *fp = fopen("test.txt", "r");
if (!fp) {
perror("fopen");
return 1;
}
char line[256];
while (fgets(line, sizeof(line), fp)) {
printf("Line: %s", line);
}
fclose(fp);
return 0;
}
使用文件操作open
open直接打开文件读取,适合二进制文件操作字节类型的数据读取,例如日志、网络协议等类型的文件。
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main() {
int fd = open("data.log", O_RDONLY);
if (fd < 0) {
perror("open");
return 1;
}
unsigned char buf[128];
ssize_t n = read(fd, buf, sizeof(buf));
if (n > 0) {
printf("Read %zd bytes\n", n);
}
close(fd);
return 0;
}
不确定长度的读取
对于不确定内容长度的读取可以使用 getline来操作,首先使用fopen获得FILE,然后使用getline逐行读取。与fgets的区别是这里的len是动态的。
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp = fopen("test.txt", "r");
if (!fp) return 1;
char *line = NULL;
size_t len = 0;
ssize_t read;
while ((read = getline(&line, &len, fp)) != -1) {
printf("Line: %s", line);
}
free(line);
fclose(fp);
return 0;
}
读取大文件
大文件读取就可以使用经典的mmap来操作了,mmap把文件映射到内存直接访问,非常适合高性能读取的场景。
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main() {
int fd = open("test.txt", O_RDONLY);
struct stat st;
fstat(fd, &st);
char *data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (data == MAP_FAILED) {
perror("mmap");
return 1;
}
write(STDOUT_FILENO, data, st.st_size);
munmap(data, st.st_size);
close(fd);
return 0;
}
读取json格式
读取json格式文件可以通过cJSon库来实现。
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
int main() {
FILE *fp = fopen("config.json", "r");
fseek(fp, 0, SEEK_END);
long len = ftell(fp);
rewind(fp);
char *data = malloc(len + 1);
fread(data, 1, len, fp);
data[len] = '\0';
fclose(fp);
cJSON *root = cJSON_Parse(data);
if (!root) {
printf("Error before: %s\n", cJSON_GetErrorPtr());
free(data);
return 1;
}
const cJSON *name = cJSON_GetObjectItemCaseSensitive(root, "name");
if (cJSON_IsString(name) && name->valuestring) {
printf("Name: %s\n", name->valuestring);
}
cJSON_Delete(root);
free(data);
return 0;
}
读取yaml文件
读取yaml文件和解析得用库libyaml来实现,注意在使用前先安装库 sudo apt install libyaml-dev
#include <yaml.h>
#include <stdio.h>
int main() {
FILE *fh = fopen("config.yaml", "r");
yaml_parser_t parser;
yaml_event_t event;
yaml_parser_initialize(&parser);
yaml_parser_set_input_file(&parser, fh);
do {
yaml_parser_parse(&parser, &event);
switch (event.type) {
case YAML_SCALAR_EVENT:
printf("Scalar: %s\n", event.data.scalar.value);
break;
default:
break;
}
if (event.type != YAML_STREAM_END_EVENT)
yaml_event_delete(&event);
} while (event.type != YAML_STREAM_END_EVENT);
yaml_event_delete(&event);
yaml_parser_delete(&parser);
fclose(fh);
return 0;
}