Bitte um Hilfe!!!



  • Hans Mustermann
    Ingo Mustermann
    Trude Musterfrau
    Trude Mustermann
    Gerda Muster
    Wird das Programm

    des oben ist zb die Textdatei jetzt versuch ich ein Programm zu schreiben was über die Komandozeile wenn ich zb Muster eingebe mir "1 Treffer " ausgibt da Muster nur einmal vorkommt ich hab schon mal angefangen aber komm nicht weiter mit dem übergeben der textdatei oder wie ich darauf prüfe

    Mein Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    int main(int argc, char *argv[])
    {
    FILE *fp;
    int i;

    fp = fopen("C:\\Users\\Nico\\Desktop\\testat-8-namen.txt","r");
    
    
    if(fp == NULL){
    
        printf("Deiteifehler\n");
        return 1;
    
    }else{
        for(i=0; i < argc;i++){
    
    
            printf("%d Treffer\n", i,argv[i]);
            system("cls");
        }
    }
    return 0;
    

    }

    Danke schon mal im Vorraus



  • also grundsätzlich liest du so lange zeichen ein, bis zu auf einen zeilentrenner stößt.

    dann suchst du nach dem anfangsbuchstaben des gesuchten wortes.

    zum schluss überprüfst du, ob der teil der zeichenkette mit der vergleichszeichenkette übereinstimmt bzw. beide gleichzeitig zu ende sind.
    wenn ja: zähler um 1 erhöhen.


  • Gesperrt



  • #include <stddef.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    
    void usage(char const *name)
    {
    	printf("Usage: %s [filename] [needle]\n\n", name);
    }
    
    int fpeek(FILE *stream)
    {
    	int ch = fgetc(stream);
    	ungetc(ch, stream);
    	return ch;
    }
    
    int main(int argc, char **argv)
    {
    	if (argc != 3) {
    		usage(argv[0]);
    		return EXIT_FAILURE;
    	}
    
    	char const *filename = argv[1];
    	char const *needle = argv[2];
    
    	FILE *input = fopen(filename, "r");
    	if (!input) {
    		fprintf(stderr, "Couldn't open \"%s\" for reading :(\n\n", filename);
    		return EXIT_FAILURE;
    	}
    
    	size_t needle_length = strlen(needle);
    	char *buffer = malloc(needle_length + 1);
    	if (!buffer) {
    		fclose(input);
    		fputs("Not enough memory :(\n\n", stderr);
    		return EXIT_FAILURE;
    	}
    
    	char *format = malloc(1);
    	if (!format) {
    		fclose(input);
    		free(buffer);
    		fputs("Not enough memory :(\n\n", stderr);
    		return EXIT_FAILURE;
    	}
    
    	int format_length = snprintf(format, 1, "%%%zus", needle_length);
    	if (format_length < 0) {
    		fclose(input);
    		free(format);
    		free(buffer);
    		fputs("snprintf() failed :(\n\n", stderr);
    		return EXIT_FAILURE;
    	}
    
    	char *temp = realloc(format, format_length + 1);
    	if(!temp) {
    		fclose(input);
    		free(format);
    		free(buffer);
    		fputs("Not enough memory :(\n\n", stderr);
    		return EXIT_FAILURE;
    	}
    
    	format = temp;
    	if (snprintf(format, ((size_t)format_length) + 1, "%%%zus", needle_length) < 0) {
    		fclose(input);
    		free(format);
    		free(buffer);
    		fputs("snprintf() failed :(\n\n", stderr);
    		return EXIT_FAILURE;
    	}
    	
    	size_t count = 0;
    
    	while (fscanf(input, format, buffer) == 1) {
    		int next_ch = fpeek(input);
    		if (next_ch != EOF && !isspace((char unsigned) next_ch)) {
    			fscanf(input, "%*s");
    			continue;
    		}
    
    		if (strcmp(buffer, needle) == 0)
    			++count;
    	}
    
    	printf("Found \"%s\" in \"%s\" %zu times\n\n.", needle, filename, count);
    
    	free(format);
    	free(buffer);
    	fclose(input);
    }
    

    und nu?


  • Gesperrt

    @Swordfish sagte in Bitte um Hilfe!!!:

    und nu?

    Die geilsten Programmierer schreiben die dicksten Programme, oder so ähnlich ging der Spruch. 😂



  • @RBS2 Hm. Dick. Ja, das Aufräumen im Fehlerfall könnt' man mit goto auch schöner machen. Dann wärs nicht so dick.


  • Gesperrt

    @Swordfish sagte in Bitte um Hilfe!!!:

    @RBS2 Hm. Dick. Ja, das Aufräumen im Fehlerfall könnt' man mit goto auch schöner machen. Dann wärs nicht so dick.

    Ich sehe mit Freuden, dass du bald den Pfad der Erleuchtung finden wirst. Jedenfalls entwickelst du das Gespür dafür.
    http://people.cs.pitt.edu/~zhangyt/teaching/cs1621/goto.slides.pdf



  • @RBS2 Ich bin weder eine Kerze noch dick und goto ist toll.

    ich habe aber schon davon gehört, daß sich so manche auch mal eine geile Kerze ... ach, lassen wir das



  • das aufräumen im fehlerfall kann man auch weglassen, wenn man das programm sowieso beendet (ganz böse 😀 ), oder man erstellt sich halt eine funktion, die das macht, und schon hat niemand mehr was zu meckern.


  • Gesperrt

    @Wade1234 sagte in Bitte um Hilfe!!!:

    das aufräumen im fehlerfall kann man auch weglassen, wenn man das programm sowieso beendet (ganz böse 😀 ), oder man erstellt sich halt eine funktion, die das macht, und schon hat niemand mehr was zu meckern.

    das kann man auch weglassen, wenn man auf malloc/realloc verzichtet, also einen statischen buffer verwendet. wer einzelne wörter einliest, darf getrost eine maximallänge voraussetzen.



  • @RBS2 sagte in Bitte um Hilfe!!!:

    das kann man auch weglassen, wenn man auf malloc/realloc verzichtet, also einen statischen buffer verwendet.

    @Wade1234 spielt wohl eher darauf an, daß das OS sowieso klar Schiff macht.

    @RBS2 sagte in Bitte um Hilfe!!!:

    wer einzelne wörter einliest, darf getrost eine maximallänge voraussetzen.

    Das sind die berühmten letzten Worte vor einem Buffer-overflow. Vor allem weiß ich ja im vorliegenden Fall ganz genau, wieviel ich maximal lesen will. Wörter länger als needle interessieren sowieso nicht.


  • Gesperrt

    @Swordfish sagte in Bitte um Hilfe!!!:

    Das sind die berühmten letzten Worte vor einem Buffer-overflow.

    Nimmste fgets(). Da flowed nix over. ☺



  • @RBS2 Mhm. Und dabei zerstückelst mit gut glück das gesuchte wort. Komm. Troll dich.


  • Gesperrt

    @Swordfish sagte in Bitte um Hilfe!!!:

    Und dabei zerstückelst mit gut glück das gesuchte wort.

    wenn das letzte zeichen des buffers kein whitespace ist, kopierst du die zeichen zwischen dem letzten whitespace und buffer-ende nach vorn (memcpy) und füllst den rest des buffers mit dem nächsten fgets()-call auf. dann kannste wieder strtok machen.

    das mag für dich vielleicht zu kompliziert sein, ist aber recht einfach. besser jedenfalls, als irgendwelche malloc-realloc-free-orgien.

    buffer-größe? nimm 1024. so lange wörter schreibt kein mensch. 😇


  • Gesperrt

    oder die fscanf-variante, kurz und knackig:

    void read_words (FILE *f) 
    {
        char x[1024];
        while (fscanf(f, " %1023s", x) == 1) {
            puts(x);
        }
    }
    

    gesehen auf stackoverflow.com.
    hat hoffentlich keinen overflow.



  • @RBS2 sagte in Bitte um Hilfe!!!:

    das mag für dich vielleicht zu kompliziert sein, ist aber recht einfach. besser jedenfalls, als irgendwelche malloc-realloc-free-orgien.

    Du findest also strtok()- und Herumkopierorgien besser als von Anfang an das zu lesen, was man braucht. Ja ne, klingt logisch ^^

    @RBS2 sagte in Bitte um Hilfe!!!:

    oder die fscanf-variante

    ... ist genau was ich mache. Nur eben mit passender Puffergröße.



  • @Wade1234 ok vielen dank ich melde mich für weitere Probleme falls ich auf welche zustöße


  • Gesperrt

    @Swordfish sagte in Bitte um Hilfe!!!:

    ... ist genau was ich mache.

    Bloß brauchst du fast 100 Zeilen dafür. 😺



  • @RBS2 Mein Physikprof hat immer gesagt: "Schreibarbeit ist keine Arbeit.". Für format ginge auch eine feste Größe ... dann sinds schon mal ~20 Zeilen weniger.

    Zeig doch deine tolle Variante ...


  • Gesperrt

    @Swordfish sagte in Bitte um Hilfe!!!:

    Zeig doch deine tolle Variante ...

    Hier, knapp 30 Zeilen:

    #include <stdio.h>
    #include <stdlib.h>
    #include <memory.h>
    #define STOP(x) {puts(x);exit(-1);}
    
    int main(int argc, char* argv[])
    {
        if (argc != 3)
            STOP ("1st arg: file name, 2nd arg: needle");
        FILE *fp = fopen (argv[1], "r");
        if (fp == 0)
            STOP ("Can't open ...");
    
        int n=0, found=0;
        char word[1024];
        while (fscanf(fp, " %1023s", word) == 1)
        {
            n++;
            if (!strcmp (word, argv[2]))
            {
                found++;
                printf ("\'%s\' is at pos. %d\n", argv[2], n);
            }
        }
        printf ("Found \'%s\' %d times.\n", argv[2], found);
    }
    
    

    Spuckt aus:

    'Sachverwalter' is at pos. 1
    'Sachverwalter' is at pos. 9
    'Sachverwalter' is at pos. 10
    Found 'Sachverwalter' 3 times.

    beim Input:

    Sachverwalter
    hallo das is ein text mustermann
    muster
    Sachverwalter Sachverwalter
    pluster


Anmelden zum Antworten