Skip to content

Commit de9825a

Browse files
committed
回滚 暂时移除对UTF-8文本支持
1 parent 32461df commit de9825a

File tree

8 files changed

+95
-96
lines changed

8 files changed

+95
-96
lines changed

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
.vs/
2+
.idea/
23
x64/
34
cmake-build-debug/
4-
*.pdb.idea/
55
cmake-build-release/
66
cmake-build-debug-mingw/
7+
*.pdb
8+
9+
lcui-quick-start.zip
10+
package-lock.json
11+
-g/

.idea/vcs.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 3.27)
22

33
PROJECT(JsonParser C)
44
set(CMAKE_C_STANDARD 17)
5+
6+
find_package(Iconv REQUIRED)
7+
58
add_library(jsonParserLib
69
core/Json.h
710
core/parser/parser.h
@@ -19,7 +22,7 @@ add_library(jsonParserLib
1922
core/utils/utf2gbk/UTF2GBK.c
2023
core/utils/utf2gbk/UTF2GBK.h
2124
)
22-
target_link_libraries(jsonParserLib PRIVATE iconv)
25+
target_link_libraries(jsonParserLib PRIVATE Iconv::Iconv)
2326

2427
add_executable(json
2528
cli/main.c

cli/main.c

Lines changed: 54 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -6,109 +6,100 @@
66
#include "Json.h"
77

88

9-
// 结构体用于存储命令行参数的值
9+
// 结构体用于存储命令行参数的值
1010
struct CommandLineArgs {
11-
FILE* input; // 输入流
12-
FILE* output; // 输出流
13-
int compress; // 是否压缩
14-
int format; // 是否格式化
15-
int utf8Text; // 是否为utf-8 文本 是则需资源回收时删除中间文件
16-
char* convertCacheFilePath; // 为utf-8文本时转换为gbk格式时生成的临时文件
17-
char* outputFilePath; // 需要输出文件路径, 当为utf-8文本时用于转换回utf-8文本
18-
11+
FILE* input; // 输入流
12+
FILE* output; // 输出流
13+
int compress; // 是否压缩
14+
int format; // 是否格式化
15+
// int utf8Text; // 是否为utf-8 文本 是则需资源回收时删除中间文件
16+
// char* convertCacheFilePath; // 为utf-8文本时转换为gbk格式时生成的临时文件
17+
// char* outputFilePath; // 需要输出文件路径, 当为utf-8文本时用于转换回utf-8文本
1918
};
2019

21-
// 函数声明
20+
// 函数声明
2221
struct CommandLineArgs parseCommandLineArgs(int argc, char* argv[]);
2322

2423
int main(const int argc, char* argv[]) {
25-
// setlocale(LC_ALL, ""); // 设置本地化环境以支持宽字符
24+
// setlocale(LC_ALL, ""); // 设置本地化环境以支持宽字符
2625
const struct CommandLineArgs args = parseCommandLineArgs(argc, argv);
27-
// 设置输入输出流
28-
// 默认为标准输入输出
26+
// 设置输入输出流
27+
// 默认为标准输入输出
2928
setInputStream(args.input);
30-
setOutputStream(args.output);
31-
32-
//解析Json
29+
setOutputStream(args.output);
30+
31+
//解析Json
3332
const struct JsonVal* json = parseValue();
34-
if (args.compress) {
35-
printJsonVal(json);
36-
}
37-
else if (args.format) {
38-
printfJsonVal(json, 0);
39-
}
33+
if (args.compress) { printJsonVal(json); }
34+
else if (args.format) { printfJsonVal(json, 0); }
4035

4136
//destoryJsonVal(json);
42-
if (args.input != stdin) {
43-
fclose(args.input);
44-
}
37+
if (args.input != stdin) { fclose(args.input); }
4538
if (args.output != stdout) {
4639
fclose(args.output);
47-
if(args.utf8Text) {
48-
convertGbkToUtf8(args.output);
49-
}
40+
// if (args.utf8Text) { convertGbkToUtf8(args.output); }
5041
}
51-
return 0;
42+
return 0;
5243
}
5344

54-
// 函数定义:解析命令行参数
45+
// 函数定义:解析命令行参数
5546
struct CommandLineArgs parseCommandLineArgs(int argc, char* argv[]) {
5647
struct CommandLineArgs args;
5748

58-
// 初始化结构体成员
49+
// 初始化结构体成员
5950
args.input = stdin;
6051
args.output = stdout;
6152
args.compress = 0;
6253
args.format = 1;
63-
args.utf8Text = 0;
64-
args.convertCacheFilePath = "";
65-
// 标记是否已经出现了--format或--compress
54+
// args.utf8Text = 0;
55+
// args.convertCacheFilePath = "__cache.json";
56+
// 标记是否已经出现了--format或--compress
6657
int formatSeen = 0;
6758
int compressSeen = 0;
68-
// 解析命令行参数
59+
// 解析命令行参数
6960
for (int i = 1; i < argc; ++i) {
7061
if (strcmp(argv[i], "--output") == 0 || strcmp(argv[i], "-of") == 0) {
71-
// 指定输出流
62+
// 指定输出流
7263
if (i + 1 < argc) {
7364
printf("Output: %s\n", argv[i + 1]);
7465
args.output = fopen(argv[i + 1], "w");
75-
args.outputFilePath = argv[i+1];
66+
// args.outputFilePath = argv[i + 1];
7667
if (args.output == NULL) {
7768
perror("Error opening output file");
7869
exit(EXIT_FAILURE);
7970
}
80-
i++; // 跳过下一个参数,因为它是文件路径
71+
i++; // 跳过下一个参数,因为它是文件路径
8172
}
8273
else {
8374
fprintf(stderr, "Error: --output option requires a file path.\n");
8475
exit(EXIT_FAILURE);
8576
}
8677
}
8778
else if (strcmp(argv[i], "--input") == 0 || strcmp(argv[i], "-if") == 0) {
88-
// 指定输入流
79+
// 指定输入流
8980
if (i + 1 < argc) {
90-
FILE* f = fopen(argv[i + 1], "r");
91-
args.convertCacheFilePath = "__cache.json";
92-
if(isUtf8(f)) {
93-
printf("INFO: Is UTF-8 Text\n");
94-
args.input = convertUtf8ToGbk(f,args.convertCacheFilePath);
95-
args.utf8Text = 1;
96-
}else {
97-
args.input = fopen(argv[i + 1], "r");
98-
}
81+
args.input = fopen(argv[i + 1], "r");
82+
// FILE* f = fopen(argv[i + 1], "r");
83+
84+
// if (isUtf8(f)) {
85+
// printf("INFO: Is UTF-8 Text\n");
86+
// args.input = convertUtf8ToGbk(f);
87+
// args.utf8Text = 1;
88+
// }
89+
// else { args.input = fopen(argv[i + 1], "r"); }
9990
if (args.input == NULL) {
10091
perror("Error opening input file");
10192
exit(EXIT_FAILURE);
10293
}
103-
i++; // 跳过下一个参数,因为它是文件路径
94+
i++; // 跳过下一个参数,因为它是文件路径
10495
}
10596
else {
10697
fprintf(stderr, "Error: --input option requires a file path.\n");
10798
exit(EXIT_FAILURE);
10899
}
109100
}
110101
else if (strcmp(argv[i], "--compress") == 0 || strcmp(argv[i], "-c") == 0) {
111-
// 压缩格式输出Json
102+
// 压缩格式输出Json
112103
if (formatSeen) {
113104
fprintf(stderr, "Error: --compress and --format cannot be used together.\n");
114105
exit(EXIT_FAILURE);
@@ -118,7 +109,7 @@ struct CommandLineArgs parseCommandLineArgs(int argc, char* argv[]) {
118109
compressSeen = 1;
119110
}
120111
else if (strcmp(argv[i], "--format") == 0 || strcmp(argv[i], "-f") == 0) {
121-
// 格式化输出Json
112+
// 格式化输出Json
122113
if (compressSeen) {
123114
fprintf(stderr, "Error: --compress and --format cannot be used together.\n");
124115
exit(EXIT_FAILURE);
@@ -127,23 +118,23 @@ struct CommandLineArgs parseCommandLineArgs(int argc, char* argv[]) {
127118
formatSeen = 1;
128119
}
129120
else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
130-
printf("用法:json [选项]...\n");
131-
printf("从输入中解析和格式化JSON数据,可选择压缩或格式化输出。\n\n");
121+
printf("用法:json [选项]...\n");
122+
printf("从输入中解析和格式化JSON数据,可选择压缩或格式化输出。\n\n");
132123

133-
printf("长选项的强制性参数对于短选项也是强制性的。\n");
134-
printf(" -if, --input 指定输入文件(默认为标准输入)\n");
135-
printf(" -of, --output 指定输出文件(默认为标准输出)\n");
136-
printf(" -f, --format 使用树形缩进输出格式化的JSON\n");
137-
printf(" -c, --compress 输出压缩的JSON\n");
138-
printf(" -h, --help 显示此帮助并退出\n\n");
124+
printf("长选项的强制性参数对于短选项也是强制性的。\n");
125+
printf(" -if, --input 指定输入文件(默认为标准输入)\n");
126+
printf(" -of, --output 指定输出文件(默认为标准输出)\n");
127+
printf(" -f, --format 使用树形缩进输出格式化的JSON\n");
128+
printf(" -c, --compress 输出压缩的JSON\n");
129+
printf(" -h, --help 显示此帮助并退出\n\n");
139130

140-
printf("示例:\n");
131+
printf("示例:\n");
141132
printf(" json -if input.json -of output.json -f\n");
142133
printf(" json --input=input.json --output=output.json --compress\n\n");
143134

144-
printf("如果未指定输入或输出文件,则程序将默认使用标准输入或标准输出。\n\n");
135+
printf("如果未指定输入或输出文件,则程序将默认使用标准输入或标准输出。\n\n");
145136

146-
printf("注意:--compress 和 --format 选项不能同时使用。\n");
137+
printf("注意:--compress 和 --format 选项不能同时使用。\n");
147138
exit(0);
148139
}
149140
else {
@@ -153,4 +144,4 @@ struct CommandLineArgs parseCommandLineArgs(int argc, char* argv[]) {
153144
}
154145

155146
return args;
156-
}
147+
}

core/parser/parser.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ struct JsonVal* parseValue() {
3030
ungetc(c, f);
3131
return parseNumber();
3232
}
33-
if (c == '"' || c == '\'') return parseString();
33+
if (c == '"' || c == '\'') return parseString(c);
3434
fprintf(
3535
stderr,
3636
"Unexcepted token %c at %llu",
@@ -39,12 +39,12 @@ struct JsonVal* parseValue() {
3939
exit(1);
4040
}
4141

42-
struct JsonString* parseStringToStr() {
42+
struct JsonString* parseStringToStr(char token) {
4343
char c;
4444
struct JsonString* str = JsonString_New();
4545
const size_t pos = ftell(f) / sizeof(char);
4646

47-
while ((c = fgetc(f)) && c != EOF && c != '"' && c != '\'') {
47+
while ((c = fgetc(f)) && c != EOF && c != token) {
4848
if (c == '\\') {
4949
c = fgetc(f);
5050
if (c == EOF) {
@@ -75,15 +75,15 @@ struct JsonString* parseStringToStr() {
7575
else { JsonStringPushBackChar(c, str); }
7676
}
7777

78-
if (c != '"' && c != '\'') {
79-
fprintf(stderr, "Expected character \" or ', but got EOF.\tString value parse begin with %llu\n", pos);
78+
if (c != token) {
79+
fprintf(stderr, "Expected character %c, but got EOF.\tString value parse begin with %llu\n", token, pos);
8080
exit(1);
8181
}
8282
return str;
8383
}
8484

85-
struct JsonVal* parseString() {
86-
struct JsonString* str = parseStringToStr();
85+
struct JsonVal* parseString(char token) {
86+
struct JsonString* str = parseStringToStr(token);
8787

8888
struct JsonVal* res = malloc(sizeof(struct JsonVal));
8989
if (res == NULL) {
@@ -234,7 +234,7 @@ struct JsonVal* parseObject() {
234234

235235
while ((c = fgetc(f)) != EOF && c != '}') {
236236
if (c == ' ' || c == '\n' || c == '\r' || c == ',') continue;
237-
if (c == '"' || c == '\'') keyVal = parseStringToStr();
237+
if (c == '"' || c == '\'') keyVal = parseStringToStr(c);
238238

239239
else if (c == ':') {
240240
const struct JsonVal* Val = parseValue();

core/parser/parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44

55
void setInputStream(FILE* stream);
6-
struct JsonVal* parseString();
6+
struct JsonVal* parseString(char token);
77
struct JsonVal* parseNumber();
88
struct JsonVal* parseBool();
99
struct JsonVal* parseNull();

core/utils/utf2gbk/UTF2GBK.c

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1+
#define _POSIX_C_SOURCE 200112L
2+
13
#include <stdio.h>
24
#include <stdlib.h>
35
#include <string.h>
46
#include <iconv.h>
7+
#include <unistd.h>
8+
9+
#define BUFFER_SIZE 4096
510

6-
FILE* convertUtf8ToGbk(FILE* input, const char* outputFileName) {
11+
FILE* convertUtf8ToGbk(FILE* input) {
712
iconv_t cd;
13+
FILE* output = tmpfile();
814
cd = iconv_open("GBK", "UTF-8");
915
if (cd == (iconv_t)-1) {
1016
perror("iconv_open");
1117
exit(EXIT_FAILURE);
1218
}
13-
14-
FILE* output = fopen(outputFileName, "w");
1519
if (output == NULL) {
1620
perror("fopen");
1721
exit(EXIT_FAILURE);
@@ -39,9 +43,9 @@ FILE* convertUtf8ToGbk(FILE* input, const char* outputFileName) {
3943

4044
iconv_close(cd);
4145
fclose(input);
42-
fclose(output);
46+
rewind(output);
4347

44-
return fopen(outputFileName, "r");
48+
return output;
4549
}
4650

4751
void convertGbkToUtf8(FILE* file) {
@@ -92,9 +96,9 @@ void convertGbkToUtf8(FILE* file) {
9296
iconv_close(cd);
9397

9498
// Reopen the original file for writing
95-
file = fopen("converted_file.txt", "w");
99+
file = freopen("converted_file.txt", "w", stdout);
96100
if (file == NULL) {
97-
perror("fopen");
101+
perror("freopen");
98102
exit(EXIT_FAILURE);
99103
}
100104

@@ -109,26 +113,21 @@ void convertGbkToUtf8(FILE* file) {
109113

110114

111115
int isUtf8(FILE* file) {
112-
rewind(file); // 将文件指针定位到文件开头
113-
116+
// 获取当前文件指针位置
117+
long originalPosition = ftell(file);
118+
int res = 0;
114119
// 读取文件的前三个字节
115120
char bom[3];
116121
size_t bytesRead = fread(bom, 1, 3, file);
117-
118-
// 如果文件小于3个字节,返回0
119-
if (bytesRead < 3) {
120-
rewind(file);
121-
return 0;
122-
}
122+
fseek(file, originalPosition, SEEK_SET);
123+
fwrite(bom, 1, bytesRead, file);
123124

124125
// 判断是否为UTF-8 without BOM编码
125126
if (bom[0] == (char)0xEF && bom[1] == (char)0xBB && bom[2] == (char)0xBF) {
126127
// 文件包含BOM,不是UTF-8 without BOM编码
127-
rewind(file);
128-
return 0;
128+
res = 0;
129129
} else {
130-
// 文件不包含BOM,可能是UTF-8 without BOM编码
131-
rewind(file);
132-
return 1;
130+
res = 1;
133131
}
134-
}
132+
return res;
133+
}

core/utils/utf2gbk/UTF2GBK.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
#pragma once
55
#include <stdio.h>
66

7-
FILE* convertUtf8ToGbk(FILE* input, const char* outputFileName);
7+
FILE* convertUtf8ToGbk(FILE* input);
88
void convertGbkToUtf8(FILE* input);
99
int isUtf8(FILE* file);

0 commit comments

Comments
 (0)