Programowanie w systemie UNIX/Kodowanie

Plik tekstowy (ang. text file) –

  • zawartość : tekst: dane w postaci alfanumerycznej. Uwaga są plik zawierające tekst w formie binarnej ( pdf, doc)
  • format pliku:
    • ciąg linii tekstu elektronicznego
    • nie jest plikiem binarnym
    • pozwala na otwarcie w edytorze tekstu

przykładyEdytuj

  • prosty tekst
  • skrypty
  • kody źródłowe programów


BudowaEdytuj

Plik tekstowy:

  • składa się ze znaków (kod znaku),
    • może się rozpoczynać znakiem kolejności bajtów (BOM)
    • może zawierać znaki końca linii (EOL)
    • jest zakończony znakiem końca pliku (EOF)

KodowanieEdytuj

Co każdy programista powinien wiedzieć o

  • kodowaniu wg Davida C. Zentgrafa [1]
  • zestawach znaków wg Joel Spolsky[2]

Kod alfanumerycznyEdytuj

Kod alfanumeryczny (ang. alphanumeric code) – kod, w którym do zapisu tekstów i liczb, przedstawianych jako ciągi cyfr, używa się określonych w danym kodzie znaków Przykładami kodów alfanumerycznych są kody:

  • ASCII
  • UTF-8
  • ISO 8859
  • Unicode ISO 10646
  • EBCDIC
  • Windows-1250.

Niektóre z kodów dopuszczają także kody sterujące, znaki diakrytyczne i znaki specjalne np. Unicode.

DekoderyEdytuj

Dekoder znaków (ang. char) czyli jak sprawdzić znak?


Dekoder plików

TestyEdytuj

Typowe problemyEdytuj

ZnakiEdytuj

 
Najczęściej używane standardy kodowanie występujące w sieci

Znaki z punktu widzenia programisty dzielimy na:

  • drukowalne
  • niedrukowalne

Podział wg znaczenia : [11]

  • litery (ang. letter) (91.8%), podkategorie: duże (uppercase = Lu) , małe (ang. lowercase = Ll), tytułowe (titlecase = Lt), zmodyfikowane ( modifier = Lm)
  • symbole (ang. symbol) : (5.0%), podkategoria: matematyczne (Symbol, math = Sm), zmodyfikowane (modifier = Sk), walutowe (currency = Sc)
  • znaki (Mark) : (1.4%)
  • cyfry (Number): 1,100 (1.0%)
  • Punctuation: 598 (0.5%)
  • inne (Other): 205 (0.2%)
  • Separator: 20 (0.0%)


Klasy znaków ( character classes) wyrażeń regularnych Bash ( Bash Regular Expressions = BRE)[12]

  • [[:alpha:]] - matches any alphabetic character written in upper or lower case.
  • [[:alnum:]]- matches any alphanumeric character - namely, the characters in the range 0-9, A-Z, a-z.
  • [[:blank:]] - matches a space and a tab character.
  • [[:digit:]]- any numeric character from 0to 9.
  • [[:upper:]]- uppercase alphabetic characters - A-Z.
  • [[:lower:]]- alphabetic characters in lower case - a-z.
  • [[:print:]] - matches any printable character.
  • [[:punct:]] - matches punctuation marks.
  • [[:space:]]- whitespace, in particular - a space, a tab character, characters NL, FF, VT, CR.



Podział wg strony kodowej [13]

  • ascii
  • unicode
    • UTF-8




Znaki drukowalneEdytuj

Program[14] drukuje znaki drukowalne ASCII:

// https://en.cppreference.com/w/c/language/ascii
// printtable ASCII
#include <stdio.h>
 
int main(void)
{
    puts("Printable ASCII:");
    for (int i = 32; i < 127; ++i) {
        putchar(i);
        putchar(i % 16 == 15 ? '\n' : ' ');
    }
}


Wynik:

Printable ASCII:
  ! " # $ % & ' ( ) * + , - . /
0 1 2 3 4 5 6 7 8 9 : ; < = > ?
@ A B C D E F G H I J K L M N O
P Q R S T U V W X Y Z [ \ ] ^ _
` a b c d e f g h i j k l m n o
p q r s t u v w x y z { | } ~


Podobne znakiEdytuj

  • ascii '-' ( Hyphen, dash, minus )
  • UTF-8 characters:
    • kod = U+2212 ( MINUS SIGN )
    • kod = U+002D ( HYPHEN-MINUS )
    • kod = U+005F ( LOW LINE )
    • kod = U+00AF ( MACRON )
    • kod = U+2010 ( HYPHEN )
    • kod = u+2011 ( NON-BREAKING HYPHEN )[15]
    • kod = U+2012 ( FIGURE DASH )
    • kod = U+2013 ( EN DASH )
    • kod = U+2014 ( EM DASH )
    • kod = U+268A ( MONOGRAM FOR YANG )


Read Character Unicode ASCII in URL HTML notations
Minus U+2212 %E2%88%92 &minus; &#x2212; &#8722;
Hyphen-minus - U+002D &#45; %2D
Full-width Hyphen-minus U+FF0D %EF%BC%8D &#xff0d; &#65293;

Znaki niedrukowalneEdytuj

  • znaki specjalne [16]


Przykłady:

  • newline character (LF = Line Feed \n, \x0a)[17]


Wyświetlanie znaków niedrukowalnychEdytuj

  • online[18]
  • w konsoli[19] (nazwa pliku przykładowa):


hl-nonprinting () { local C=$(printf '\033[0;36m') B=$(printf '\033[0;46m') R=$(printf '\033[0m') np=$(env printf "\u00A0\uFEFF"); sed -e "s/\t/${C}▹&$R/g" -e "s/$/${C}⁋$R/" -e "s/[$np]/${B}& $R/g";}

lub od = Octal Dump:

od -c p.txt # c same as -t c, select printable characters or backslash escapes
 od -tx1  file # output as a hexadecimal 1-byte units 

lub hexdump:

 hexdump -C file  # tell you byte-for-byte what the file actually contains


lub z użyciem sed[20]

 sed -n 'l' myfile.txt


lub vim


 vi -b myfile.txt

lub otworzyć w LibreOffice Writer i zaznaczyć opcję pokaż Menu/Widok/Znaczniki formatowania[21]

catEdytuj

   cat -t -e p.txt


Formatowanie pliku makefile sprawdzimy za pomocą: [22]

  cat -e -t -v makefile

W wyniku:

  • tabulatory jako ^I
  • końcówki linii jako $

BOMEdytuj

Unicode Byte-Order-Marker (BOM)[23]


Znajdowanie plików z BOM :[24]

grep -rl $'\xEF\xBB\xBF'

lub :

file * | grep UTF

albo znaleźć i usunąć BOM:

find . -type f -exec sed '1s/^\xEF\xBB\xBF//' -i.bak {} \; -exec rm {}.bak \;

lub dos2unix[25]


W c: [26]


// http://unicodebook.readthedocs.org/en/latest/guess_encoding.html
#include <string.h>   /* memcmp() */

const char *UTF_16_BE_BOM = "\xFE\xFF";
const char *UTF_16_LE_BOM = "\xFF\xFE";
const char *UTF_8_BOM = "\xEF\xBB\xBF";
const char *UTF_32_BE_BOM = "\x00\x00\xFE\xFF";
const char *UTF_32_LE_BOM = "\xFF\xFE\x00\x00";

char* check_bom(const char *data, size_t size)
{
    if (size >= 3) {
        if (memcmp(data, UTF_8_BOM, 3) == 0)
            return "UTF-8";
    }
    if (size >= 4) {
        if (memcmp(data, UTF_32_LE_BOM, 4) == 0)
            return "UTF-32-LE";
        if (memcmp(data, UTF_32_BE_BOM, 4) == 0)
            return "UTF-32-BE";
    }
    if (size >= 2) {
        if (memcmp(data, UTF_16_LE_BOM, 2) == 0)
            return "UTF-16-LE";
        if (memcmp(data, UTF_16_BE_BOM, 2) == 0)
            return "UTF-16-BE";
    }
    return NULL;
}


Kodowanie Reprezentacja (hexadecimal) Reprezentacja (decimal) Bajty jako znaki CP1252
UTF-8 EF BB BF 239 187 191 
UTF-16 (BE) FE FF 254 255 þÿ
UTF-16 (LE) FF FE 255 254 ÿþ
UTF-32 (BE) 00 00 FE FF 0 0 254 255 ␀␀þÿ (␀ refers to the ASCII null character)
UTF-32 (LE) FF FE 00 00 255 254 0 0 ÿþ␀␀ (␀ refers to the ASCII null character)
UTF-7 2B 2F 76 38
2B 2F 76 39
2B 2F 76 2B
2B 2F 76 2F

2B 2F 76 38 2D
43 47 118 56
43 47 118 57
43 47 118 43
43 47 118 47
43 47 118 56 45
+/v8
+/v9
+/v+
+/v/
+/v8-
UTF-1 F7 64 4C 247 100 76 ÷dL
UTF-EBCDIC DD 73 66 73 221 115 102 115 Ýsfs
SCSU 0E FE FF 14 254 255 ␎þÿ (␎ represents the ASCII "shift out" character)
BOCU-1 FB EE 28 251 238 40 ûî(
GB-18030 84 31 95 33 132 49 149 51 „1•3



Można go usunąć za pomocą:[27]

sed '1 s/\xEF\xBB\xBF//' < input > output

Dodać:

printf("\xef\xbb\xbf");

String czyli łańcuchy znakówEdytuj

Plik tekstowyEdytuj

Plik tekstowy[28] składa się z linii[29] i kończy się znakiem końca pliku ( EOF )[30].

Linia jest to ciąg znaków[31] (drukowalnych[32] i niedukowalnych[33]) zakończony znakiem końca linii[34]

Linię możemy podzielić na wyrazy rozdzielone spacjami[35]


typy plików tekstowychEdytuj


csvEdytuj

Przykładowy csv[36], który może być zaimportowany do kalendarza:

Subject,Start Date,Start Time,End Date,End Time,All Day,Description
My important event,04/19/2012,6:00pm,04/19/2012,9:00pm,false,Longer Description
An all-day event,04/19/2012,,04/19/2012,,true,Missing times are OK
A multi-day event,04/19/2012,6:00pm,04/20/2012,6:00pm,false,Start date and end date are different

icalEdytuj

Plik iCalendar[37][38] służy do zapisu danych kalendarzy. [39]

  • Pierwszy wiersz w pliku iCalendar zawiera nagłówek = BEGIN: VCALENDAR
  • ostatni wiersz pliku ( stopka) = END:VCALENDAR.
  • Pomiędzy powyższymi wierszami wprowadzane są wydarzenia.
    • wydarzenie musi być ujęte w wiersze BEGIN:VEVENT i END:VEVENT.


BEGIN: VCALENDAR 
BEGIN:VEVENT 
(szczegóły pojedynczego wydarzenia) 
END:VEVENT 
BEGIN:VEVENT 
(szczegóły pojedynczego wydarzenia) 
END:VEVENT 
END:VCALENDAR

biblioteki:

Sygnatura plikuEdytuj

  • sygnatura pliku w wikipedii[42]
  • BOM [43]

Wczytywanie danych z pliku - parserEdytuj

Kodowanie plikuEdytuj

Sprawdzanie za pomocą komendy file ( nazwa pliku i wynik przykładowe) :

file a.txt
a.txt: UTF-8 Unicode (with BOM) text, with very long lines

UTF-8


Za pomocą komendy od :[46]

od -c babymonsterBUM.txt

przykładowy wynik :

0000000 357 273 277   s   i   z   e       2   0   0   0       1   0   0
0000020   0  \n   v   i   e   w       1   5   4       0   .   4   0   2
0000040   6   2   2   3   2   4   2   1   4   1   8   5   2   1   4   8
0000060   0   3   7   8   2   4   7   2   4   5   8   4   0   2   5   8
0000100   3   5   7   5   5   1   3   5   0   1   1   3   4   2   8   8
0000120   1   0   2   7   0   4   2   5   2   5   6   2   7   0   3   9
0000140   5   6   9   5   0   2   8   8   1   6   7   0   9   4   6   7
0000160   4   5   5   5   7   4   1   2   9   3   0   3   2   7   1   1
0000200   5   3   9   3   2   5   8   7   9   4   9   1   3   5   4   8
...
0010260   r   a   t   e   -   m   y   -   f   r   a   c   t   a   l   )
0010300   /   b   a   b   y   -   m   o   n   s   t   e   r   /  \n
0010317

Lub za pomocą edytora binarnego , np. beav, Jeex[47] lub Okteta.[48]

Grafika ASCIEdytuj

Grafika ASCI ( ASCI-Art)


Directory content

docs/
├── img/            # Image dir
├── include/        # TeX and HTML options
├── parts/          # Markdown content
├── _bookdown.yml   # bookdown options
├── _output.yml     # rmd output options
├── book.pdf        # PDF output
├── index.html      # HTML output
├── main.rmd        # main MD file
├── Makefile
└── README.md


info o plikuEdytuj

WięcejEdytuj

ŹródłaEdytuj

  1. What Every Programmer Absolutely, Positively Needs To Know About Encodings And Character Sets To Work With Text by David C. Zentgraf
  2. the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses by Joel Spolsky
  3. Character Encoder / Decoder
  4. Online Character Map
  5. wikipedia kod znaku
  6. Mausr - Marek's Unicode Symbols Recognizer
  7. iconv − character set conversion
  8. iconv − character set conversion
  9. Browser Test Page for Unicode Character
  10. stackoverflow question representing-eof-in-c-code
  11. znaki unicode
  12. bash-scripts-regular-expressions by Mikhail Raevskiy Sep 20, 2020
  13. What Every Programmer Absolutely, Positively Needs To Know About Encodings And Character Sets To Work With Text by David C. Zentgraf
  14. cppreference : ascii
  15. UTF-8 General Punctuation. Range: Decimal 8192-8303. Hex 2000-206F.
  16. Handling special characters in C (UTF-8 encoding)- stackoverflow
  17. Newline in wikipedia
  18. soscisurvey : view-chars
  19. bash function to highlight non-printing characters: tab, newline, BOM, nbsp
  20. alvin alexander : display-nonprintable-characters-in-text-file
  21. https://www.obliczeniowo.com.pl/794
  22. stackoverflow question: makefile4-missing-separator-stop
  23. BOM w wikipedii
  24. Elegant way to search for UTF-8 files with BOM?
  25. dos2unix converters
  26. Unicode encodings
  27. A Shell Script to Find and Remove the BOM Marker by Enrico M. Crisostomo
  28. Plik tekstowy
  29. linia w ang. wikipedii
  30. EOF w wikipedii
  31. znakowy typ danych w wikipedii
  32. znaki drukowalne w wikipedii
  33. znaki niedrukowalne w wikipedii
  34. Koniec linii w wikipedii
  35. spacja
  36. CSV to iCal Calendar Convertor by Manas Tungare
  37. Internet Calendaring and Scheduling Core Object Specification (iCalendar)
  38. iCalendar Specification Excerpts
  39. Pliki w formacie iCalendar
  40. libical library
  41. gcalcli library
  42. sygnsatura poliku w ang. wikipedii
  43. How to Determine Text File Encoding Submitted by Ben Bryant
  44. jak korzystać w c z utf-8
  45. C i unicode
  46. od - The Geek stuff
  47. Jeex
  48. Okteta - edytor plików binarnych