Wortsuche in einem Text, mit zusätzlicher Schleife



  • Hallo zusammen, ich hoffe ihr könnt mir als Anfänger helfen.
    Wir sollen in c++ etwas erstellen und ich habe die Aufgabe ein Programm zu programiieern, dass:

    1. einen Text einliest, welchen ich jeweils aktuell eingebe.
      z.B. "Die Tastatur ist kaputt, deshalb kann ich nicht richtig schreiben."

    2. nach Eingabe des Textes soll das Programm nach einem vordefiniertem Wort suchen.
      z.B. das Wort, dass durch das Programm gesucht werden soll ist "Tastatur"

    3. Jede Zeile wird mit "Enter" bestätigt und es gibt einen neuen Zeilenvorschub.

    4. Danach prüft das Programm, ob das Wort dabei ist.

    5. Ist das Wort nicht dabei, kann ich die nächste Zeile vollschreiben und mit "Enter" beendigen.

    6. das soll immer so weiter gehen, bis eine bestimmte Speichergröße erreicht wird, z.B. 0,5 kByte

    7. Bedingung 1: Ist das Wort dabei, soll das Programm beendet werden.

    8. Bedingung 2: wird die nächste Zeile als Leerzeile gestartet, soll das Programm beendet werden

    9. Bedingung 3: wie schon geschrieben, soll die max. Speichergröße 0,8 kByte betragen

    10. In jedem Fall wird vor dem Programmende der Inhalt des Gesamttextpuffer dem Benutzer angezeigt.

    11. Es soll eine String Funktion verwendet werden, aus der C++ Standardbibliothek.

    12. Der Speicherplatz soll statisch festgelegt werden.
      13 Wenn eine Zeile (ein C++-String mit abschließender 0x00) in den Gesamttextpuffer
      geschrieben wurde, muß diese 0 mit einem "Zeilenvorschub" (ASCII-Zeichen:
      0x0d+0x0a) überschrieben werden!

    Mir fehlt absolut der Ansatz wie ich an die Sache rangehen kann und hoffe dass ihr mir helfen könnt.



  • #include <cstddef>   // std::size_t
    #include <cstring>   // std::strcpy()
    #include <string>    // std::string, std::getline()
    #include <iostream>  // std::cin, std::cout
    
    int main()
    {
        constexpr std::size_t  whole_input_size               { 820 };   // 820 bytes =~ 0.8 * 1024 bytes + 1 for terminating zero
        char                   whole_input[whole_input_size]  {};
        std::size_t            whole_input_length             {};
        char const * const     word_to_find                   { "Tastatur" };
    
        for (std::string line; whole_input_length < whole_input_size - 1 && std::getline(std::cin, line) && line.length();) {
            // append line to whole_input buffer:
            line += "\r\n";
            std::size_t whole_input_space_left = whole_input_size - 1 - whole_input_length;
            std::size_t num_chars_to_copy = line.length() <= whole_input_space_left ? line.length() : whole_input_space_left;
            std::strncpy(whole_input + whole_input_length, line.c_str(), num_chars_to_copy);
            whole_input_length += num_chars_to_copy;
    
            // find word_to_find:
            if (line.find(word_to_find) != std::string::npos) {
                std::cout << '"' << word_to_find << "\" found in the last line entered :)\n\n";
                break;
            }
        }
    
        // output whole_input:
        std::cout << "Your input:\n" << whole_input << '\n';
    }
    

    Aber es ist wieder einmal eine ziemlich sinnfreie Aufgabe die ausdrücklich nicht wirklich schönes C++ und künstliche Beschränkungen fordert. Bitte besorg' Dir - falls Du nicht nur durch diese Vorlesung irgendwie durchkommen willst sondern wirklich was lernen willst - ein gutestm Lehrbuch. Threads über Bücher zu C++ findest Du hier im Forum zur Genüge.



  • Danke erstmal für das Programmbeispiel.
    Kurze Erläuterung warum ich es mache. Du hast zum einen Recht, es ist Bestandteil meines Elektro-Studiums und ich hatte bisher mit Programmieren nichts am Hut. C++ ist nun mal gefordert. Ich versuche schon verschiedene Tutorials zu verfolgen, aber dazu findet man auch verschiedene Meinungen.
    Mein Hauptproblem ist, dass es ein Fernstudium ist und ich hauptberuflich arbeite. Der Kontakt zu den Professoren ist absolut eingeschränkt und per E-mail zu kommunizieren ist nicht einfach.
    Ich möchte durch die Vorlesung durchkommen, aber nicht irgendwie.
    Ich nehme jeden Hinweis offen entgegen und hoffe hier Hilfe zu finden.
    Ich weiß das viele Themen sich gleichen oder ähnlich sind und immer wieder kommen.
    Vielleicht hat jemand noch gute Ratschläge was Literatur oder Online-Tutorials angeht, dann her damit.

    Trotzdem danke für deine Hilfe.
    Ich würde trotzdem gerne Fragen dazu stellen, würde es aber erstmal probieren und nachvollziehen.
    MfG Ulf



  • @ulle1749 sagte in Wortsuche in einem Text, mit zusätzlicher Schleife:

    Ich würde trotzdem gerne Fragen dazu stellen, würde es aber erstmal probieren und nachvollziehen.

    Ja, mach' das. Ich habe mir Mühe gegeben die Variablen so selbsterklärend wie nur möglich zu benennen. Der Grundgedanke ist daß so lange eine Zeile gelesen wird wie

    1. Platz im Puffer für die Gesamteingabe ist
    2. std::cin nicht in einen Fehlerzustand geht
    3. die Eingabe nicht "leer" ist. (line.length() != 0).

    Die immer wieder Anhängerei an das bereits in whole_input stehende ist halt ein krampf, sollte aber nachvollziehbar sein.



  • Moin moin,

    es gibt eine Fehlermeldung:

    C4996 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

    ich hatte geändert in den strncpy_c, dort kam aber folgende Fehlermeldung
    C2660 "strncpy_s" Funktion akzeptiert keine 3 Argumente
    E0304 Keine Instanz von überladene Funktion "strncpy_s" stimmt mit der Argumentliste überein

    Hast du eventuell noch eine Idee?
    Beide Fehlermeldungen beziehen sich auf die selbe Zeile.



  • #define _CRT_SECURE_NO_WARNINGS
    

    vor dem Einbinden von <cstring>

    oder strncpy_s() mit den korrekten Parametern nehmen.



  • @Swordfish Ich fürchte allerdings, der Prof will C ohne ++ sehen. Sprich der wird std::string als cheat werten.



  • @Tyrdal Das mag ja sein. Ich glaube auch nicht daß der OP die Aufgabenstellung 1:1 gepostet hat. Aber da ich nichts anderes hatte bin ich davon ausgegangen was halt dasteht. Wenn es wirklich so schwammig ist wie vom OP wiedergegeben würde ich den Aufgabensteller einfach angrinsen und sagen: "Davon steht in der Aufgabe nichts und ich soll doch eigentlich C++ lernen."



  • @Swordfish In der Aufgabe steht:

    "Es soll eine String Funktion verwendet werden, aus der C++ Standardbibliothek."

    Was auch immer das bedeuten soll. eine = mindestens eine? Oder das "k" von "keine" nicht abgeschrieben? Was soll uns das Komma sagen? Ist es für eine besondere Betonung da?

    (in keiner anderen Sprache habe ich so oft von Aufgaben gehört, die man ohne die jeweilige Standardbibliothek lösen soll)



  • @wob sagte in Wortsuche in einem Text, mit zusätzlicher Schleife:

    in keiner anderen Sprache habe ich so oft von Aufgaben gehört, die man ohne die jeweilige Standardbibliothek lösen soll

    Naja...
    Das hat Vorteile und Nachteile.

    Ein Vorteil einer Lehr-/Lernmethode wo man anfangs auf die Standard-Library verzichtet ist dass man lernt sich zu helfen wenn's mal nix fertiges gibt. In anderen Sprachen sehe ich sehr häufig dass erfahrene Programmierer die einfachsten Dinge nicht auf die Reihe bekommen. Sowas wie einen String Zeichen für Zeichen durchzugehen um damit irgendwas zu machen ist etwas was denen nicht mal in den Sinn kommt. Dafür muss es was fertiges geben. Und wenn nicht, dann ... na dann geht's halt einfach nicht. Bei C++ sehe ich das nicht so oft. Bei C noch seltener.

    Ein Nachteil ist dass man die Leute dazu konditioniert an NIH zu leiden. Was man wiederrum in anderen Sprachen seltener sieht.



  • @hustbaer Hm. Ich denke, dass ein frühes "wir müssen alles von Hand machen" abschreckend ist. Nichts geht automatisch. Ständig stürzt das eigene Programm ab. Man braucht schon Durchhaltevermögen.

    Wenn ich gleich mit std::string anfange, kann ich leicht einfache "Hallo Welt"-Programme schreiben. Wenn ich dann halbwegs sicher verstanden habe, wie "if" und Schleifen funktionieren, kann man dann trotzdem noch C-Strings lehren. Wenn man dann noch mit while (*str++) arbeitet, braucht man auch noch Pointer. Ist für mich daher kein Thema, mit dem man vor std::string anfangen sollte.

    Das ist zumindest meine Meinung.



  • @wob
    Die Reihenfolge ist wieder ne andere Sache.
    Mir geht's mehr darum dass diverse Dinge oft gar nicht gelehrt bzw. gelernt werden.

    Bin mir auch nicht sicher was für C++ im Endeffekt besser wäre. Also Aufgaben die man "zu Fuss" programmieren muss ja oder nein. Weil eben wie gesagt beides Vor- und Nachteile hat.

    Ich denke in Mix aus beidem wäre gut. Also z.B. Aufgaben wo verlangt wird dass ein bestimmter Teil 1x mit Verwendung der Standard-Library und 1x ohne Verwendung der Standard-Library implementiert wird. Dadurch lernt man wie man "zu Fuss" programmiert, aber gleichzeitig auch wie man es "normal" machen würde.





  • @Swordfish Was hat das mit der Frage zu tun ob es Sinn macht zu lernen wie man "low-level" Programmiert, also Ding ohne Zuhilfenahme der Standard-Library löst?
    Im Prinzip geht's dabei doch bloss darum wie man Algorithmen implementiert.
    Wenn man strstr oder std::search nicht selbst implementieren kann, dann ist das mMn. eine krasse Einschränkung.

    Zu lehren wie das geht, hat mMn. nichts mit "teaching C" zu tun.



  • Kennst Du denn den Beitrag?



  • 🙂
    Schimpft sie darin auch auf low-level Zeugs?
    Ich mag die Tante eigentlich, aber wenn sie anfängt zu predigen dass man nicht mehr lehren sollte wie man mit Zeigern arbeitet und Algorithmen implementiert, dann überleg ich mir das nochmal.



  • @Swordfish sagte in Wortsuche in einem Text, mit zusätzlicher Schleife:

    Kennst Du denn den Beitrag?

    Ich hatte mir den Vortrag damals komplett angeschaut und zum Beispiel „Accelerated C++“ wird das auch gut umgesetzt. Nur ist eben auch das Problem, dass man immer noch in C++ einige LowLevel Dinge beherrschen muss, um sinnvoll C APIs kapseln zu können. Was nützt es mir, wenn ich im Stile von „Accelerated C++“ C++ gelernt habe, aber dann z.B. die MySQL C Library nutzen muss (es ist die Tage ja mal wieder so ein Thread aufgepoppt) und dann nicht weiß, dass ich da ganz schnell SQL Injections produzieren kann, wenn ich da nicht vorsichtig bin.

    P.S. Die PostgreSQL C Library ist deutlich einfacher und sicherer nutzbar, die kennt seit Jahren eine sichere Query Function, die ohne Prepared Statements auskommt.



  • @hustbaer sagte in Wortsuche in einem Text, mit zusätzlicher Schleife:

    🙂
    Schimpft sie darin auch auf low-level Zeugs?
    Ich mag die Tante eigentlich, aber wenn sie anfängt zu predigen dass man nicht mehr lehren sollte wie man mit Zeigern arbeitet und Algorithmen implementiert, dann überleg ich mir das nochmal.

    Das tut sie nicht. Sie sagt explizit, dass man das selbstverständlich nutzten und lehren kann, sie sagt nur, dass das nicht an den Anfang gehört.



  • @john-0 sagte in Wortsuche in einem Text, mit zusätzlicher Schleife:

    aber dann z.B. die MySQL C Library nutzen muss (es ist die Tage ja mal wieder so ein Thread aufgepoppt) und dann nicht weiß, dass ich da ganz schnell SQL Injections produzieren kann, wenn ich da nicht vorsichtig bin.

    Nur zur Sicherheit: das, was diese Woche hier diskutiert wurde, war eine Library für den Arduino von einem einzelnen Autoren, nicht eine offizielle MySQL-Library. Selbstverständlich kann die offizielle Library Platzhalter verarbeiten - mit prepared Statements: https://dev.mysql.com/doc/refman/8.0/en/sql-prepared-statements.html (ok, dein Punkt war, dass du das mit nur einem Call haben willst. Gut. Aber auf jeden Fall ist das so besser als mit sprintf).



  • @wob sagte in Wortsuche in einem Text, mit zusätzlicher Schleife:

    … Selbstverständlich kann die offizielle Library Platzhalter verarbeiten - mit prepared Statements: …

    Ja, das ist mir seit Jahren bekannt. Nur kenne ich MySQL noch aus der Zeit als das noch nicht ging und damals PostgreSQL schon PQexecParams kannte. Das wurde bei PostgreSQL 7.4 in das Protokoll eingeführt. Vorher musste man bei beiden FOSS RDBMS sehr vorsichtig beim Escapen sein, dass man kein Unfug anstellte.

    Mich wundert es nur, dass man bei MySQL/MariaDB es in fast 20 Jahren noch immer nicht geschafft hat eine vergleichbare Funktion in die Library zu integrieren.


Anmelden zum Antworten