PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C falsches Ergebnis


UpMerge
2008-08-21, 00:51:36
Hallo!


Diese Programm soll die Variable char txt[]= "Hallo", in ollaH verwandeln und in char txt2[80] abspeicher.

Bei der Ausführung des Programmes, ist bei der Ausgabe von txt2 nichts zu lesen. Hab ich vielleicht einen Parameter falsch übergeben oder hab ich sonst was nicht richtig gemacht?
Mir scheint, als wäre was mit der letzten For-Schleife nicht in Ordnung.



#include <stdlib.h>
#include <stdio.h>
#include <string.h>

char Umdrehen(char *,char *);

int main()
{
char txt1[]="Hallo",txt2[80];
char *pt1,*pt2;
pt1=txt1;
pt2=txt2;
Umdrehen(pt1,pt2);
printf("txt1=%s\ntxt2=%s\n",txt1,txt2);
system("pause");
}

char Umdrehen(char *txt1,char *txt2)
{
char *pt1,*pt2,h;

for(pt2=txt1;*pt2;pt2++);/* pt2 auf das letzte Zeichn von txt setzten */

pt2--;
printf("%s\n\n",pt2);/* Kontrolle ob pt2 auf o ist*/
pt1=txt1;

for(;*pt2==-1;pt2--,h++)
{
h=*pt1;
*pt1=*pt2;
*pt2=h;

}
return(*pt1,*pt2);

}

T4ch0n4d3l
2008-08-21, 02:48:18
Ich hab jetzt hier keinen Kompiler, aber was mir auffällt ist:

h++ in der letzten For-Schleife ist sinnlos.
Warum werden alle Pointer zweimal gespeichert? (Betrifft txt1 wird nochmal in pt1 und txt2 in pt2 gespeichert, sowohl in main, als auch in Umdrehen).
pt1=txt2; soll es doch bestimmt heißen?
Warum kopierst du den Inhalt von txt2 nach txt1? Ist doch garnicht Aufgabe.
Das Kriterium deiner letzten For Schleife sagt aus: "Tue solange der INHALT der Speicheraddresse pt2 gleich -1 ist", der kann aber 'H','a','l' oder 'o' sein. Die Schleife wird demzufolge garnicht ausgeführt.


Mein Vorschlag ohne gewähr (eben weil ich keinen Kompiler zur Hand habe)


void Umdrehen(char *,char *);

int main()
{
char txt1[]="Hallo",txt2[80];
Umdrehen(txt1,txt2);
printf("txt1=%s\ntxt2=%s\n",txt1,txt2);
system("pause");
}

void Umdrehen(char *pt2,char *pt1)
{
char *start = pt2;
for(;*pt2!='\0';pt2++);
pt2--;

for(;pt2!=start;pt2--) /* Bis der Pointer wieder auf Ausgangsstellung ist... dass ist nicht das Gleiche wie pt2!=0 oder pt2>0 */
{
*pt1=*pt2;
pt1++;
}
}

urpils
2008-08-21, 07:10:54
ich hab zwar absolut keinen Plan von C... aber wenn du nen Pointer definieren willst, sollte es dann nicht nach dem Motto:
Pointer = Adresse von Variable gehen?
also pt1=&txt1
?

edit:
hab grad den Thread hierunter gelesen und mein Wissen damit aufgefrischt, dass bei Arrays der Name der Variable wohl für die Adresse des ersten Elementes steht ;) also vergiss meinen Einwand *g*

UpMerge
2008-08-21, 09:58:47
Warum kopierst du den Inhalt von txt2 nach txt1? Ist doch garnicht Aufgabe.
Da hast du recht!
Wäre trotzdem schön wenn auch noch die Variablen vertauscht wären.
Die Pointer sind für jede Funktion eigens gemacht, da es sich um lokale Variablen handelt.(Bin mir selber nicht mehr sicher.)


h war zum speichern der Zeichen von pt1 da, damit ich sie dann pt2 übergeben kann.
Dann hätte txt1 ollaH ausgegeben und txt2 Hallo aber geht halt nit.

Bei deinem Programm, kommt beim ollaH das H nicht mit den richtigen Werten zurück, sonst bast alles.

T4ch0n4d3l
2008-08-21, 13:32:44
Hast ja auch noch ein paar Fehlerchen drinne, die ich beschrieben habe ;)


void Umdrehen(char *,char *);

int main()
{
char txt1[]="Hallo",txt2[80];
Umdrehen(txt1,txt2);
printf("txt1=%s\ntxt2=%s\n",txt1,txt2);
system("pause");
}

void Umdrehen(char *pt2,char *pt1)
{
char *start = pt2;
for(;*pt2!='\0';pt2++);

do {
pt2--;
*pt1=*pt2;
pt1++;
} while (pt2!=start);
}


So müsste das 'H' mitkommen.

Sag mal bitte, was du mit for(;*pt2==-1;pt2--,h++) vor hattest.

Mfg,
Markus

RuteniuM
2008-08-21, 13:49:21
So sollte es funktionieren:
#include <stdio.h>
#include <string.h>

int main(int argc, char** argv)
{
char *str1="Hello!", *str2;
char *sp, *dp; // source & destination
int sl = strlen( str1 );

printf("Aus %s ", str1);

for (sp = str1, dp = str2 + sl-1; *sp != '\0'; sp++, dp--)
{
*dp = *sp;
}

str2[sl] = '\0'; // string end

printf("wird %s\n", str2);

return 0;
}Edit: Mal wieder zu langsam... T4ch0n4d3ls Code ist sogar etwas schöner. :)

UpMerge
2008-08-21, 17:30:01
*pt2==-1 wollte ich das zeichen for dem char auslesen.(geht ja nicht oder? :)).
pt2-- sollte eben solange nach unten zählen bis die -1 kommt.
h++ sollte die Variable zu speichern nach oben schieben.

Gast
2008-08-21, 19:10:05
*pt2==-1 wollte ich das zeichen for dem char auslesen.(geht ja nicht oder? :)).


Ich glaube du meinst wohl eher sowas wie *(pt2 - 1) == '\0'
'\0' ist das gleiche wie direkt 0 ohne '' also das Stringende.

an.zgep
2008-08-21, 20:08:01
da du keine ahnung haben kannst, was an der speicherstelle "pt2 - 1" gespeichert ist würd ich lieber nicht versuchen darauf zuzugreifen. im besten fall hast du eine zugriffsverletzung und das betriebssystem würgt dein programm ab, im schlimmsten läufts in einem undefinierten zustand weiter

edit: btw, du fragst immer nach c-code, deine main-funktion hat aber einen rückgabewert. ist das neu in C99 oder vermischt du da ein wenig c mit c++?

UpMerge
2008-08-21, 21:27:59
Ich glaube du meinst wohl eher sowas wie *(pt2 - 1) == '\0'
'\0' ist das gleiche wie direkt 0 ohne '' also das Stringende.
Ja sieht schon besser aus aber funktioniert das auch?


edit: btw, du fragst immer nach c-code, deine main-funktion hat aber einen rückgabewert. ist das neu in C99 oder vermischt du da ein wenig c mit c++?

Mein Kompiler kann mit void nix anfangen deswegen.

Gast
2008-08-21, 22:28:08
edit: btw, du fragst immer nach c-code, deine main-funktion hat aber einen rückgabewert. ist das neu in C99 oder vermischt du da ein wenig c mit c++?
C99 ist eigentlich auch nicht mehr so neu

http://www.galileocomputing.de/openbook/c_von_a_bis_z/c_011_015.htm#Xxx999328

void main(void) {
}

Nach dem älteren C89-Standard ist dies auch richtig. Läuft ein Compiler aber nach dem C99-Standard, sollte dann eine Warnung ausgegeben werden, dass die main()-Funktion einen Rückgabewert erwartet.

Die main()-Funktion lautet (nach C99) richtig:

int main(void) {
return 0;
}

Gast
2008-08-21, 22:32:20
Ja sieht schon besser aus aber funktioniert das auch?


-1 brauchst du nicht da das pt2-- vorher ausgeführt wird.
== 0 ist außerdem auch falsch da du ja nicht auf das stringende prüfen willst sondern grad umgekehrt
!= 0 kann man ja einfach weglassen.

robobimbo
2008-08-21, 22:46:42
hab noch meine aufgabe aus der fh gespeichert - wir mussten damals den string direkt umdrehen. bei dieser methode brauchst - wenn du den anfangs und den endchar tauscht - nur bis zur hälft des strings drübergehen.


void reverse(char *s)
{
char *string_ende = s + strlen(s) - 1; // Ermittle Endposition des übergebenen Strings und speicher das in einen Pointer
char platzhalter; // Platzhaltervariable
// platzhalter = NULL; // Pointer mit sauberen Wert belegen

while (s < string_ende ) // Vergleiche Pointer mit Pointer
{
platzhalter = *s; // Dereferenzierung - Buchstabe von vorne zwischenspeichern
*s = *string_ende; // Nimm Buchstaben von hinten und setze ihn nach vorne
*string_ende = platzhalter; // Nimm Buchstaben von vorne und setze ihn nach hinten
s++; // Startpointer um eins erhöhen
string_ende--; // Endepointer um eins vermindern
}
}

T4ch0n4d3l
2008-08-22, 00:44:26
Ja sieht schon besser aus aber funktioniert das auch?
Wie schon gesagt wurde, greifst du damit auf eine dir unbekannte Speicheradresse zu, was zur Zugriffsverletzung führen kann.

h++ sollte die Variable zu speichern nach oben schieben.

h++ inkrementiert den Inhalt der Variable, nicht deren Adresse. Wenn vorher ein 'a' drinstand, steht dann ein 'b' drin. Du überschreibst aber h sofort danach mit h=*pt1, wodurch h++ überhaupt keinen Effekt hat (nichtmal einen negativen ;) ) h ist kein Pointer. Richtig ist pt1++ (siehe meinen Quelltext).

UpMerge
2008-08-22, 16:17:29
Vielen Dank für Eure Hilfe!!

Werd mich noch ein wenig mehr mit Pointern auseinander setzten müssen, so wies ausschaut. :)

an.zgep
2008-08-23, 18:16:50
C99 ist eigentlich auch nicht mehr so neu

http://www.galileocomputing.de/openbook/c_von_a_bis_z/c_011_015.htm#Xxx999328

da ich seit 97 nur noch c++ progge ist es für mich noch immer unerforschtes gebiet :D
danke übrigens für den link, jetzt ist alles klar!

robobimbo
2008-08-29, 21:30:43
Bin gerade drübergestolpert: http://msdn.microsoft.com/en-us/visualc/bb496952.aspx

Schau es Dir mal an, wird ganz gut erklärt

Ectoplasma
2008-09-01, 12:22:09
Warum macht ihr das so kompliziert?



char txt = "Hallo";
char txt2[80];
char *p1 = txt;
char *p2 = txt2 + strlen(txt);

*p2-- = '\0';
for (; *p1; ++p1, --p2) {
*p2 = *p1;
}



Noch was. Den ++operator würde ich vor die Variable schreiben.
Wenn man ++ hinter die Variable schreibt, dann hat der Operator
einen Rückgabewert. Wenn man mit Iteratoren arbeitet, dann
kann letztere Variante langsamer sein, als die Variante mit dem
Operator vor der Variablen, denn diese hat keinen Rückgabewert.