Textbearbeitung, unsicher - VST Fehler



  • Guten Abend.
    Also ich habe ein Programm fürs formatieren einer Überschrift geschrieben.
    Es soll die Überschrift mit Sterchen * und Leerzeichen verzieren.
    Überschrift: Politik
    Vorher: Politik
    Nachher: * P * o * l * i * t * i * k *

    Mein Code SOLLTE bis auf den ersten und letzten Stern funktionieren....
    Aber: Ich debugge es, drücke im Menü auf 1 (habe auch ein einfaches Menü programmiert) und dann kommt die Meldung vom Windows Explorer: überschrift formatierung.exe funktioniert nicht mehr
    Wenn ich eine Zeile raus nehme
    und zwar diese hier: "str[b] = " * ";" kommt die Fehlermeldung nicht mehr, aber es wird nicht mal mehr was ausgegeben.
    Ich habe morgen wieder eine Arbeit, wäre nett wenn ihr mir schnell helfen könnt.

    Hier der Code:

    #include <stdio.h>
    #include <conio.h>
    #include <string.h>
    
    void zahlung (char[]);
    int menu (void);
    
    void main (void)
    {
    	FILE *lfn;
    	char zeile[100], lol[50];
    	int ant;
    
    	while (ant = menu())
    	{
    		switch (ant)
    		{
    		case 1:
    
    			lfn = fopen ("C:\\Users\\Cem\\Desktop\\Desktop\\Documents\\Visual Studio 2008\\Projects\\überschrift formatierung\\cem.txt","r");
    			if (!lfn)
    			{
    				printf ("Datei konnte nicht geoeffnet werden!");
    				break;
    			}
    			fgets (zeile, 100, lfn);
    			while (!feof(lfn))
    			{
    				zahlung(zeile);
    				printf ("%s\n", zeile);
    				fgets (zeile, 100, lfn);
    			}
    			break;
    		default:
    			printf ("Falsche Eingabe!");
    		}
    	}
    }
    
    int menu (void)
    {
    	int ant;
    
    	puts ("\t*** Probeteast ***\n\n");
    	puts ("0 ... Ende");
    	puts ("1 ... Fkt1");
    
    	printf ("\nBitte ihre Wahl: ");
    	scanf ("%d", &ant);
    	flushall ();
    	return ant;
    }
    
    void zahlung (char zeile[100])
    {
    	char str[100];
    	int a, b, c, lg;
    	a = 0;
    	c = 0;
    	lg = 0;
    	b = 4;
    
    	while (zeile[c] > 0)
    	{
    		c++;
    	}
    	lg  = c * 2 + 4 + 1;
    	str[lg] = '\0';
    	lg = lg - 2;
    
    	while(str[a] != '\0')
    	{
    		str[lg] = str[c];
    		lg = lg - 2;
    		c--;
    		a++;
    		while(str[a] != '\0')
    		{
    			str[b] = " * ";
    			b++;
    
    		}
    	}
    
    }
    

    Gruß
    c.nub



  • Ich habe den Inhalt der txt Datei geändert und es hat nur noch eine Zeile und ein Wort: Politik
    Keine Fehlermeldung mehr! Aber, ich komme zurück ins Menü, es wird nicht in case 1 weiter gemacht.
    Wo liegt der Fehler?



  • dein sternchen-anhänger sieht zu kompliziert aus, ist bestimmt auch verbuggt. probier mal die primitvlösung:

    void mach_sternchen (char *in, char *out)
    {
        while (*in)
        {
            *out++ = '*';
            *out++ = *in++;
        }
        *out++ = '*';
        *out = 0;
    }
    

    und so dann aufrufen:

    char *in = "hallo";
    char out[256];
    ...
    mach_sternchen (in, out);
    puts (out);
    ...
    

    🙂



  • frickys code mit leerzeichen (war leicht, weil die vorlage fein war):

    void mach_sternchen (char *in, char *out)
    {
        while (*in)
        {
            *out++ = '*';
            *out++ = ' ';
            *out++ = *in++;
            *out++ = ' ';
        }
        *out++ = '*';
        *out = 0;
    }
    


  • Hey
    Mir zeigt er Fehler an weil man eine FILE Variable keinen Wert zu weisen kann oder wie ist das? Und auch keine Zeichen?
    Das ist doch nur die Verbindung zur txt Datei.
    vorallem nicht so:

    *out++ = '*'
    

    Ich habs mit eurer Version nicht mal ausführen können. Muss ich bei den Parametern oben FILE* rein schreiben?
    Eine Step4Step Erklärung wäre nett!

    Gruß
    c.nub



  • Hast du einen FILE* für out übergeben? out sollte ein char-Array oder ein Zeiger auf char sein, nennen wir es "Puffer". In diesem Puffer bauen fricky und volkard die Ausgabe zusammen. Du könntest die Zeichen stattdessen auch gleich augeben (mit putchar() oder sowas). Wenn du aber einen Puffer verwendest, musst du den natürlich am Ende auch noch ausgeben.

    Ich habs mit eurer Version nicht mal ausführen können.

    Das sollte nicht schwer werden:

    #include <stdio.h>
    
    void mach_sternchen (char *in, char *out)
    {
        while (*in)
        {
            *out++ = '*';
            *out++ = ' ';
            *out++ = *in++;
            *out++ = ' ';
        }
        *out++ = '*';
        *out = 0;
    }
    
    int main(int ac, char **av)
    {
        char *in = "hallo";
        char out[256];
    
        mach_sternchen (in, out);
        puts (out);
    
        return 0;
    }
    

    Läuft gut. Ohne den Puffer könntest du es zB so machen:

    #include <stdio.h>
    
    void schreib_sternchen (char *in)
    {
        while (*in)
        {
            putchar('*');
            putchar(' ');
            putchar(*in++);
            putchar(' ');
        }
        putchar('*');
    }
    
    int main(int ac, char **av)
    {
        char *in = "hallo";
    
        schreib_sternchen (in);
    
        return 0;
    }
    


  • So, etwas geändert, syntax Fehler und sonstige Sachen verändert.

    #include <stdio.h>
    #include <conio.h>
    #include <string.h>
    
    void zahlung (char[]);
    int menu (void);
    
    void main (void)
    {
        FILE *lfn;
        char zeile[100];
        int ant;
    
        while (ant = menu())
        {
            switch (ant)
            {
            case 1:
    
                lfn = fopen ("C:\\Users\\Cem\\Desktop\\Desktop\\Documents\\Visual Studio 2008\\Projects\\überschrift formatierung\\cem.txt","r");
                if (!lfn)
                {
                    printf ("Datei konnte nicht geoeffnet werden!");
                    break;
                }
                fgets (zeile, 100, lfn);
                while (!feof(lfn))
                {
                    zahlung(zeile); // in diesem moment sollte es verarbeitet werden
                    printf ("%s\n", zeile); // es wird NUR Politik ohne formatierungen ausgegebn
                    fgets (zeile, 100, lfn);
                }
                break;
            default:
                printf ("Falsche Eingabe!");
            }
        }
    }
    
    int menu (void)
    {
        int ant;
    
        puts ("\t*** Probeteast ***\n\n");
        puts ("0 ... Ende");
        puts ("1 ... Fkt1");
    
        printf ("\nBitte ihre Wahl: ");
        scanf ("%d", &ant);
        flushall ();
        return ant;
    }
    
    void zahlung (char zeile[])
    {
        int a, b, c, lg;
        a = 0;
        c = 0;
        lg = 0;
        b = 4;
    
        while (zeile[c] != '\0')
        {
            c++;
        }
        lg  = c * 4 + 2; // gesamtlänge mit sternchen und leerzeichen + 1 für die stelle der binären 0.
        zeile[lg] = '\0';
    	lg= lg -3; // - 3 dann sind wir auf stelle 27... also 29 = * und 28 = leerzeichen.
    
        while(zeile[a] <= c)
        {
            zeile[lg] = zeile[c]; // zeile[27] = zeile[c]; also in c ist die letzte stelle von politik. also K... stelle 27 ist leer.... k geht in 27 rein.
            lg = lg - 3;
            c--;
            a++;
            zeile[b] = ' ';
            b++;
            zeile[b] = '*';
            b++;
            zeile[b] = ' ';
            b = b + 2;
        }
    
    }
    

    Bitte seht euch den Code an... Ich denke vom Prinzip her ist es richtig.
    Ich brauche es in dieser Form, also bitte keine anderen Codes posten, weil fast immer etwas neues dabei ist, was wir noch nicht gelernt haben.

    btw: der Test wurde auf Dienstag verschoben, also ich beschäftige mich gerade in der Stunde damit.

    Gruß
    c.nub



  • Ich brauche es in dieser Form, also bitte keine anderen Codes posten, weil fast immer etwas neues dabei ist, was wir noch nicht gelernt haben.

    Sag mal... was hast du denn von einem Programmierforum erwartet?

    Du hattest mich eigentlich mit dem #include <conio.h> abgeschreckt, aber da geht es scheinbar nur um flushall(). Wenn ich das rausnehme, ist es ANSI-C, und ich kann's auch testen. Wenn ich dann den Pfad zur Datei auf eine Testdatei umbiege, bekomme ich zwar wilde Ausgaben, aber ohne Sterne drin.

    Das ist schade, weil ich sicher nicht zu dem mentalen Aufwand bereit bin, deine zahlung() zu durchschauen, wo das Ding gar so böse aussieht. Vier Ganzzahlen, von denen ich bei keiner erkennen kann, was sie tun soll, am Anfang ein strlen()-Aufruf, den du gleich selbst inlined hast... Wenn du mir also verbietest, eine einfachere Alternative zu erfinden, kann ich dir nicht weiter helfen.



  • c.nub schrieb:

    Ich brauche es in dieser Form, also bitte keine anderen Codes posten, weil fast immer etwas neues dabei ist, was wir noch nicht gelernt haben.

    wenn dich die pointer stören, dann mach es mit 'nem array-index à la:

    *ptr++ = irgendwas;
    //
    // ... entspricht ...
    //
    ptr[idx] = irgendwas;
    idx = idx + 1;
    

    dein originalcode ist ziemlich schrottig, weil er den string selbst verändert, das geht in dem fall nicht gut, weil zeichen überschrieben werden, die er später noch braucht.
    🙂



  • ;fricky schrieb:

    wenn dich die pointer stören, dann mach es mit 'nem array-index à la:

    *ptr++ = irgendwas;
    //
    // ... entspricht ...
    //
    ptr[idx] = irgendwas;
    idx = idx + 1;
    

    dein originalcode ist ziemlich schrottig, weil er den string selbst verändert, das geht in dem fall nicht gut, weil zeichen überschrieben werden, die er später noch braucht.
    🙂

    Das ist eine gute und hilfreiche Antwort.
    @ Mister Sonderzeichen:
    90% deiner Antwort war unnötig... auf gut Deutsch = Mist.
    Ja okay, ich sehe ein, dass ich net der tollste coder bin... und? Ich lerne es gerade, also bitte reg dich nicht wegen Luft auf.
    Nein ich rege mich nicht auf, ich will mich nur rechtfertigen, weil mich deine Antwort mich wie einen Idioten hinstellt... Aber gut ganz nach dem Motto: do what ever you want.
    Ich möchte hier aber nicht über blödsinn diskutieren und streiten... Trotzdem danke wegen deiner vorherigen Antwort, aber meckern kannst du auf www.ich-muss-wieder-meckern-weil-ein-noob-nicht-richtig-coden-kann-bzw-noch-nicht-alle-befehle-gelernt-hat.de

    Ich glaube ich werd mir so ne Seite erstellen und immer posten wenn so eine Antwort kommt... Ich habs satt.

    Ich versuche das jetzt mal den Code zu ändern...

    Gruß
    c.nub

    *edit*
    Wie funktioniert diese Bedingung in der*** while Schleife? Wann kommt man rein/raus? Wie lange läuft sie?

    ***

    while (in[index])
    {
    }
    


  • c.nub schrieb:

    Wie funktioniert diese Bedingung in der*** while Schleife? Wann kommt man rein/raus? Wie lange läuft sie?

    while (in[index])
    {
    }
    

    das reicht sogar schon. while(in[index]) ist gleichbedeutend mit while(in[index] != 0)
    die schleife läuft so lange, wie sie zeichen im string findet (als zeichen gilt jeder wert ungleich 0).
    🙂



  • @ Mister Sonderzeichen:
    90% deiner Antwort war unnötig... auf gut Deutsch = Mist.

    Hehe. Mach dir nichts draus, deshalb wirst du eben nicht zensiert. 🙂

    Ich versuche das jetzt mal den Code zu ändern...

    Halte ich für eine gute Idee. Mach es so wie fricky, das ist leicht zu verstehen und funktioniert. Die mach_sternchen() würde mit Array-Ausdrücken so aussehen:

    void mach_sternchen (char in[], char out[])
    {
        int i = 0, j = 0;
    
        while (in[i])
        {
            out[j++] = '*';
            out[j++] = ' ';
            out[j++] = in[i++];
            out[j++] = ' ';
        }
        out[j++] = '*';
        out[j] = 0;
    }
    

    (Ungetestet)
    Arrays werden in Wahrheit gar nicht an Funktionen übergeben, es sieht nur so aus: eigentlich sind es Zeiger. Und Zeiger darf man verändern. Wenn man in und out aber mit den Array-Operationen bearbeiten will, wird man sie als unveränderlich behandeln. Deshalb habe ich i und j als Index-Zahlen einführen müssen.



  • Danke an alle, also das mit der Schleife dachte ich mir schon. Der Code ist wirklich einfacher als ich dachte, und ist wirklich leicht zu verstehen.
    Aber es ist unnötig nach der Schleife der Variable out nochmal einen Stern zuzuweisen.

    Es funktioniert wunderbar.

    Gruß c.nub



  • Ach ja: falls dich die ++ stören: eine Zeile wie

    out[j++] = in[i++];
    

    sieht dann zB so aus:

    out[j] = in[i];
    i = i + 1;
    j = j + 1;
    

    Aber das weisst du ja schon.

    Ganz was anderes: wäre es nicht prinzipiell einfacher, die Datei zeichenweise einzulesen, nach jedem Zeichen die Trenner auszugeben? Damit könntest du dir die bösen Zeilenpuffer sparen. Also etwa so:

    // in main():
    ...
    case 1:
        lfn = fopen ("file.txt","r");
        if (!lfn)
        {
            printf ("Datei konnte nicht geoeffnet werden!");
            break;
        }
        schreib_sternchen(lfn);
        fclose(lfn);  /* <-- sollte man nicht vergessen */
        break;
    ...
    
    // wobei schreib_sternchen() diesmal so definiert ist:
    void schreib_sternchen(FILE *fp)
    {
        int c;
    
        while ((c = getc(fp)) != EOF)
            if (c == '\n')
                putchar(c);
            else
                printf("* %c ", c);
        puts(" *");
    }
    

Log in to reply