Zeichen an Position im String löschen ohne CRT-Funktionen (elementar)



  • Hallo zusammen,
    ich möchte eine Funktion schreiben. Zuerst soll die Länge des Strings gezählt werden, dann soll der String gedruckt werden. Nun möchte ich an einer bestimmten Stelle des Strings ein Zeichen löschen. Das Problem ist nach durchlauf meiner while Schleife um die Länge des Strings zu zählen ist mein String "leer" und somit ist auch kein Zugriff auf eine Position im String mehr möglich.
    Gibt es eine möglichkeit den String wieder her zu stellen oder wie soll ich das anstellen?

    Danke schon mal im vorraus.

    Achso und wir sollen die Funktion auf elementare Weise selber programmieren, ohne auf Funktionen der CRT zurückzugreifen.

    int myStrChrDeleteByPosition(char *s, int pos)
    {
        char *t = s;																					// String
    	int i = pos;																					// Position und i für schleife
    
        printf("\nLöschen Sie ein Zeichen im Hauptstring mittels seiner Positionsangabe:\n\n");
    	printf("%s\n", t);
    	
    	while (*t != 0)
    	{
    		printf("%i", i);																			// Die ausgabe soll so erfolgen (vorgabe)
    		t++;
    		i++;
    	}
    	    
    	printf("\n\nBei welcher Position soll das Zeichen gelöscht werden? >");
        scanf("%i", &i);
    
    	t[i] = '\n';																					//position i löschen 
    
        printf("Das Zeichen an Position %i wurde gelöscht\n", i);
        printf("Drücken sie eine Taste zur Fortsetzung!");
        getchar(); getchar();
    
    	return 0;
    }
    


  • t=s?

    Das ist C Code.



  • @Platinumer Schau mal hier, mit Beispiel: https://en.cppreference.com/w/cpp/string/basic_string/erase

    Aber ich hab schon das Gefühl das dies als Übungsaufgaben von Hand geschrieben werden soll....

    Nimm aber cout/cin statt printf/... Oder du willst dies in C schreiben, dann bist du aber im falschen Forum.

    Ups. Hab nicht zuende gelesen. Sollt ihr selbst schreiben...



  • @Platinumer Deine Funktion bekommt doch schon die pos mit übergeben. Dein printf/scanf gehört dann in die main. Nicht in die Funktion die das Zeichen löschen soll.

    Schreib dies Bitte zu einem kompilierbaren Beispiel um. Mit main. Danke!



  • This post is deleted!


  • Okay das hat einwandfrei funktioniert 👍🏼 Danke
    2 Fragen hätte ich allerdings doch noch 😬

    1. Das t [ i ] = '\0'; löscht mir ab der Stelle i alles. Was muss ich eingeben das er mir nur dieses eine Zeichen an der Position i löscht?

    2. Um die while Schleife mit s++; laufen zu lassen muss mein s also mein char veränderbar also ein pointer *s sein.
      Ich habe in meiner main s allerdings als s[] = "string" definiert. Muss ich s zum pointer machen oder gibt es eine Möglichkeit in der while schleife Einfluss darauf zu nehmen.

    int _tmain(int argc, _TCHAR* argv[], _TCHAR** envp)
    {
        int e = -1;				// Eingabe
        char s[] = "string";
    	
    	char z[2] = "a";		// Zeichen das eingefügt werden soll
        int i = 0;				// Position
        do
        {   
            
            system("cls");                                                                                     //Zum wiederholen der Konsole
    
            printf("Auswahlmenü des Programms zum Test aller erstellten String-Funktionen\n");
            printf("=====================================================================\n\n");
            printf("Der Hauptstring ist aktuell durch folgenden String gegeben:\n");
    
            if (e == -1)
            {
                printf("(leerer String)\n\n");
            }
            else
            {
                printf("%s\n\n", s);
            }
    
            printf("        Hauptstring durch den Benutzer eingeben ......................... 1\n");
            printf("        Hauptstring (zu Kontrollzwecken) drucken ........................ 2\n");
            printf("        Länge des Hauptstrings ermitteln ................................ 3\n");
            printf("        Ein Zeichen im Hauptstring löschen .............................. 4\n");
            printf("        Ein Zeichen im hauptstring überschreiben ........................ 5\n");
            printf("        Ein zeichen in den Hauptstring einfügen ......................... 6\n");
            printf("        Irgendein Zeichen eines anderen Strings im Hauptstring finden ... 7\n");
            printf("        Einen (anderen) Teilstring im Hauptstring finden ................ 8\n");
            printf("        Einen anderen String ans Ende des Haupstring dranhaengen ........ 9\n\n");
            printf("        Programm beenden (auch mit der Eingabe von <CR>) ................ 0\n\n");
            printf("Ihre Eingabe >");
            scanf("%i", &e);
        
    
            switch (e)
            {
            case 1: stringEingabe(s);
                break;
            case 2: stringLaenge(s);
                break;
            case 3: myStrlen(s);
                break;
            case 4: 
    			
    			printf("\nLöschen Sie ein Zeichen im Hauptstring mittels seiner Positionsangabe:\n\n");
    			printf("%s\n", s);
    
    			while (*s != 0)
    			{
    				printf("%i", i);
    				s++;
    				i++;
    			}
    			printf("\n\nBei welcher Position soll das Zeichen gelöscht werden? >");
    			scanf("%i", &i); myStrChrDeleteByPosition(s, i);
    			
    			
    			break;
    		/*case 5: myStrChrSubstituteByPosition(s, i, z[0]);
    			break;*/
            default:
                break;
            }
        
        } while (e != 0);
    
        return 0;
    


  • @Platinumer Bin nicht so der c- Mensch. Der string ist dann imho eine Zeichenkettenkonstante und das ändern dürfte dann UB (undefiniertes Verhalten). Kann gehen, muss aber nicht. Hab da aber keine genaue Ahnung wie das ist bei C. Also egal ob * oder []. Dies ist ja nur ein Zeiger auf den konstanten string.

    Habe mir deinen code jetzt nicht angeguckt weil gerade keine Zeit.
    Du müsstest bei dem string ab pos immer das Zeichen pos+1 an pos schreiben. Inkl. dem nullbyte '\0'. Natürlich immer prüfen ob pos nicht evtl. zu groß ist... So ungefähr...



  • @Platinumer sagte in Zeichen an Position im String löschen ohne CRT-Funktionen (elementar):

    Du hast kein compilierbares Beispiel gepostet.

    2 Fragen hätte ich allerdings doch noch 😬

    1. Das t [ i ] = '\0'; löscht mir ab der Stelle i alles. Was muss ich eingeben das er mir nur dieses eine Zeichen an der Position i löscht?

    Das Null-Byte löscht rein gar nichts, sondern wird als Ende des Strings interpretiert. Wenn Du ein Zeichen aus dem String löschen willst, musst Du alle Zeichen um genau diese eine Position verschieben.

    1. Um die while Schleife mit s++; laufen zu lassen muss mein s also mein char veränderbar also ein pointer *s sein.
      Ich habe in meiner main s allerdings als s[] = "string" definiert. Muss ich s zum pointer machen oder gibt es eine Möglichkeit in der while schleife Einfluss darauf zu nehmen.

    Zu den Problemen in Deinem Code.

    • Die main Funktion entspricht nicht der Norm. int main () oder int main(int argc, char** argv) sind erlaubt, alles andere sind Compiler spezifische proprietäre Erweiterungen.
    • Man kann bei modernen 64Bit Systemen mit int und Felder über die man iteriert ganz schnell auf die Nase fallen. Deshalb immer size_t oder ssize_t verwenden. Der passende Typ für die Größe von Feldern ist size_t, wenn man einmal einen Typen für Differenzen braucht nutzt man ssize_t. Der Punkt ist wichtig.
    • Alle notwendigen includes fehlen.
    • Der von der angelegte String ist konstant und kann während der Laufzeit gar nicht verändert werden. Wenn Du das willst, musst kannst Du Speicher allozieren.

    Wie alloziert man Speicher?

    
    char const* const s = "string";
    size_t size_string = 1024;
    char * const vs = malloc(sizeof(char)*size_string);
    
    strcpy (vs, s);
    
    // sonstiger Code
    
    free(vs);
    
    


  • char s[] = "string"
    

    Dies ist beschreibbarer (lokaler) Speicher, denn es wird ein Array (als Kopie) mit strlen("string")+1 Zeichen angelegt (hier also 7).
    Nur bei const char *s = "string" darf man nicht den Inhalt verändern, da direkt das String-Literal beschrieben würde.
    @dirkski, @john-0: Oder bezieht ihr euch auf etwas anderes?



  • @john-0 Danke für die Antwort, also das Problem mit der Schleife habe ich gelöst indem ich eine extra Funktion geschrieben habe. Zerbreche mir grad nur noch den Kopf über "Zeichen aus dem String löschen". Bin dann auch drauf gekommen die Positionen zu verschieben mit einer for Schleife, aber komme einfach nicht drauf.
    compilierbares Beispiel kann ich dir jetzt nur mein ganzes Programm rein kopieren.
    Aber will hier jetzt auch nicht alles mit code zu spamen.



  • Warum wurde mein Beitrag geputzt? Ich hatte ja auch nix anderes gesagt, als das, was jetzt hier steht.



    • Der von der angelegte String ist konstant und kann während der Laufzeit gar nicht verändert werden. Wenn Du das willst, musst Du Speicher allozieren.

    Das ist falsch.
    Das Nachplappern von aufgeschnapptem Halbwissen fällt (Profis) sofort auf.
    Ein Stringliteral hat den Typ char[] und nicht const char[], hier ist also nichts konstant.
    Im Übrigen spricht der Standard nur von UB beim Schreibzugriff auf Stringliterale, er verbietet nicht ein Veränderung.
    Im konkreten Fall dient das Stringliteral sowieso nur als (flüchtige) Quelle für die Initialisierung des char[], und das ist natürlich sehr wohl veränderbar.



  • @Th69 sagte in Zeichen an Position im String löschen ohne CRT-Funktionen (elementar):

    Dies ist beschreibbarer (lokaler) Speicher,

    Exakt!
    Sorry Platinumer, ich habe zu lange nicht mehr rein in C programmiert.



  • @john-0 alles gut, bin ja am Ende auf ein Lösung gekommen und dankbar für jede Hilfe.
    Können da auch gerne gleich mal weiter machen 🙂
    Wenn ich ein Zeichen in den String einfügen möchte (nicht ersetzen), muss ich zuerst alle Zeichen vor der Position an der ich einsetzen möchte um eins nach vorne verschieben, dann Zeichen an der gewünschten Position einfügen und dann noch alle Zeichen nach der Position nach hinten verschieben, oder ?
    also for schleife - t[ i ] = zeichen - for schleife



  • @Platinumer sagte in Zeichen an Position im String löschen ohne CRT-Funktionen (elementar):

    Wenn ich ein Zeichen in den String einfügen möchte (nicht ersetzen), muss ich zuerst alle Zeichen vor der Position an der ich einsetzen möchte um eins nach vorne verschieben, dann Zeichen an der gewünschten Position einfügen und dann noch alle Zeichen nach der Position nach hinten verschieben, oder ?
    also for schleife - t[ i ] = zeichen - for schleife

    Nach vorne verschieben funktioniert nicht (d.h. Index -1 geht schon nicht) und wäre UB. Als String wird alles vom Anfang (Index 0) des Strings bis zum Null-Byte interpretiert. Z.B. char s[256] = "string"; definiert das Char-Array 256 Bytes groß, und initialisiert es mit dem String "string" plus Null-Byte. Dann kannst Du solange Zeichen einfügen, bis die Gesamtkapazität (inklusive Null-Byte) 256 erreicht.

    Das Einfügen funktioniert so, um an Stelle i ein Zeichen einzufügen verschiebt man vom Ende aus, alles eine Stelle nach „hinten“ bis Position ierreicht ist. Dort fügt man das neue Zeichen ein.



  • @Th69 Nein, absolut logisch was du schreibst. Kopf->Tischkante

    Sorry wg. der späten Antwort...


Log in to reply