У меня есть 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}
( source ):
[ziga@localhost ~]$ file components.csv
components.csv: ISO-8859 text, with very long lines, with CRLF line terminators
Если я читаю этот файл напрямую, используя cat
и ограничиваю вывод первой парой строк, используя head
, я вижу первый неизвестный символ �
. Это ожидается, поскольку система в UTF-8
может обрабатывать ASCII
символов, но не расширена ASCII
символов ( source ), где, вероятно, �
принадлежит:
[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
Но теперь я преобразую кодировку файла и создам новую файл components-utf8.csv в 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;
}