Skip to content

Commit f39945c

Browse files
committed
Bug Fix: utf-8文本读入输出至控制台时乱码
1 parent 9ca22e1 commit f39945c

File tree

3 files changed

+69
-71
lines changed

3 files changed

+69
-71
lines changed

cli/main.c

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ int main(const int argc, char* argv[]) {
3737
if (args.input != stdin) { fclose(args.input); }
3838
if (args.output != stdout) {
3939
fclose(args.output);
40-
// if (args.utf8Text) { convertGbkToUtf8(args.output); }
4140
}
4241
return 0;
4342
}
@@ -61,7 +60,7 @@ struct CommandLineArgs parseCommandLineArgs(int argc, char* argv[]) {
6160
if (strcmp(argv[i], "--output") == 0 || strcmp(argv[i], "-of") == 0) {
6261
// 指定输出流
6362
if (i + 1 < argc) {
64-
printf("Output: %s\n", argv[i + 1]);
63+
puts("Output: ");puts(argv[i + 1]); puts("\n");
6564
args.output = fopen(argv[i + 1], "w");
6665
// args.outputFilePath = argv[i + 1];
6766
if (args.output == NULL) {
@@ -71,7 +70,7 @@ struct CommandLineArgs parseCommandLineArgs(int argc, char* argv[]) {
7170
i++; // 跳过下一个参数,因为它是文件路径
7271
}
7372
else {
74-
fprintf(stderr, "Error: --output option requires a file path.\n");
73+
fputs("Error: --output option requires a file path.\n", stderr);
7574
exit(EXIT_FAILURE);
7675
}
7776
}
@@ -94,14 +93,14 @@ struct CommandLineArgs parseCommandLineArgs(int argc, char* argv[]) {
9493
i++; // 跳过下一个参数,因为它是文件路径
9594
}
9695
else {
97-
fprintf(stderr, "Error: --input option requires a file path.\n");
96+
fputs("Error: --input option requires a file path.\n", stderr);
9897
exit(EXIT_FAILURE);
9998
}
10099
}
101100
else if (strcmp(argv[i], "--compress") == 0 || strcmp(argv[i], "-c") == 0) {
102101
// 压缩格式输出Json
103102
if (formatSeen) {
104-
fprintf(stderr, "Error: --compress and --format cannot be used together.\n");
103+
fputs("Error: --compress and --format cannot be used together.\n", stderr);
105104
exit(EXIT_FAILURE);
106105
}
107106
args.compress = 1;
@@ -111,30 +110,36 @@ struct CommandLineArgs parseCommandLineArgs(int argc, char* argv[]) {
111110
else if (strcmp(argv[i], "--format") == 0 || strcmp(argv[i], "-f") == 0) {
112111
// 格式化输出Json
113112
if (compressSeen) {
114-
fprintf(stderr, "Error: --compress and --format cannot be used together.\n");
113+
fputs("Error: --compress and --format cannot be used together.\n", stderr);
115114
exit(EXIT_FAILURE);
116115
}
117116
args.format = 1;
118117
formatSeen = 1;
119118
}
119+
else if (strcmp(argv[i], "--utf") == 0 || strcmp(argv[i], "-u") == 0) {
120+
// 本地字符集设置为 UTF-8
121+
setlocale(LC_ALL, "zh_CN.UTF-8");
122+
}
120123
else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
121-
printf("用法:json [选项]...\n");
122-
printf("从输入中解析和格式化JSON数据,可选择压缩或格式化输出。\n\n");
124+
setlocale(LC_ALL, "zh_CN.UTF-8");
125+
puts("用法:json [选项]...\n");
126+
puts("从输入中解析和格式化JSON数据,可选择压缩或格式化输出。\n\n");
123127

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");
128+
puts("长选项的强制性参数对于短选项也是强制性的。\n");
129+
puts(" -if, --input 指定输入文件(默认为标准输入)\n");
130+
puts(" -of, --output 指定输出文件(默认为标准输出)\n");
131+
puts(" -f, --format 使用树形缩进输出格式化的JSON\n");
132+
puts(" -c, --compress 输出压缩的JSON\n");
133+
puts(" -u, --utf 启用utf-8编码支持\n");
134+
puts(" -h, --help 显示此帮助并退出\n\n");
130135

131-
printf("示例:\n");
132-
printf(" json -if input.json -of output.json -f\n");
133-
printf(" json --input=input.json --output=output.json --compress\n\n");
136+
puts("示例:\n");
137+
puts(" json -if input.json -of output.json -f\n");
138+
puts(" json --input=input.json --output=output.json --compress\n\n");
134139

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

137-
printf("注意:--compress 和 --format 选项不能同时使用。\n");
142+
puts("注意:--compress 和 --format 选项不能同时使用。\n");
138143
exit(0);
139144
}
140145
else {

core/parser/parser.c

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ void setInputStream(FILE* stream) { f = stream; }
99
void ignoreWhiteCharactor() {
1010
char c;
1111
while ((c = fgetc(f)) != EOF && (c == ' ' || c == '\r' || c == '\n' || c == '\t'));
12-
if (!(c == ' ' || c == '\r' || c == '\n' || c == '\t' || c == EOF)) { ungetc(c, f); }
12+
if (!(c == ' ' || c == '\r' || c == '\n' || c == '\t' || c == EOF)) ungetc(c, f);
1313
}
1414

1515

@@ -132,15 +132,21 @@ struct JsonVal* parseNumber() {
132132
exit(1);
133133
}
134134
ungetc(c, f);
135-
res->type = NUMBER;
136-
res->val = str;
135+
res->type = NUMBER; res->val = str;
137136
return res;
138137
}
139138

140139
struct JsonVal* parseBool() {
141140
char c;
142141
// true or false
142+
struct JsonVal* res = malloc(sizeof(struct JsonVal));
143+
if (res == NULL) {
144+
// 内存分配失败 OOM (?)
145+
// 异常退出, OS进行内存回收
146+
exit(1);
147+
}
143148

149+
res->type = BOOL;
144150
if ((c = fgetc(f)) == 't' || c == 'T') {
145151
// true
146152
const char trueStr[] = "true";
@@ -165,16 +171,7 @@ struct JsonVal* parseBool() {
165171
exit(1);
166172
}
167173
ungetc(c, f);
168-
struct JsonVal* res = malloc(sizeof(struct JsonVal));
169-
if (res == NULL) {
170-
// 内存分配失败 OOM (?)
171-
// 异常退出, OS进行内存回收
172-
exit(1);
173-
}
174-
175-
res->type = BOOL;
176174
res->val = JsonStringFromCharArray("true");
177-
return res;
178175
}
179176
else if (c == 'f' || c == 'F') {
180177
// false
@@ -206,9 +203,7 @@ struct JsonVal* parseBool() {
206203
// 异常退出, OS进行内存回收
207204
exit(1);
208205
}
209-
res->type = BOOL;
210206
res->val = JsonStringFromCharArray("false");
211-
return res;
212207
}
213208
else {
214209
fprintf(
@@ -218,6 +213,7 @@ struct JsonVal* parseBool() {
218213
); // 写入报错到标准错误流
219214
exit(1);
220215
}
216+
return res;
221217
}
222218

223219

@@ -321,7 +317,6 @@ struct JsonVal* parseNull() {
321317
// 异常退出, OS进行内存回收
322318
exit(1);
323319
}
324-
res->type = BOOL;
325-
res->val = JsonStringFromCharArray("false");
320+
res->type = NONE; res->val = NULL;
326321
return res;
327322
}

core/utils/outputer.c

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -55,72 +55,70 @@ void printJsonVal(const struct JsonVal* val) {
5555
}
5656

5757
void printString(const struct JsonString* str) {
58-
if (!str->length) {
59-
fprintf(f, "\"\"");
60-
}
61-
else {
62-
fprintf(f, "\"");
63-
for(int i = 0; i < str->length; i++) {
64-
if(str->str[i] == '\n') fprintf(f, "\\n");
65-
else if (str->str[i] == '\t') fprintf(f, "\\t");
66-
else if (str->str[i] == '\r')fprintf(f, "\\r");
67-
else if (str->str[i] == '"')fprintf(f, "\\\"");
68-
else if (str->str[i] == '\'')fprintf(f, "\\'");
69-
else fprintf(f, "%c", str->str[i]);
70-
}
71-
fprintf(f, "\"");
58+
fputc('"', f);
59+
char * reader = str->str;
60+
while (*reader) {
61+
if (*reader == '\n') fputs("\\n", f);
62+
else if (*reader == '\t') fputs("\\t", f);
63+
else if (*reader == '\r') fputs("\\r", f);
64+
else if (*reader == '"') fputs("\\\"", f);
65+
else if (*reader == '\'') fputs("\\'", f);
66+
else fputc(*reader, f);
67+
68+
reader++;
7269
}
70+
71+
fputc('"', f);
7372
}
7473

7574
void printfObject(const struct JsonObj* obj, const int hierarchy) {
76-
fprintf(f, "{\n");
75+
fputs("{\n", f);
7776
for (int i = 0; i < obj->size; i++) {
78-
indent(hierarchy + 1);
79-
printString(obj->key + i); fprintf(f, ": ");
80-
printfJsonVal((obj->value + i), hierarchy + 1);
81-
if (i != obj->size - 1) fprintf(f, ",");
82-
fprintf(f, "\n");
77+
indent(hierarchy + 1); printString(obj->key + i);
78+
fputs(": ", f); printfJsonVal(obj->value + i, hierarchy + 1);
79+
if (i != obj->size - 1) fputs(",", f);
80+
fputs("\n", f);
8381
}
84-
indent(hierarchy); fprintf(f, "}");
82+
indent(hierarchy); fputs("}", f);
8583
}
8684

8785

8886

8987
void printfArray(const struct JsonArray* array, int hierarchy) {
90-
fprintf(f, "[\n");
88+
fputs("[\n", f);
9189
for (int i = 0; i < array->length; i++) {
92-
indent(hierarchy + 1);
93-
printfJsonVal(&((array->arr)[i]), hierarchy + 1);
94-
if (i != array->length - 1) fprintf(f, ","); fprintf(f, "\n");
90+
indent(hierarchy + 1); printfJsonVal(&array->arr[i], hierarchy + 1);
91+
if (i != array->length - 1) fputs(",", f);
92+
fputs("\n", f);
9593
}
96-
indent(hierarchy); fprintf(f, "]");
94+
indent(hierarchy); fputs("]", f);
9795
}
9896

9997

10098
void printNumber(const struct JsonString* num) {
101-
fprintf(f, "%s", num->str);
99+
fputs(num->str, f);
102100
}
103101

104102
void printBool(const struct JsonString* bl) {
105-
fprintf(f, "%s", bl->str);
103+
fputs(bl->str, f);
106104
}
107105

108106
void printNONE() {
109-
fprintf(f, "Null");
107+
fputs("null", f);
110108
}
111109

112110
void printObject(const struct JsonObj* obj){
113-
fprintf(f, "{");
111+
fputc('{', f);
114112
for (int i = 0; i < obj->size; i++) {
115-
printString(obj->key + i); fprintf(f, ":");
113+
printString(obj->key + i); putc(':', f);
116114
printJsonVal(obj->value + i);
117-
if (i != obj->size - 1) fprintf(f, ",");
118-
} fprintf(f, "}");
115+
if (i != obj->size - 1) fputc(',', f);
116+
} fputc('}', f);
119117
}
120118
void printArray(const struct JsonArray* array){
121-
fprintf(f, "[");
119+
fputc('[', f);
122120
for (int i = 0; i < array->length; i++) {
123121
printJsonVal(array->arr + i);
124-
if (i != array->length - 1) fprintf(f, ",");
125-
}fprintf(f, "]");
122+
if (i != array->length - 1) fputc(',', f);
123+
}fputc(']', f);
126124
}

0 commit comments

Comments
 (0)