Forum: PC-Programmierung Hilfe bei einem C-Programm fuer einen ASCII Art Dekodierer


von ektoplasma (Gast)


Angehängte Dateien:

Lesenswert?

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.

von ektoplasma (Gast)


Lesenswert?

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
von ektoplasma (Gast)


Lesenswert?

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?

von Max H. (hartl192)


Lesenswert?

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
von Steffen M. (ektoplasma)


Lesenswert?

Stimmt, das habe ich ganz vergessen.

Also reserviere ich mir mit malloc einfach meinen Speicher?
1
array = (int *) malloc(size * sizeof(int));

von Max H. (hartl192)


Lesenswert?

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
von Daniel A. (daniel-a)


Angehängte Dateien:

Lesenswert?

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!

von Steffen M. (ektoplasma)


Lesenswert?

Ja, leider muessen wir das in C machen. Da ich auch im Stoff hinterher 
hinke, bin ich ziemlich ratlos wie ich das anstellen soll.

von Steffen M. (ektoplasma)


Lesenswert?

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?

von Max H. (hartl192)


Lesenswert?

Steffen M. schrieb:
> Soll ich dann einfach mit MAX Größe initialisieren?
Wenn du eine sinnvolle MAX Größe angeben kannst, dann ja.

von foobar (Gast)


Lesenswert?

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 ;-)

von Daniel A. (daniel-a)


Angehängte Dateien:

Lesenswert?

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
von Robert L. (lrlr)


Lesenswert?

man muss nur dumm genug fragen, dann macht einem schon irgend ein Depp 
die Hausaufgaben, oder was ist das hier ...

;-)

von Ben (Gast)


Lesenswert?

foobar schrieb:
> Sowas in der Uni?!?

Eher für eine TH, ehemals HAW. Die Aufgabe kommt mir bekannt vor...

von Steffen M. (ektoplasma)


Lesenswert?

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
Noch kein Account? Hier anmelden.