strlen in C++

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

strlen in C++

Beitrag von Duff » 22.03.2009 11:23:42

Und wieder eine Frage zu C++.....

Code: Alles auswählen

// reverse01.cpp
#include <iostream>
#include <algorithm>
#include <string>
#include <string>
using namespace std;

int main(int argc, char **argv){
   char wort[80];
   copy(argv[1], argv[1]+strlen(argv[1])+1,wort);
   reverse(wort, wort+strlen(wort));
   cout << wort << endl;
}
Was ist bei der Verwendung von strlen falsch?

Code: Alles auswählen

daniel@daniel-laptop:~/scripts/C++/Einstieg_in_C++/Kapitel09$ g++ -Wall -o reverse01 reverse01.cpp 
reverse01.cpp: In function ‘int main(int, char**)’:
reverse01.cpp:10: error: ‘strlen’ was not declared in this scope
Wenn ich mir die manpage zu strlen anschaue, ist der Aufruf doch richtig.
Oh, yeah!

Benutzeravatar
GoKi
Beiträge: 2068
Registriert: 04.07.2003 23:08:56
Lizenz eigener Beiträge: MIT Lizenz

Re: strlen in C++

Beitrag von GoKi » 22.03.2009 11:38:18

Duff hat geschrieben:Wenn ich mir die manpage zu strlen anschaue, ist der Aufruf doch richtig.
Der Compiler beschwert sich auch nicht über den Aufruf an sich, er kennt schlicht und ergreifend die Funktion nicht. Der Blick in die Manpage war schon mal der richtige Ansatz.
Dort findest Du folgende Information.

Code: Alles auswählen

SYNOPSIS
       #include <string.h>

       size_t strlen(const char *s);
Also es fehlt der include.

Code: Alles auswählen

// reverse01.cpp
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring> // c++ version vom C header string.h
using namespace std;

int main(int argc, char **argv){
   char wort[80];
   copy(argv[1], argv[1]+strlen(argv[1])+1,wort);
   reverse(wort, wort+strlen(wort));
   cout << wort << endl;
}
Allerdings willst Du doch c++ Programmieren? Daher würde ich einen c++ String benutzen. Du musst dich dabei unteranderem nicht um die Länge des Strings kümmern (Speicher reservieren, falls argv[1] länger als 80 Zeichen ist).

Code: Alles auswählen

int main(int argc, char **argv) {
   string wort = argv[1];
   reverse(wort.begin(), wort.end());
   cout << wort << endl;
}
MfG GoKi
:wq

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: strlen in C++

Beitrag von Duff » 22.03.2009 12:27:21

Stimmt, so ist es besser wie du es beschrieben hast.

Wie müsste denn jetzt noch eine gute Fehlerbehandlung in diesem Beispiel aussehen, wenn keine Eingabe gemacht wurde?
Oh, yeah!

Benutzeravatar
GoKi
Beiträge: 2068
Registriert: 04.07.2003 23:08:56
Lizenz eigener Beiträge: MIT Lizenz

Re: strlen in C++

Beitrag von GoKi » 22.03.2009 13:10:52

hmm... eine einfache Abfrage von argc ist doch ausreichend in dem Fall?
Da Du in deinem Eingangsposting copy verwendest hast, hier auch noch mal eine Lösung mittels reverse_iterator, ostream_iterator und copy.
http://nopaste.debianforum.de/20115
MfG GoKi
:wq

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: strlen in C++

Beitrag von Duff » 22.03.2009 19:19:43

Danke, nur diese 2 Zeilen verstehe ich nicht ganz..

Code: Alles auswählen

copy(wort.rbegin(), wort.rend(), ostream_iterator<char>(cout));
cout << endl;
Oh, yeah!

Benutzeravatar
GoKi
Beiträge: 2068
Registriert: 04.07.2003 23:08:56
Lizenz eigener Beiträge: MIT Lizenz

Re: strlen in C++

Beitrag von GoKi » 22.03.2009 19:59:26

Ich denke mal, die erste Zeile ist unklar. Die zweite gibt lediglich das Zeilenende aus.

copy selbst hast Du schon angewendet. Du weißt also, dass du damit einen Bereich gegeben durch zwei Iteratoren kopieren kannst. Als Ziel dient wiederum ein Iterator.
Ersetzen wir copy durch einen for Loop, dann erhalten wir ungefähr:

Code: Alles auswählen

ostream_iterator<char> output(cout);
for (string::reverse_iterator it = wort.rbegin(); it != wort.rend(); it++)
  *output++ = *it;
ostream_iterator<T> ist ein Iterator, der die übergebenen Werte in einem ostream kopiert, in unserem Beispiel nach cout. Hierfür wird der operator<< benutzt, der für T definiert sein muss.
Äquivalent zu oben wäre also

Code: Alles auswählen

for (string::reverse_iterator it = wort.rbegin(); it != wort.rend(); it++)
  cout << *it;
Um rückwärts ("verkehrt herum") durch einen Bereich zu laufen, existiert der reverse_iterator. rbegin() liefert einen reverse_iterator auf das letzte Element zurück, rend() wiederum einen reverse_iterator vor dem ersten Element. Im Vergleich zum normalen iterator bewegen sich die Operationen - wie z.B. it++ - in die entgegengesetzte Richtung.
Äquivalent wäre

Code: Alles auswählen

for (int i = (int)wort.size() - 1; i >= 0; i--)
  cout << wort[i];
Es gibt eben wie immer mehrere Möglichkeiten :-)
MfG GoKi
:wq

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: strlen in C++

Beitrag von Duff » 23.03.2009 07:50:34

Super Erklärung.

Mich wunderte vor allem, warum in der Zeile

Code: Alles auswählen

copy(wort.rbegin(), wort.rend(), ostream_iterator<char>(cout));
der Einbagestring auch ausgeben wurde.
Oh, yeah!

Antworten