C String umdrehen

T

thefy

Gast
Hallo Leute,
ich versuche mich gerade an einer kleinen C Aufgabe habe aber ein Problem mit den Pointern.

PHP:
#include <string.h>
#include <stdio.h>

void kopieren_und_umdrehen(char* output, char* input) {
    
    int a;
    int b;
    int c;
    
    a=strlen(input);
    

    for (b=a; b>=0; b--) {
        
        for (c=0; c<a; c++) {
            output[c] = *(input+b);
            break;
        }
        
    }
    

    
}

void dreieck_ausgabe(char* input) {
    
    int a;
    int b;
    int c;
    
    a = strlen(input);
    
    
    for (b=a; b>=0; b--) {
        for (c=0; c<b; c++) {
            printf("%c", *(input+c));
        }
        printf("\n");
    }
    
}

int main(int argc, char** argv) {
 
    // Kontrolliere, ob genug Argumente vorhanden sind
    // wenn nicht, RETURN -1
 
    char* input_string;          //pointing zu den input strings
   
    
    char output_buffer[1000];    //output speichern

    // Gehe hier durch jeden input string und verwende die zwei Funktionen
    
    int i;
    int d;
    
    for (i=1; i<argc; i++) {
        kopieren_und_umdrehen(output_buffer, argv[i]);
        
        for (d=0; d<strlen(argv[i]); d++) {
            
            
            printf("%c", output_buffer[d]);
        
        }
        
        printf("\n");
        
        dreieck_ausgabe(argv[i]);

    }
    

    return 0;
}


Ich will das alles mit Pointern lösen also ohne Arrays (außer argv).
Das Programm soll direkt von der Kommandozeile lesen.
z.B. tippt man ein: ./Programm Hallo Test und es soll folgendes ausgeben:

ollah
Hallo
Hall
Hal
Ha
H
tseT
Test
Tes
Te
T

Es soll das Wort also erst umdrehen und dann immer einen Buchstaben entfernen. Der zweite Teil in dem immer ein Buchstabe
entfernt werden soll funktioniert. Der obere in dem der String umgedreht wird funktioniert allerdings nicht.
Ich möchte die Werte aus der Umkehr Funktion mit Hilfe von Pointern in den Output Speicher ablegen und dann aus der Main Funktion ausgeben. Die Werte aus der "Dreieck Funktion" können direkt geprintet werden (das funktioniert ja auch).

Eigentlich verstehe ich die Funktionsweise von Pointern, aber ich denke dass in der Umkehr Funktion irgendwas nicht stimmt.
Ich würde mich freuen wenn jemand kurz drüber sehen könnte. Bitte keine kompletten Codes, da ich den Sinn dahinter verstehen möchte. Falls ich irgendwo einen Denkfehler bezüglich der Pointer habe würde ich mich über eine kurze allgemeine Erklärung freuen.

In der Umkehr Funktion habe ich im Moment noch " output[c] = *(input+b); " stehen. Ich möchte es aber eigentlich ohne einen Array zugriff lösen. Wenn ich aber output+c schreibe gibt der compiler eine Fehlermeldung aus.

Vom Aufbau möchte ich das Programm nicht ändern. Die Funktionen sollen also so bleiben.

Laut Aufgabe soll noch die Pointer Variable char* input_string; verwendet werden. Ich kann doch aber direkt mit argv auf die Adresse zugreifen (so wie ich es gemacht habe). Oder brauche ich diese Variable für etwas anderes?

Vielen Dank schon mal!
Gruß
 
Code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>


void reserve(char *quelle, char *ziel){

	char *p = quelle + strlen(quelle);	       // Ende des Strings finden
	while(p>=quelle)				// solange wir nicht wieder am Anfang sind
		*ziel++ = *--p;				// rueckwaerts kopieren, pointer weiterzaehlen


}

int main(int argc, char** argv){
int i;
char quelle[100];
char ziel[100];

while(1){

for (i=0; quelle[i]!=0x00; i++){
		printf("Bitte geben Sie einen Text ein:\n");
 	 	 fflush(stdout);
 	 	 fgets(quelle, 100, stdin);


reserve(quelle, ziel);

printf("Der bearbeitete Text lautet: %s\n", ziel);

}

}
return 0;
}

Das könnte vielleicht helfen ;)
 
Ich hab es mal eben gelöst, und versuche nur die nötigsten Hinweise zu geben.
output[c] ist das gleiche wie *(output+c).

Ansonsten ist dein Ansatz mit den zwei Schleifen in kopieren_und_umdrehen() unsinnig. Du brauchst nur eine Schleife und etwas Addition und Subtraktion bei den Pointern. Wenn es dir zu kompliziert ist in Pointern zu denken, dann sprich die Pointer erst mal wie Arrays an, und ersetze dann einfach die Syntax.
 
Ich möchte das Problem mit Zeigern statt mit Arrays lösen bedeutet etwa so viel wie ich möchte eine Symphonie und keine Sinfonie schreiben. Das sind nur unterschiedliche Schreibweisen für die selbe Sache.
 
Code:
#include <string.h>
#include <stdio.h>

int main() {
    char *str = "Lagerregal";
    char *rev = strrev(str);
    printf("%s <==> %s\n", str, rev);
    return 0;
}
:D
 
Umdrehen geht mit einer for next schleife indem du jeden einzelnen char des wortes von hinten nach vorne ausliest und mit printf %c ausgibst.
Das wort abschneiden erreichst du wieder mit einer for next schleife, indem du einfach das Wort mit '0' chars von hinten her auffüllst. Ausgabe mit %s oder println.
 
Hi,

du kannst printf auch dazu benutzen um nur eine bestimmte Länge deines strings auszugeben
Hier mal die Spezifikation

Code:
printf("%.*s", intstrlength, input_string);

intstrlength ist im diesem Fall die Variable, die die auszugebenen Länge angibt und wird hier beim * eingesetzt

wenn z.B. intstrlength = 3 und input_string = "Hallo" ist die Ausgabe -> "Hal"

char output_buffer[1000] kannste dir übrigens sparen


1. Programmargumente in einer Schleife abklappern und auf input_string verweisen
2. Funktion zum umdrehen siehe Kanibal
3. Funktion zum Zeichenweise ausgeben
4. zurück zu 1. bis alle Argumente abgearbeitet sind

müssten in deinem Fall 3 Argumente sein (argc)
0 = Programmpfad (weglassen)
1 = Hallo
2 = Test


mfg
 
Zuletzt bearbeitet: (nö)
Ok erst mal danke für die Infos!
Ich möchte das Problem gerne ohne die strrev Funktion lösen.

Der 2. Teil mit dem Ausgeben in "Dreiecksform" klappt. Lediglich das umdrehen mit Hilfe der for-Schleife will nicht so ganz.
Das Problem liegt denke ich in der Form wie ich die Buchstaben des umgedrehten Strings nacheinander in den output_buffer ablegen will und von diesem in der Main Funktion ausgeben will. Sie werden also nicht richtig abgespeichert.
Ergänzung ()

So ich habe jetzt noch mal mein Gehirn, trotz Kater:freak:, angestrengt und habe die Sinnlosigkeit der 2. for-Schleife entdeckt.
Ich habe es jetzt so gelöst:

Code:
void kopieren_und_umdrehen(char* output, char* input) {
    
    int a;
    int b;
    int c;
    int d;
    
    a=strlen(input);
    
    
    for (b=a; b>0; b--) {
        
        d = b-1;
        c = a-b;
            *(output+c) = *(input+d);
        
    }
}

Das mit der dreiecksform habe ich auch nicht richtig erklärt. Ich wollte eigentlich, dass nur jeweils ein Buchstaben entfernt wird.
Also z.B.: ./Programm computerbase

esabretupmoc
computerbase
omputerbase
mputerbase
puterbase
uterbase
terbase
erbase
rbase
base
ase
se
e


Das habe ich durch eine leichte Veränderung der for-Schleife hinbekommen.

Code:
void dreieck_ausgabe(char* input) {
    
    int a;
    int b;
    int c;
    int d;
    
    a = strlen(input);
    
    
    for (b=a; b>=0; b--) {
        for (c=a-b; c<a; c++) {
            printf("%c", *(input+c));
        }
        printf("\n");
    }
    
}


Vielen vielen Dank für die Hinweise!
Ergänzung ()

Jetzt habe ich doch noch eine allgemeine Frage. Ich habe den gesamten Code nun auf Pointer umgestellt.
Ich wollte der Pointer-Variable "input_string" argv zuordnen. Also: input_string =argv;
Allerdings lies das der Compiler nicht zu und habe es deshalb, wie im Code unten zu sehen, in die fortschleife der Main-Funktion eingebunden. Warum ist die erste Variante nicht möglich? argv ist nach meinem Wissen ein Array. Deshalb müsste argv doch der Adresse des ersten Wertes entsprechen. Laut Aufgabenstellung soll die Variable input_string verwendet werden, obwohl man gleich
argv nehmen könnte. Keine Ahnung was das für einen Sinn hat. Abgesehen davon gibt mir das Programm jetzt
merkwürdige ausgaben: z.B. ./Programm Das ist ein Test. Es klappt nur beim ersten Wort, bei den anderen nicht.

saD
as
s

tsi
t

nie

tseT

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

void kopieren_und_umdrehen(char* output, char* input) {
    
    int a;
    int b;
    int c;
    int d;
    
    a=strlen(input);
    
    for (b=a; b>0; b--) {
        
        d = b-1;
        c = a-b;
            *(output+c) = *(input+d);
        
    }
}

void dreieck_ausgabe(char* input) {
    
    int a;
    int b;
    int c;
    
    a = strlen(input);
    
    
    for (b=a; b>=0; b--) {
        for (c=a-b; c<a; c++) {
            printf("%c", *(input+c));
        }
        printf("\n");
    }
    
}

int main(int argc, char** argv) {
 
    // Kontrolliere, ob genug Argumente vorhanden sind
    // wenn nicht, RETURN -1
 
    char* input_string;          //pointing zu den input strings
   
    char output_buffer[1000];    //output speichern

    // Gehe hier durch jeden input string und verwende die zwei Funktionen
    
    int i;
    int d;
    
    for (i=1; i<argc; i++) {
        
        input_string = argv[i];
        kopieren_und_umdrehen(output_buffer, input_string);
        
        for (d=0; d<strlen(input_string); d++) {
            
            printf("%c", *(output_buffer+d));
        
        }
        
        printf("\n");
        
        dreieck_ausgabe(input_string+i);

    }
    
    return 0;
}
Ergänzung ()

Ok ich habe den Fehler gefunden. Hatte in der Main-Funktion beim zugriff auf die "Dreieck"-Funktion noch input_string+i stehen. Das habe ich auf input_string geändert. Jetzt funktioniert das Programm wie ich es möchte.
Aber warum die Zuweisung mit argv nicht geklappt hat versteh ich immer noch nicht.
 
Zuletzt bearbeitet von einem Moderator:
thefy schrieb:
Aber warum die Zuweisung mit argv nicht geklappt hat versteh ich immer noch nicht.
Code:
char* != char**
Das eine ist ein Pointer auf char, das andere ist ein Pointer auf einen Pointer auf char. Das ist nicht das Selbe, deshalb funktioniert die Zuweisung nicht.
In deiner for-Schleife hast du es ja richtig gemacht und mit argv den doppelten Pointer auf einen normalen Pointer reduziert, den du dann auch input_string zuweisen kannst.
Wenn du unbedingt input_string auf das erste Zeichen des ersten Arrays ( Pointers ) setzen willst, musst du vorher den doppelten Pointer dereferenzieren.
Also:
Code:
char* input_string = argv[0];
// oder
char* input_string = *argv;

Gruß
BlackMark
 
Ok verstanden. Vielen Dank!
Wenn ich nur argv schreibe ist es ein Pointer auf Pointer, aber wenn ich argv habe ist es ja nur ein Pointer auf das jeweilige Argument der Kommandozeile und kann deswegen char* input_string zugeordnet werden.
 
Anderer Ansatz wäre "LIFO" und "FIFO" Stack and Queue´s...

ist sehr performant diese funktionen gegen listen laufen zu lassen und die funktionalität ist in der API vorhanden;)

einfach mal googeln iteressante Geschichte.
 
Zurück
Oben