Präprozessor in eine Variable umbauen, Programm tuts nicht mehr



  • Ich habe jetzt mal

    int iMAXW;
    

    gelassen, es also nicht genullt...

    dennoch bleiben meine eigentlichen Probleme (siehe Beitrag 1)



  • Übrigens, ich bekomme jetzt nach der Texteingabe eine Endlosschleife,
    in der er mir lauter Sternchen macht...
    Ich wollte die fflush Alternative benutzen:

    scanf ( "%*[^\n]" );
    scanf ( "%*c" );
    

  • Mod

    Phenny schrieb:

    Ich habe jetzt mal

    int iMAXW;
    

    gelassen, es also nicht genullt...

    dennoch bleiben meine eigentlichen Probleme (siehe Beitrag 1)

    Du hast das Problem ja auch in keinster Weise gelöst. Hast du die Antworten nicht gelesen? Inwiefern sollte es dir denn helfen, eine Arraylänge von 0 gegen eine undefinierte Arraylänge zu tauschen? Und das Nullen des Arrays hat wie dir schon erklärt wurde, überhaupt nichts mit deinem iMAXW zu tun.

    c.rackwitz schrieb:

    Wenn du selber Code schreibst, musst du ihn auch verstehen. Code ist kein Haufen von wahllos zusammengeschmissenen Buchstaben und Zeichen, Code ist Logik pur. Du musst genau wissen, warum du wo und welches Zeichen setzt.



  • iMAXW ist doch kein Array?, es ist doch nur l ein Array, welches den integer iMAXW enthält.


  • Mod

    Phenny schrieb:

    iMAXW ist doch kein Array?, es ist doch nur l ein Array, welches den integer iMAXW enthält.

    Nein. So wie du es schreibst ist iMAXW ein int. l ist ein Array. Aber l enthält nicht iMAXW, sondern hat die Länge iMAXW. Und welchen Wert hatte iMAXW bei deinem Code?

    Zuerst hatte es den Wert 0 ➡ Array hat Länge 0. ➡ Fehler/Absturz beim Zugriff auf Arrayelemente

    Dann, nach der Änderung, einen undefinierten Wert ➡ Array hat undefinierte (möglicherweise sogar negative) Länge ➡ in der Regel Absturz.



  • Also, SeppJ

    bevor ich den Präprozessor MAXW in int iMAXW umgebaut habe, hatte ich
    für den Array "l" eigentlich

    int l[MAXW] = {0};
    

    nur geht das mit diesem int iMAXW nichtmehr weil ich dann
    Probleme mit Pointer etc bekomme.



  • ups, mein Fehler...
    ich meinte eig., dass ich dann Probleme mit der größe bekomme
    siehe hier

    histogramm.c:27: error: variable-sized object may not be initialized
    histogramm.c:27: warning: excess elements in array initializer
    histogramm.c:27: warning: (near initialization for ‘l’)
    

  • Mod

    edit: war nicht richtig.



  • verstehe ich jetzt nicht... 😕



  • also, so sah der Code am Anfang aus, bevor ich "iMAXW" eingeführt habe:

    #include <math.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #define MAXW 25
    
    void wlist(char *s, int *l) {
        char *t;
        for (t = strtok(s, " ?!.,\n"); t; t = strtok(0, " .,\n"))
            if (*t && strlen(t) <= MAXW)
                l[strlen(t) - 1]++;
    
    }
    
    main() {
        char strtmp[10];
        char x[256];
        int i, weiter = 1, lauf = 0, l[MAXW] = {0};
    
        printf("\nWas soll die Maximale Wortlaenge sein?");
        scanf("\n%d", &MAXW);
        printf("Schreiben Sie ihren Text: \n");
        fgets(x,sizeof x,stdin);  //Eingabe des zu bearbeitenden Textes
        wlist(x, l);
        printf("\nHistogramm der Wortlaenge eines Textes\n"
                "----------------------------------------------------------------------------\n");
        for (i = 0; i < MAXW; ++i)
            printf("%3d", i + 1);
        puts("");
    
        while (weiter) {
            ++lauf;
            weiter = 0;
            for (i = 0; i < MAXW; ++i)
                printf("  %c", l[i] && l[i] >= lauf ? '*' : ' '), weiter = !weiter ? l[i] > lauf : weiter;
            puts("");
        }
        printf("\n----------------------------------------------------------------------------\n");
        for (i = 0; i < MAXW; ++i)
            printf("%3s", l[i] > 7 ? (sprintf(strtmp,"%d",l[i]),strtmp) : "");
        printf("\n");
        return 0;
    }
    


  • printf("\nWas soll die Maximale Wortlaenge sein?");
        scanf("\n%d", &MAXW);
    

    sorry, hatte vergessen das noch aus dem alten Code rauszulöschen...

    #include <math.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #define MAXW 25
    
    void wlist(char *s, int *l) {
        char *t;
        for (t = strtok(s, " ?!.,\n"); t; t = strtok(0, " .,\n"))
            if (*t && strlen(t) <= MAXW)
                l[strlen(t) - 1]++;
    
    }
    
    main() {
        char strtmp[10];
        char x[256];
        int i, weiter = 1, lauf = 0, l[MAXW] = {0};
    
        printf("Schreiben Sie ihren Text: \n");
        fgets(x,sizeof x,stdin);  //Eingabe des zu bearbeitenden Textes
        wlist(x, l);
        printf("\nHistogramm der Wortlaenge eines Textes\n"
                "----------------------------------------------------------------------------\n");
        for (i = 0; i < MAXW; ++i)
            printf("%3d", i + 1);
        puts("");
    
        while (weiter) {
            ++lauf;
            weiter = 0;
            for (i = 0; i < MAXW; ++i)
                printf("  %c", l[i] && l[i] >= lauf ? '*' : ' '), weiter = !weiter ? l[i] > lauf : weiter;
            puts("");
        }
        printf("\n----------------------------------------------------------------------------\n");
        for (i = 0; i < MAXW; ++i)
            printf("%3s", l[i] > 7 ? (sprintf(strtmp,"%d",l[i]),strtmp) : "");
        printf("\n");
        return 0;
    }
    


  • Üblicherweise verwendet man Grossbuchstaben für Konstanten oder #define wie im Beispiel. Wenn diese auch noch variabel sein soll, wie du jetzt offenbarst, dann muss für C89, wo Arraydefinition nur für konstante Größen definiert ist, auch l dynamisch definiert werden, z.B. mittels

    int *l=calloc(imaxw,sizeof(int)); /* sollte vor Ende auch wieder freigegeben werden */
    


  • Wutz schrieb:

    Üblicherweise verwendet man Grossbuchstaben für Konstanten oder #define wie im Beispiel. Wenn diese auch noch variabel sein soll, wie du jetzt offenbarst, dann muss für C89, wo Arraydefinition nur für konstante Größen definiert ist, auch l dynamisch definiert werden, z.B. mittels

    int *l=calloc(imaxw,sizeof(int)); /* sollte vor Ende auch wieder freigegeben werden */
    

    Verwirr ihn doch nicht entgültig. 😉

    Da er sein gepostetes Programm offensichtlich bis zur Ausführung gebracht hat, dürfen wir, denke ich, davon ausgehen, dass er einen C99-Compiler einsetzt.



  • Leideer nicht,
    ich benütze den Compiler Cygwin_4.x.
    Was aber dennoch funktioniert ^^



  • Programmiersprache C...bevor noch irgendwelche Missverständnisse aufkommen^^



  • Der dürfte aber schon C99 unterstützen, sonst hätte dein Programm nicht übersetzt werden können. Aber egal...

    Ich habe deinen Code mal notdürftig umgestrickt, damit du wenigstens wieder was Funktionierendes hast. Schön ist der Code deshalb noch lange nicht. Nutze bitte mal die Suchfunktion des Forums und suche nach "Eingabepuffer leeren", dann findest du sicher eine (standardkonforme) Alternative für fflush(stdin), die auch funktioniert.

    #include <cmath>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    
    void wlist(char *s, int *l, int maxW) {
    	char *t;
    	for (t = strtok(s, " ?!.,\n"); t; t = strtok(0, " .,\n"))
    		if (*t && strlen(t) <= maxW)
    			l[strlen(t) - 1]++;
    
    }
    
    int main() {
    	char strtmp[10];
    	char x[256];
    	int i, weiter = 1, lauf = 0;
    	int maxW;
    
    	printf("\nWas soll die Maximale Wortlaenge sein?\n");
    	scanf("%i\0\n", &maxW);
    	fflush(stdin);
    
    	int *l=calloc(maxW,sizeof(int));	//dynamisch Speicher per calloc alloziert
    
    	//bei dir dürfte alternativ auch das hier funktionieren:
    	//int l[maxW];
    
    	printf("Schreiben Sie ihren Text: \n");
    	fgets(x,sizeof x,stdin);  //Eingabe des zu bearbeitenden Textes
    	wlist(x, l, maxW);
    	printf("\nHistogramm der Wortlaenge eines Textes\n"
    		"----------------------------------------------------------------------------\n");
    	for (i = 0; i < maxW; ++i)
    		printf("%3d", i + 1);
    	puts("");
    
    	while (weiter) {
    		++lauf;
    		weiter = 0;
    		for (i = 0; i < maxW; ++i)
    			printf("  %c", l[i] && l[i] >= lauf ? '*' : ' '), weiter = !weiter ? l[i] > lauf : weiter;
    		puts("");
    	}
    	printf("\n----------------------------------------------------------------------------\n");
    	for (i = 0; i < maxW; ++i)
    		printf("%3s", l[i] > 7 ? (sprintf(strtmp,"%d",l[i]),strtmp) : "");
    	printf("\n");
    	return 0;
    }
    


  • Bei deinem Code wird die Texteingabe übersprungen,
    da "scanf" das \n an "fgets" übergiebt, weshalb ich das "getchar()"
    nach "scanf" hatte 😃



  • Phenny schrieb:

    Bei deinem Code wird die Texteingabe übersprungen,
    da "scanf" das \n an "fgets" übergiebt, weshalb ich das "getchar()"
    nach "scanf" hatte 😃

    Bei mir nicht. Bei mir funktioniert ja auch fflush(stdin) (MS-Compiler). Bei dir offensichtlich nicht. Das Ziel der Zeile ist es ja, den Eingabepuffer zu leeren. Wenn bei dir was übrig bleibt, wurde dieses Ziel nicht erreicht. Ein Grund mehr, endlich auf mich zu hören, und das mal durch was Vernünftiges zu ersetzen.



  • Du Schlingel^^
    "clearbuff()" jaja, du hast mir die Brotkrümel sozusagen gelegt^^

    Ja, nun ist mein letzes Problem eigentlich die Wörter, die
    Länger sind als "maxW" ganz hinten als Zahl darzustellen,
    also genau wie die einzelnen Wörter bearbeitet werden, so müssen auch
    diese bearbeitet werden die zulang sind. Sprich also die Wörter die
    größer sind als maxW werden dann ganz hinten unter
    "sagen wir mal maxW = 10"

    -----------------------------------------------------
    1 2 3 4 5 6 7 8 9                                     10
    * * * * * * * * *                                     *
    * *     *   *                                         *
    *       *                                             *
    --------------------------------------------------------
    

    ungefähr halt so, ich denke ich kann

    printf("\nHistogramm der Wortlaenge eines Textes\n"
            "----------------------------------------------------------------------------%i\n", maxW);
    

    machen, aber wie krieg ich bloß die sterne da so nach hinten? 😕



  • Na du kannst doch zählen, und du weißt doch, wieviele Zeichen in der Breite du zur Verfügung hast. Wo ist jetzt die Schwierigkeit, entsprechend viele Spaces zu drucken?

    Hast du eigentlich schon mal gesehen, wie deine Ausgabe aussieht, wenn du für maxW 40 eingibst? Wer auch immer das Programm geschrieben hat, wird sich beim ursprünglichen Wert schon was gedacht haben... 💡


Anmelden zum Antworten