pathterminuspages/brkmnd.dk/aboutcontactabout me

Oversætter til trælse html-tabeller

21-09-2017

Jeg er har om C i skolen. Jeg har altid nogle småprojekter jeg laver når jeg lige får lyst. Jeg fik lyst, og siden jeg har om C, kan jeg ligeså godt lave det i C.

Projektet er som følger: Jeg har ofte brug for at lave tabeller, feks. til at liste tal op i. Lad os sige at vi vil lave 10-tabellen fra folkeren:

x12345678910
112345678910
22468101214161820
336912151821242730
4481216202428323640
55101520253035404550
66121824303642485460
77142128354249566370
88162432404856647280
99182736455463728190
10102030405060708090100

HTML-koden hertil er:

[table class="mat-symboltabel"] [tr style='background-color:#FFFFFF;'][td]x[/td][td]1[/td][td]2[/td][td]3[/td][td]4[/td][td]5[/td][td]6[/td][td]7[/td][td]8[/td][td]9[/td][td]10[/td][/tr] [tr style='background-color:#D8D8D8;'][td]1[/td][td]1[/td][td]2[/td][td]3[/td][td]4[/td][td]5[/td][td]6[/td][td]7[/td][td]8[/td][td]9[/td][td]10[/td][/tr] [tr style='background-color:#FFFFFF;'][td]2[/td][td]2[/td][td]4[/td][td]6[/td][td]8[/td][td]10[/td][td]12[/td][td]14[/td][td]16[/td][td]18[/td][td]20[/td][/tr] [tr style='background-color:#D8D8D8;'][td]3[/td][td]3[/td][td]6[/td][td]9[/td][td]12[/td][td]15[/td][td]18[/td][td]21[/td][td]24[/td][td]27[/td][td]30[/td][/tr] [tr style='background-color:#FFFFFF;'][td]4[/td][td]4[/td][td]8[/td][td]12[/td][td]16[/td][td]20[/td][td]24[/td][td]28[/td][td]32[/td][td]36[/td][td]40[/td][/tr] [tr style='background-color:#D8D8D8;'][td]5[/td][td]5[/td][td]10[/td][td]15[/td][td]20[/td][td]25[/td][td]30[/td][td]35[/td][td]40[/td][td]45[/td][td]50[/td][/tr] [tr style='background-color:#FFFFFF;'][td]6[/td][td]6[/td][td]12[/td][td]18[/td][td]24[/td][td]30[/td][td]36[/td][td]42[/td][td]48[/td][td]54[/td][td]60[/td][/tr] [tr style='background-color:#D8D8D8;'][td]7[/td][td]7[/td][td]14[/td][td]21[/td][td]28[/td][td]35[/td][td]42[/td][td]49[/td][td]56[/td][td]63[/td][td]70[/td][/tr] [tr style='background-color:#FFFFFF;'][td]8[/td][td]8[/td][td]16[/td][td]24[/td][td]32[/td][td]40[/td][td]48[/td][td]56[/td][td]64[/td][td]72[/td][td]80[/td][/tr] [tr style='background-color:#D8D8D8;'][td]9[/td][td]9[/td][td]18[/td][td]27[/td][td]36[/td][td]45[/td][td]54[/td][td]63[/td][td]72[/td][td]81[/td][td]90[/td][/tr] [tr style='background-color:#FFFFFF;'][td]10[/td][td]10[/td][td]20[/td][td]30[/td][td]40[/td][td]50[/td][td]60[/td][td]70[/td][td]80[/td][td]90[/td][td]100[/td][/tr] [/table]

Og den slags er jeg blevet ret træt af at skrive. Man laver ofte fejl, der er </td><td> mellem hver søjle, jeg kommer ofter til at skrive noget i mellem de to tags osv.

Løsningen er selvfølgelig at lave et program der oversætter noget mere læseligt til html. Så sådan et program har jeg lavet i C.

C blev opfundet i 1972. Det er et såkaldt imperativt programmerings hvori man kan strukturere sin kode med funktioner og 'structs'. Sproget er typestærkt. Det er midlevel, det minder i sin skrivemåde om nyere sprog, men samtidig kan man i C få adgang til maskininstruktioner og hukommelsen.

Fint nok, en platform for mit projekt. Der er i midlertidigt en masse ting man vænner sig til at de nyere sprog gør for en, men som C absolut ikke gør. I mit projekt har jeg haft brug for at arbejde med strenge. Altså tegn i citationstegn : "Jeg er en streng". Der er ikke strenge i C. Der er arrays. Et array i C er bare en allokeret sammenhængende del af computerens hukommelse. Man kan feks. initialisere, få adgang og skrive til et array ved enten at bruge den syntaks der hører til pointere, eller den der hører til arrays:

#include <stdio.h> int main(){ int A[10]; //Init nogle værdier A[0] = 10; A[1] = 20; *(A + 3) = 30; //Ændr nogle værdier *A = -1000; *(A + 1) = -10; //Flere mærkelige ting int* B = A + 2; *B = -291; printf("test A[0] : %d\n",A[0]); //-1000 printf("test A[1] : %d\n",A[1]); //-10 printf("test A[2] : %d\n",A[2]); //-291 return 0; }

Dette er egentligt fint nok. For vores ovenstående A er der allokeret 10 hukommelsespladser. Prøver jeg på A[10] i et nyere programmeringssprog, får jeg en eller anden form for fejl. Prøver jeg på det samme i C, får jeg, hvis jeg er heldig, en segmentation fault - jeg prøver at få adgang til noget i hukommelsen jeg ikke har adgang til. Hvis jeg derimod ikke får segfault, er der ikke rigtig nogen der ved hvad der sker. Hvad som helst kan returneres. Et tilfældigt tal der ligger det sted i hukommelsen, måske 0, hvem ved.

I mit program skulle jeg konkatenere to strenge i nogle situationer. I de fleste nyere sprog gøres det med + : "Jeg er " + "sammensat". Dette kan man af gode grunde ikke i C. Der er derimod en strcat() der gør det. Den tager 2 argumenter som er to strenge, først en destination og så en kilde. Begge er pointere, destinationen overskrives ved at kilden påsættes i enden. Og her gik det galt. Lad os feks. prøve med:

#include <stdio.h> #include <string.h> int main(){ char str0[] = "test "; char str1[] = ""; strcat(str0,"mand"); strcat(str1,"mogens"); printf("str0 : %s\n",str0); printf("str1 : %s\n",str1); return 0; }

Compiles dette med -fno-stack-protector, får vi:

str0 : ogens str1 : mogens

Altså et buffer overflow et eller andet sted. Det er noget pis, derfor skal man i C sikre sig at alle ens strenge, arrays og den slags har en passende længde.

Men jeg har lavet en tabelparser. Som udgangspunkt skal den have et input som:

\r x \s 1 \s 2 \s 3 \s 4 \s 5 \s 6 \s 7 \s 8 \s 9 \s 10 \r \r 1 \s 1 \s 2 \s 3 \s 4 \s 5 \s 6 \s 7 \s 8 \s 9 \s 10 \r \r 2 \s 2 \s 4 \s 6 \s 8 \s 10 \s 12 \s 14 \s 16 \s 18 \s 20 \r \r 3 \s 3 \s 6 \s 9 \s 12 \s 15 \s 18 \s 21 \s 24 \s 27 \s 30 \r \r 4 \s 4 \s 8 \s 12 \s 16 \s 20 \s 24 \s 28 \s 32 \s 36 \s 40 \r \r 5 \s 5 \s 10 \s 15 \s 20 \s 25 \s 30 \s 35 \s 40 \s 45 \s 50 \r \r 6 \s 6 \s 12 \s 18 \s 24 \s 30 \s 36 \s 42 \s 48 \s 54 \s 60 \r \r 7 \s 7 \s 14 \s 21 \s 28 \s 35 \s 42 \s 49 \s 56 \s 63 \s 70 \r \r 8 \s 8 \s 16 \s 24 \s 32 \s 40 \s 48 \s 56 \s 64 \s 72 \s 80 \r \r 9 \s 9 \s 18 \s 27 \s 36 \s 45 \s 54 \s 63 \s 72 \s 81 \s 90 \r \r 10 \s 10 \s 20 \s 30 \s 40 \s 50 \s 60 \s 70 \s 80 \s 90 \s 100 \r

\r er række start og ende. \s er søjlesplit. Meget simpelt. Man parser med følgende kommando ./lavtabel sti alt tilvalg hvor sti er stien til filen, alt er om der skal altereres i farver, her kan vælges ja/nej, og tilvalg er parsertilvalg. Indtil videre er der tilvalget mat. Hvis dette, bliver feks. \_200 lavet om til <sub>200</sub>.

Hele programmet kan hentes her. Kildekoden er med. Det kan være at jeg foretager smarte ændringer i programmet. Hvis så, redegør jeg for dem i en tekstfil der medfølger.