Zeichenketten einlesen



  • Hallo Leute,

    bei folgendem Task komme ich nicht weiter.

    Die Aufgabe ist: Es sollen 2 Zeichenketten eingelesen werden. Falls die zweite Zeichenkette ein Teil der ersten Zeichenkette ist, soll die Position der zweiten Zeichenkette in
    der ersten Zeichenkette und “Ja “ ausgegeben werden. (Mit gets aus stdio.h)

    Die Funktion strstr(char * str1, const char * str2) aus string.h referenziert den Speicherplatz wo str2 in str1 erscheint.
    Beispiel: Eingabe: (str1=) acbdefgh (str2=) def
    Ausgabe: Ja Position 4
    Eingabe (str1=) acbdefgh (str2=) pqr
    Ausgabe: Nein
    Das Programm soll so erweitert werden, dass es dann auch die weiteren Positionen von str2 in str1 angibt.

    ich habe:

    function(string, string2)
    int i;
    size_string n = sizeof(string) / sizeof(char)
    size_string2 n = sizeof(string2) / sizeof(char)
    for (i = 0; i < size_string; ++i)
    {
    	boolean exists = true	
    	for(j = 0; j < size_string2; ++j){
    		if(i+j >= size_string)
    			exists = false;
    			break;
    		if(string[i+j] != string2[j])
    			exists = false;
    			break;
    	}
    	if(exists)
    		print(Exists in position %d, i)
    }
    
    
    

    der code ist aber nicht valid.
    Ich bin sehr froh über Hilfestellung.

    LG



  • @Switch_24 sagte in Zeichenketten einlesen:

    aber nicht valid.

    Stimmt. Dann schlag nach, wie man eine Funktion schreibt.



  • es geht hier um semantische Fehler, nicht die der Syntax. Es ist hier kein Strukturfehler denke ich.



  • Zeig Deinen echten Code. Schreib' in eine Zeile vor Deinem Code ``` und in eine Zeile nach Deinem Code ```. Alternativ markiere Deinen Code und klicke auf das </> in der Symbolleiste über dem Textfeld.
    Zeit ein komplettes, kompilierbares Programm und beschreibe woran Du Schwierigkeiten hast.



  • Tipp: in der Aufgabe wird die Funktion strstr doch bereits genannt. Versuche doch einfach mal, die auch zu verwenden! Siehe auch https://en.cppreference.com/w/c/string/byte/strstr



  • Aber zum Teufel nochmal vergiss gets(). Nimm fgets() verdammt nochmal.

    Aber selbst dann, wenn man fgets() nimmt ist es in C nicht trivial festzustellen ob die Eingabe in den Puffer gepasst hat. Mit der Aufgabe zwei Strings nacheinander einzugeben hast Du eigentlich schon die A***karte gezogen. Du hast jetzt zwei Optionen: Tun was meistens funktioniert (und dein Lehrer wahrscheinlich dummerweise akzeptiert) oder es ernsthaft, foolproof anzugehen und Dir gedanken über Streams zu machen.



  • So, jetzt habe ich ein neues Schema.

    #include <string.h>
    #include <stdio.h>
    int main(char*str, char*substr) 
    {
          
          printf("Eingabe von String1 und String2:");
            scanf("%s %s",str,substr);
     
    
      
        char* pos = strstr(str, substr);
        
     
          
        if(pos) {
            printf("Ja '%s' ist in '%s' an Position: %ld\n", substr, str, pos - str);
        } else {
            printf("nein'%s' ist nicht in '%s'\n", substr, str);
        }
    
       return 0;
    }
    
    
    

    vom Verständnis finde ich das jetzt einleuchtender.
    Was ist trozdem falsch?



  • @Switch_24 sagte in Zeichenketten einlesen:

    int main(char*str, char*substr) 
    

    Das ist keine gültige Signatur für main(). Selbst wenn ... wo soll denn der Speicher auf die die beiden Zeiger zeigen jetzt magischerweise erscheinen?
    Nebenbei: scanf() mit dem Formatstring %s ohne eine Größe (width) anzugeben ist ein No-Go.



  • Also eine neue Funktion? Wofür brauche ich dann die main() , der Speicher ist doch "da" ohnehin?



  • @Switch_24 sagte in Zeichenketten einlesen:

    Wofür brauche ich dann die main()

    main() ist der entry point in Dein Programm. Diese Funktion wird von der Runtime Library aufgerufen wenn Dein Programm ausgeführt wird.

    @Switch_24 sagte in Zeichenketten einlesen:

    der Speicher ist doch "da" ohnehin?

    int *foo;
    

    Das ist ein Zeiger. Ein uninitialisierter. Egal wieviel Speicher in Deinem Rechner steckt, der zeigt erstmal irgendwohin und der Wert, die Adresse, dieses uninitialisierten Pointers ist zu nichts zu gebrauchen. Wenn Du Zeichenketten einlesen willst würde ich ein Array of char vorschlagen.



  • Ich bin gerade etwas verwirrt und blicke auch nicht mehr so recht durch, sitze schon recht lange daran. Also char *str[5] z.b?



  • @Switch_24 sagte in Zeichenketten einlesen:

    char *str[5]

    Das ist ein array of 5 pointers to char. was sagen denn Deine Unterlagen bzw. Deine Mitschrift?



  • @Swordfish aus meinen Aufzeichnungen wird es leider nicht so ersichtlich..



  • ich lerne es mehr bei doing it yourself, also beziehe ich mich auch youtube oder das internet. Also ich habe nichts, wo ich mich konkret darauf beziehen kann



  • Dann solltest du mal ausprobieren / nachlesen, was der Unterschied ist zwischen:

    char x;
    char *x;
    char x[100];
    char *x[100];
    char (*x)[100];
    

    https://cdecl.org/ kann dabei helfen.

    Du brauchst Speicherbereich für deine beiden einzulesenden Strings. Mein Rat für den Anfang wäre aber erst einmal: leg die Strings in deinem Programm einfach fest, also zum Beispiel:

    const char text[] = "Dies ist der lange lange String";
    const char suchstring[] = "lang";
    

    Und entwickle dann eine Funktion, die eben alle "lang"-Positionen innerhalb des Textes findet. Erst danach kümmere dich um die Eingabe.

    Das hat mehrere Vorteile:

    1. Das Problem ist einfacher.
    2. Du kannst das leicht testen und brauchst nicht immer den String neu einzugeben
    3. Durch Trennung der Eingabe von der Verarbeitung wird deine Funktion vermutlich reusable. Denn wer weiß, ob du immer von der Konsole einlesen willst oder ob die Daten später nicht mal aus einem grafischen Eingabebereich in einem Fenster kommen.
    4. Du musst dich erstmal nicht damit herumschlagen, wie du sicherstellst, dass dein Eingabepuffer groß genug für die Eingabe ist. Zu gets hat @Swordfish ja schon was gesagt. Hier der Link: https://en.cppreference.com/w/c/io/gets - lies die "Notes"! Wenn du dich erstmal gar nicht um das Einlesen kümmerst, hast du auch kein Problem damit. Klingt banal, aber oft ist es gut, Problemen einfach direkt aus dem Weg zu gehen und andere (=andere Personen, andere Teile des Programms) sich darum kümmern zu lassen, die sich damit auskennen/die dafür speziell gemacht wurden.

    Bonusfragen für dich. Wie unterscheiden sich:

    char suchstring[100] = "lang";
    char suchstring[] = "lang";
    char *suchstring = "lang";
    

    Und wo kann man überall const dazuschreiben? Wo sollte man? (und falls du auch an C++ Interesse haben solltest: gibt es hier ggf. einen Unterschied?)



  • @Switch_24 sagte in Zeichenketten einlesen:

    (Mit gets aus stdio.h)

    Gibt es die Funktion überhaupt noch?

    Wie alt sind denn deine Unterlagen?


  • Mod

    Jupp, gets wurde im fernen Jahre 2011 abgeschafft. Und zwar ganz komplett, nicht bloß deprecated. In C++ gab es noch eine Gnadenfrist bis 2014. Bald werden Kinder mit der Programmierung beginnen, die nicht geboren waren, als gets noch existierte.

    @Switch_24 : Da steckt gewiss eine Lektion über die Gefahren von wilden Internetquellen darin. Besonders wenn es um recht gnadenlose Sprachen wie C geht.



  • @wob sagte in Zeichenketten einlesen:

    Dann solltest du mal ausprobieren / nachlesen, was der Unterschied ist zwischen:

    char x;
    char *x;
    char x[100];
    char *x[100];
    char (*x)[100];
    

    https://cdecl.org/ kann dabei helfen.

    How To Read C Declarations



  • danke schonmal soweit, ich bin vorangekommen