我有一个C程序test.elf,它应该处理UTF-8编码的文件,并在UTF-8系统的终端中打印它。现在有人给了我一个文件components.csv,它是ISO-8859-1编码的。我遇到了一些问题。
我的系统的编码可以在终端中签入,它确实是UTF-8
[ziga@localhost ~]$ echo $LANG
en_US.UTF-8我还可以检查或猜测(!)文件的编码,这是ISO-8859-{1,2,3,4,5,6,7,8,9,10,11,13,14,15} (来源)之一:
[ziga@localhost ~]$ file components.csv
components.csv: ISO-8859 text, with very long lines, with CRLF line terminators如果我直接使用cat读取这个文件,并将输出限制在使用head的前几行,我将看到第一个未知字符�。这是预期的,因为系统在UTF-8中可以处理ASCII字符,但不能处理扩展ASCII字符(来源),而�可能属于:
[ziga@localhost ~]$ cat components.csv | head -n4
id_articolo,codice,descrizione,esistenza,disponibilita,qta_rim_iniziale,qta_caricata,qta_scaricata,qta_ord_clienti,qta_ord_fornitori,val_rim_iniziale,val_caricato,val_scaricato,ultimo_costo,c_scorta_min,c_cod_fornitore,c_des_fornitore,c_prd_qta_avanz,c_prd_qta_wip,prezzo_listino,codice,qta_altri_carichi,qta_altri_scarichi
41,15MQ040N,Diodo schottky 3A 40V SMA,6755,0000,6755,0000,6755,0000,0,0,0,0,0,0,0,0,0,,,0,0,0,NR,0,0
49,24LC256-I/SN,Memoria flash 8 pin SOIC-8 256kbit,22,0000,22,0000,22,0000,0,0,0,0,16,0600,0,0,0,0,57010035,EBV Elektronik,0,0,0,NR,0,0
2156,24LC512-I/SN,"Memoria EEPROM I2C 64kx8bit 2,5�5,5V 400kHz SOIC8",92,0000,92,0000,92,0000,0,0,0,0,50,6000,0,0,0,0,57010274,GSE s.r.l.,0,0,0,NR,0,0现在,如果我用我的程序直接处理这个文件,程序将以这个精确的字符结束它的执行,这也是预期的:
[ziga@localhost ~]$ ./test.elf components.csv a
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
1:
Commencing import procedure of file "components.csv" into SQLite database "a".
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
2:
CSV file "components.csv" found.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
3:
Printing inputed file "components.csv":
id_articolo,codice,descrizione,esistenza,disponibilita,qta_rim_iniziale,qta_caricata,qta_scaricata,qta_ord_clienti,qta_ord_fornitori,val_rim_iniziale,val_caricato,val_scaricato,ultimo_costo,c_scorta_min,c_cod_fornitore,c_des_fornitore,c_prd_qta_avanz,c_prd_qta_wip,prezzo_listino,codice,qta_altri_carichi,qta_altri_scarichi
41,15MQ040N,Diodo schottky 3A 40V SMA,6755,0000,6755,0000,6755,0000,0,0,0,0,0,0,0,0,0,,,0,0,0,NR,0,0
49,24LC256-I/SN,Memoria flash 8 pin SOIC-8 256kbit,22,0000,22,0000,22,0000,0,0,0,0,16,0600,0,0,0,0,57010035,EBV Elektronik,0,0,0,NR,0,0
2156,24LC512-I/SN,"Memoria EEPROM I2C 64kx8bit 2,5但是现在,我将转换文件的编码,并以UTF-8编码创建一个新的文件UTF-8。对于每个ISO-8859-{1,2,3,4,5,6,7,8,9,10,11,13,14,15}编码,我多次尝试了这个过程,下面的解决方案得到了最好的结果:
iconv -f ISO-8859-1 -t UTF-8 components.csv > components-utf8.csv如果我使用cat和head处理新文件,未知字符现在呈现为÷:
[ziga@localhost ~]$ cat components-utf8.csv | head -n4
id_articolo,codice,descrizione,esistenza,disponibilita,qta_rim_iniziale,qta_caricata,qta_scaricata,qta_ord_clienti,qta_ord_fornitori,val_rim_iniziale,val_caricato,val_scaricato,ultimo_costo,c_scorta_min,c_cod_fornitore,c_des_fornitore,c_prd_qta_avanz,c_prd_qta_wip,prezzo_listino,codice,qta_altri_carichi,qta_altri_scarichi
41,15MQ040N,Diodo schottky 3A 40V SMA,6755,0000,6755,0000,6755,0000,0,0,0,0,0,0,0,0,0,,,0,0,0,NR,0,0
49,24LC256-I/SN,Memoria flash 8 pin SOIC-8 256kbit,22,0000,22,0000,22,0000,0,0,0,0,16,0600,0,0,0,0,57010035,EBV Elektronik,0,0,0,NR,0,0
2156,24LC512-I/SN,"Memoria EEPROM I2C 64kx8bit 2,5÷5,5V 400kHz SOIC8",92,0000,92,0000,92,0000,0,0,0,0,50,6000,0,0,0,0,57010274,GSE s.r.l.,0,0,0,NR,0,0如果我用我的程序处理新文件,它从一开始一直执行到结束(这里我只粘贴前几行),但将÷呈现为?:
[ziga@localhost ~]$ ./test.elf components-utf8.csv a
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
1:
Commencing import procedure of file "components-utf8.csv" into SQLite database "a".
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
2:
CSV file "components-utf8.csv" found.
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
3:
Printing inputed file "components-utf8.csv":
id_articolo,codice,descrizione,esistenza,disponibilita,qta_rim_iniziale,qta_caricata,qta_scaricata,qta_ord_clienti,qta_ord_fornitori,val_rim_iniziale,val_caricato,val_scaricato,ultimo_costo,c_scorta_min,c_cod_fornitore,c_des_fornitore,c_prd_qta_avanz,c_prd_qta_wip,prezzo_listino,codice,qta_altri_carichi,qta_altri_scarichi
41,15MQ040N,Diodo schottky 3A 40V SMA,6755,0000,6755,0000,6755,0000,0,0,0,0,0,0,0,0,0,,,0,0,0,NR,0,0
49,24LC256-I/SN,Memoria flash 8 pin SOIC-8 256kbit,22,0000,22,0000,22,0000,0,0,0,0,16,0600,0,0,0,0,57010035,EBV Elektronik,0,0,0,NR,0,0
2156,24LC512-I/SN,"Memoria EEPROM I2C 64kx8bit 2,5?5,5V 400kHz SOIC8",92,0000,92,0000,92,0000,0,0,0,0,50,6000,0,0,0,0,57010274,GSE s.r.l.,0,0,0,NR,0,0这对我来说是个误会。特别是因为我的程序将内部编码设置为发送系统的编码,而且我还使用了广泛的打印功能。以下是该程序的源代码:
// Headers:
#include <locale.h>
#include <wchar.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// Function prototypes:
void ruler(void);
// Function definitions:
void ruler(void){
char* r1 = getenv("COLUMNS");
int r2;
if(r1 == NULL){
r2 = 100;
}
else{
r2 = strtol(r1, NULL, 10);
}
int i;
for(i = 0; i < r2; i++){
putwchar(L'―');
}
putwchar(L'\n');
}
// Entry point:
int main(int argc, char** argv){
// Setting the user-perfered locale.
setlocale(LC_ALL, "en_US.UTF-8");
ruler();
// Check if exactly two arguments are passed to the binary
if(argc != 3){
wprintf(L"USAGE:\n\t%s <CSV file in UTF-8 encoding> <database>\n\nHINT:\n\tUse terminal application \"file\" to guess CSV file's encoding and \"iconv\" to transcode it to UTF-8\n", argv[0]);
ruler();
return 1;
}
else{
wprintf(L"1:\n\tCommencing import procedure of file \"%s\" into SQLite database \"%s\".\n", argv[1], argv[2]);
ruler();
}
// Open CSV file
FILE* csv_file = fopen(argv[1], "r");
if(csv_file == NULL){
wprintf(L"2:\n\tCSV file \"%s\" not found.\n", argv[1]);
ruler();
return 1;
}
else{
wprintf(L"2:\n\tCSV file \"%s\" found.\n", argv[1]);
ruler();
}
// Print CSV file
wprintf(L"3:\n\tPrinting inputed file \"%s\":\n\n", argv[1]);
char c = fgetwc(csv_file);
while(c != WEOF){
putwchar(c);
c = fgetwc(csv_file);
}
putwchar(L'\n');
return 0;
}发布于 2020-02-20 07:58:41
您需要使用正确的类型来表示宽字符-- char是不够的。
char c = fgetwc(csv_file);应:
wint_t c = fgetwc(csv_file);根据fgetwc引用。
用于其他用途(如当不处理返回值时,有wchar_t来表示宽字符。
https://stackoverflow.com/questions/60315068
复制相似问题