Hallo Liebe Forumuser, ich habe eine Aufgabe fuer die Uni zu bewaeltigen und stecke fest. ich soll aehnlich wie in http://cboard.cprogramming.com/c-programming/56439-ascii-art-decoder-encoder.html einen Dekodierer auf C Basis erstellen, der mir solch verschluesselten Dateien dekodiert. Das Programm Soll: - Benutzer nach Dateinamen fragen. - Zeilen dieser Datei als Datensätze des dargestellten Kodierers interpretieren - Die Daten dekodieren und gibt die verschluesselten Daten dann entsprechend ihrer Anzahl und Reihenfolge am Bildschirm aus, damit man das urspruengliche Bild sehen kann. Danach die Ausgabe nicht nur auf dem Bildschirm sondern zusätzlich in eine TXT-Datei schreiben. Die Elemte der Syntax duerfen durch beliebig viel Leerraum getrennt sein. Dazu zaehlen: - Leerzeichen - Tabulatorzeichen - Neue Zeile Zeichen Da dann mit der ctype.h Funktion isspace zur Erkennung von Leerraumzeichen arbeiten.
Mein Code sieht folgendermaßen aus:
1 | /*
|
2 | |
3 | fp = fopen("abc.txt", "w"); //Datei im write modus geöffnet -> wird automatisch erzeugt.
|
4 | |
5 | |
6 | fputs( //zaehler * //zeichen, fp);
|
7 | |
8 | |
9 | //Ausgeben von dem Zeichen * Zaehler auf der Console:
|
10 | |
11 | int p = 0;
|
12 | |
13 | while (p < //zaehler, p++){
|
14 | |
15 | printf("%c", //zeichen);
|
16 | |
17 | }
|
18 | |
19 | |
20 | |
21 | fclose(fp);
|
22 | |
23 | }*/
|
24 | |
25 | |
26 | int i = 1, b, zn= 0; |
27 | char array[]; |
28 | int main () |
29 | {
|
30 | |
31 | FILE *input, *output; |
32 | char* z; //Anzahl Zeichen |
33 | char* c, *cn = ""; //Zeichen |
34 | char BREITE, name_input[255], name_output[255]; |
35 | |
36 | printf("Nennen sie den Dateinamen : "); |
37 | scanf("%s",name_input); |
38 | input=fopen(name_input,"r"); |
39 | if(input == NULL) { |
40 | printf("%s Datei konnte nicht geoeffnet werden.\n",name_input); |
41 | return EXIT_FAILURE; |
42 | }
|
43 | /*else {
|
44 | printf("Nennen Sie einen Dateinamen zum speichern : ");
|
45 | scanf("%s",name_output);
|
46 | output=fopen(name_output,"w+");
|
47 | if(output==NULL) {
|
48 | printf("Datei konnte nicht gespeichert werden.\n");
|
49 | return EXIT_FAILURE;
|
50 | }*/
|
51 | |
52 | fgets(array, 1200, input); //array erzeugen. |
53 | //erste zeile
|
54 | char* e = strtok(array,"=;"); //initialiserung, welche char* array |
55 | e = strtok(NULL,"=;"); //bereits initialisiert |
56 | |
57 | int y = 0; |
58 | b=0; |
59 | for(y; y<sizeof(e)-2; y++){ //Berechnung Breite |
60 | b+=((int)e[y]-'0'); |
61 | b=b*10; |
62 | }
|
63 | b = b/10; //Breite |
64 | int boolean = 1; |
65 | while(fgets(array, 1200, input)){ |
66 | z ='\0'; |
67 | z = strtok(array, ("' \n\t")); |
68 | //z ="12";
|
69 | printf("%s", z); //unsere Zahl vor dem Zeichen |
70 | c = '\0'; |
71 | c = strtok(NULL, ("'")); |
72 | printf("%s", c); //unser zeichen nach zahl |
73 | for(y = 0; y < sizeof(z)-2; y++){ //Berechnung Breite -2 wegen \0 |
74 | zn+=((int)z[y]-'0'); |
75 | zn=zn*10; |
76 | }
|
77 | zn = zn/10; //Breite |
78 | printf("zn %d",zn); |
79 | char test[10] = "abc"; |
80 | strncat(test,c,3); //Zusammensetzen |
81 | printf("%s",test); |
82 | /* for(zn; zn>0; z--){
|
83 | |
84 | }*/
|
85 | }
|
86 | |
87 | /* while(boolean == 1){
|
88 | z = strtok(NULL, ("' \n\t"));
|
89 | printf("%s",z);
|
90 | c = strtok(NULL, ("'"));
|
91 | printf("%s", c);
|
92 | boolean = 0;
|
93 | }*/
|
94 | /*z = strtok(array, ("' \n\t"));
|
95 | while(z != NULL){
|
96 | printf("%s", z);
|
97 | c = strtok(NULL, ("'"));
|
98 | printf("%s", c);
|
99 | }*/
|
100 | |
101 | return EXIT_SUCCESS; |
102 | }
|
:
Bearbeitet durch Moderator
Tut mir leid fuer das Durcheinander, aber ich bin noch ein Anfaenger. Es sind noch viele printf's im Programm zur Fehlersuche und ein Test zur Stringverkettung. Meine Ausgabe auf der Konsole ist sehr wirr und aber hier meine erste Zeile der Ausgabe. Nennen sie den Dateinamen : asterix.caa 8 zn 32abc 24 zn 344abc 3 zn 3422abc 14 zn 34234abc 3 zn 342322abc 81 zn 3423301 Der erste Part stimmt. 8 und " " ein Leerzeichen als Zeichen, jedoch weiss ich nicht wieso er dann bei 32 ankommt und der Zahlenwert immer laenger wird. Stimmt was mit dem /0 nicht?
ektoplasma schrieb: > char array[]; Das wird so nichts, woher soll der Compiler wissen, wie viel Speicher er für dein Array reservieren soll? > char* e = strtok(array,"=;"); //initialiserung, welche char* array > e = strtok(NULL,"=;"); //bereits initialisiert > > int y = 0; > b=0; > for(y; y<sizeof(e)-2; y++){ //Berechnung Breite sizeof(e) liefert dir hier die Größe in Bytes des Pointers und nicht die Länge des Strings, dafür ist strlen da. Beschäftig dich lieber mal mit den Grundlagen. ektoplasma schrieb: > Tut mir leid fuer das Durcheinander Was schon mal viel zu Lesbarkeit beiträgt sind die Code Tags:
1 | [c]C-Code[/c] |
:
Bearbeitet durch User
Stimmt, das habe ich ganz vergessen. Also reserviere ich mir mit malloc einfach meinen Speicher?
1 | array = (int *) malloc(size * sizeof(int)); |
Steffen M. schrieb: > Also reserviere ich mir mit malloc einfach meinen Speicher? > array = (int *) malloc(size * sizeof(int)); Dann würde ich array aber mit
1 | char *array; |
deklarieren. Den Pointer würde ich auch nach (char*) und nicht nach (int*) casten und mit der Größe size * sizeof(char) allokieren. Nicht vergessen, den Speicher am Ende wieder freizugeben. Wenn du auch mit statischer Größe zurechtkommst, würde ich auf das malloc verzichten.
:
Bearbeitet durch User
Für Stringverarbeitung ist c ziemlich unpraktisch. Ich würde in c eine statemachine dafür verwenden. Hier mal ein getestetes JavaScript beispiel:
1 | javascript:void ((function(){ |
2 | function draw(x){ |
3 | var res = x.match(/([^\n]+)=([^\n]+);\n((.|\n)*)/m); |
4 | if(!res) |
5 | return ''; |
6 | var v = res[1]; |
7 | var n = res[2]; |
8 | var data = res[3].match(/(\d+)\w*'(.)'/g); |
9 | var s = ''; |
10 | for(var i=0,j=0;i<data.length;i++){ |
11 | var m = data[i].match(/(\d+)\w*'(.)'/); |
12 | if(!m) continue; |
13 | var len = m[1]; |
14 | var ch = m[2]; |
15 | while(len--){ |
16 | s += ch; |
17 | if(!((j+++1)%n)) |
18 | s+="\n"; |
19 | } |
20 | } |
21 | return s; |
22 | } |
23 | document.body.style.whiteSpace="pre"; |
24 | document.body.style.fontFamily="monospace"; |
25 | document.body.style.fontSize="11px"; |
26 | document.body.innerText=draw(document.body.textContent||document.body.text||document.body.innerText); |
27 | })()); |
Aber das Bild ist gut gelungen, sehr gut!
Ja, leider muessen wir das in C machen. Da ich auch im Stoff hinterher hinke, bin ich ziemlich ratlos wie ich das anstellen soll.
Max H. schrieb: > Steffen M. schrieb: >> Also reserviere ich mir mit malloc einfach meinen Speicher? >> array = (int *) malloc(size * sizeof(int)); > Dann würde ich array aber mit
1 | char *array; |
deklarieren. > Den Pointer würde ich auch nach (char*) und nicht nach (int*) casten und > mit der Größe size * sizeof(char) allokieren. Nicht vergessen, den > Speicher am Ende wieder freizugeben. > > Wenn du auch mit statischer Größe zurechtkommst, würde ich auf das > malloc verzichten. Soll ich dann einfach mit MAX Größe initialisieren?
Steffen M. schrieb: > Soll ich dann einfach mit MAX Größe initialisieren? Wenn du eine sinnvolle MAX Größe angeben kannst, dann ja.
Sowas in der Uni?!? Naja, für schlecht gestellte Aufgaben gibt's auch schlechte Lösungen:
1 | /* quick'n'dirty .caa interpreter - copyright foobar@mikrocontroller.net */
|
2 | #include <stdio.h> |
3 | |
4 | int main(int argc, char **argv) |
5 | {
|
6 | int b = 80; |
7 | int x = 0; |
8 | int c; |
9 | |
10 | while ((c = getchar()) != EOF) |
11 | if (c >= '0' && c <= '9') |
12 | {
|
13 | int n = 0; |
14 | |
15 | do
|
16 | n = 10*n + c-'0'; |
17 | while ((c = getchar()) >= '0' && c <= '9'); |
18 | |
19 | if (c == ';') |
20 | b = n; |
21 | if (c == '\'') |
22 | {
|
23 | c = getchar(); |
24 | while (n-- > 0) |
25 | {
|
26 | putchar(c); |
27 | if (++x >= b) |
28 | putchar('\n'), x = 0; |
29 | }
|
30 | }
|
31 | }
|
32 | putchar('\n'); |
33 | return 0; |
34 | }
|
Benutzung: ./a.out <asterix.caa bzw: ./a.out <asterix.caa >ausgabe.txt Dies soll nur ein Beispiel sein, wie man sowas auf die einfachste Weise implementieren kann (nicht sollte!). Auch wenn man den Parser schöner macht, sind komplexe String-Funktionen oder dynamische Speicherverwaltung nicht nötig. Btw, Kommentare habe ich mit Absicht weggelassen - klamüser selbst raus, wie/warum das funktioniert, wo Probleme auftreten und mach es dann besser ;-)
Hier noch eine Lösung in c von mir im Anhang. Kompilieren mit: gcc -Wall -Werror -Wextra -pedantic -std=c99 main.c -o main Verwendung: main < asterix.caa
:
Bearbeitet durch User
man muss nur dumm genug fragen, dann macht einem schon irgend ein Depp die Hausaufgaben, oder was ist das hier ... ;-)
foobar schrieb: > Sowas in der Uni?!? Eher für eine TH, ehemals HAW. Die Aufgabe kommt mir bekannt vor...
Ich bin jetzt doch drauf gekommen. Etwas einfacher als die von dir Daniel. Trotzdem vielen Dank an euch alle fuer eure Hilfe.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.