String wiedergeben
-
Man könnte jetzt noch hinzufügen, dass der Code implizit auch noch annimmt, dass das System einen ASCII-konformen Zeichensatz verwendet der auf gar keinen Fall internationalisierte Zeichen wie ä,ö, und ü enthält. Ich kenne aus dem Stehgreif Systeme, bei denen der Code nicht zufriedenstellend funktioniert - zum Beispiel an dem wo ich gerade sitze. Aber ich kenne kein System, wo es nicht zumindest die c-Version von toupper gibt.
-
TyRoXx schrieb:
Und was genau ist an dem Scheiß jetzt besser als richtiges C++?
Zum Glück ist volkard momentan irgendwie abwesend, der wäre glatt vom Balkon gesprungen hätte er den Code lesen müssen.
-
Nur um das nochmal klarzustellen: Meine Bitte nach Code war nicht, um sich über dich lustig zu machen. Mir war ziemlich klar, dass dein Code ungefähr so aussehen würde und dass du dir der Probleme nicht bewusst bist. Manchmal muss man aber glaube ich die Leute etwas auflaufen lassen, damit sie sich von besseren Lösungen überzeugen lassen

-
Man muss aber dazu sagen, dass es natürlich auch mit c-strings viel schöner ginge:
const char* toUpper(const char* str){ std::size_t size = std::strlen(str); const char* result = new char[size]; std::transform(str,str+size,result,std::toupper); return result; }Der Aufrufer muss sich natürlich immer noch mit dem delete rum plagen, das würde einem erst der string abnehmen:
std::string toUpper(std::string const& str){ std::string result(str.size()); std::transform(str.begin(),str.end(),result.begin(),std::toupper); return result; }Aber wie du siehst wird der Code dadurch schon viel übersichtlicher und eine Menge der ätzenden Fehlerquellen werden einem abgenommen.
-
Achja, wenn ein Dreißigzeiler zu dein kleinen Algorithmen gehört und du für 16 Algorithmen 1500 Zeilen veranschlagst, wie groß ist dann erst dein größter Algorithmus? Kann man da überhaupt noch durchblicken? Drei deiner Algorithmen haben wir ja bereits ersetzt. Fehlen noch 13
Wie heißen sie?
-
Michael E. schrieb:
Achja, wenn ein Dreißigzeiler zu dein kleinen Algorithmen gehört und du für 16 Algorithmen 1500 Zeilen veranschlagst, wie groß ist dann erst dein größter Algorithmus? Kann man da überhaupt noch durchblicken? Drei deiner Algorithmen haben wir ja bereits ersetzt. Fehlen noch 13
Wie heißen sie?Leute Leute, muss ich mich hier komplett entblößen

unsigned int s_get_lenght(const char* string); const char* s_get_fraction(const char* string, const char* delimiter, unsigned int position); const char* s_get_fraction_atFront(const char* string, const char* delimiter); const char* s_get_fraction_atEnd(const char* string, const char* delimiter); const char* s_convert_toUpper(const char* string); const char* s_convert_toLower(const char* string); const char* s_filter_numeral(const char* string, bool ovw /*= true*/, const char* ovw_s /*= "*"*/); const char* s_filter_specsym(const char* string, bool ovw /*= true*/, const char* ovw_s /*= "*"*/); const char* s_filter_string(const char* string, const char* fstring, bool ovw /*= true*/, const char* ovw_s /*= "*"*/); const char* s_append(const char* string, const char* addition, unsigned int position, bool ovw /*= false*/, const char* ovw_s /*= "*"*/); const char* s_append_atFront(const char* string, const char* addition, bool ovw /*= false*/); const char* s_append_atEnd(const char* string, const char* addition); const char* s_cut_out(const char* string, unsigned int from, unsigned int to /*= 0*/); const char* s_cut_off(const char* string, unsigned int from, unsigned int to /*= 0*/); unsigned int s_split(const char* string, const char* delimiter); bool s_compare(const char* string_1, const char* string_2);
-
Ich versteh' grad nicht, wieso das hier
std::transform(s.begin(), s.end(), s.begin(), std::toupper);diesen Fehler hier verursacht
Fehler: keine passende Funktion für Aufruf von »transform(std::basic_string<char>::iterator, std::basic_string<char>::iterator, std::basic_string<char>::iterator, <unaufgelöster überladener Funktionstyp>)«|, und das hier
std::transform(s.begin(), s.end(), s.begin(), toupper);funktioniert. Warum ist das so?
-
<ctype.h> statt <cctype> eingebunden?
-
Flüchtigkeitsfehler. Es kollidieren toupper(int) und toupper(charT, locale) im namespace std miteinander und der Compiler braucht Hilfe bei der Entscheidung. da du noch die alte c-version mit eingebunden hast, kommt die Kollision im globalen namensraum nicht zustande.
immernoch ungetestet
int (*applyUpper)(int) = std::toupper; std::transform(s.begin(), s.end(), s.begin(), applyUpper);
-
Also das ist der Code
#include <algorithm> #include <string> #include <iostream> #include <cctype> std::string to_upper(const std::string& str) { std::string s = str; std::transform(s.begin(), s.end(), s.begin(), std::toupper); return s; } int main() { std::cout << to_upper("Hallo."); }Fehler:
|9|Fehler: keine passende Funktion für Aufruf von »transform(std::basic_string<char>::iterator, std::basic_string<char>::iterator, std::basic_string<char>::iterator, <unaufgelöster überladener Funktionstyp>)«| |9|Anmerkung: Kandidaten sind:| c:\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\bits\stl_algo.h|4871|Anmerkung: template<class _IIter, class _OIter, class _UnaryOperation> _OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation)| c:\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\bits\stl_algo.h|4907|Anmerkung: template<class _IIter1, class _IIter2, class _OIter, class _BinaryOperation> _OIter std::transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation)|Und mal mit otze's Korrigierung:
Keine Fehler. Okay, danke

-
RussianTux schrieb:
Leute Leute, muss ich mich hier komplett entblößen

unsigned int s_get_lenght(const char* string); // std::strlen / kann std::string const char* s_get_fraction(const char* string, const char* delimiter, unsigned int position); const char* s_get_fraction_atFront(const char* string, const char* delimiter); const char* s_get_fraction_atEnd(const char* string, const char* delimiter); const char* s_convert_toUpper(const char* string); // Gezeigt const char* s_convert_toLower(const char* string); // Gezeigt const char* s_filter_numeral(const char* string, bool ovw /*= true*/, const char* ovw_s /*= "*"*/); const char* s_filter_specsym(const char* string, bool ovw /*= true*/, const char* ovw_s /*= "*"*/); const char* s_filter_string(const char* string, const char* fstring, bool ovw /*= true*/, const char* ovw_s /*= "*"*/); const char* s_append(const char* string, const char* addition, unsigned int position, bool ovw /*= false*/, const char* ovw_s /*= "*"*/); // kann std::string const char* s_append_atFront(const char* string, const char* addition, bool ovw /*= false*/); // kann std::string const char* s_append_atEnd(const char* string, const char* addition); // Kann std::string const char* s_cut_out(const char* string, unsigned int from, unsigned int to /*= 0*/); // kann std::string const char* s_cut_off(const char* string, unsigned int from, unsigned int to /*= 0*/); // kann std::string unsigned int s_split(const char* string, const char* delimiter); bool s_compare(const char* string_1, const char* string_2); // kann std::string
-
unsigned int s_get_lenght(const char* string);Hat std::string schon unter dem Namen
size.const char* s_get_fraction(const char* string, const char* delimiter, unsigned int position); const char* s_get_fraction_atFront(const char* string, const char* delimiter); const char* s_get_fraction_atEnd(const char* string, const char* delimiter);Wenn ich die Namen richtig interpretiere, willst du einen Substring von Position position bis zum ersten Auftreten von delimiter nach position (bzw. andersrum bei atEnd). Das lässt sich implementieren als
string getSubstrFromPosToDelimiter(const string& input, size_t start, const string& delimiter) { string::const_iterator iter = search(input.begin() + start, input.end(), delimiter.begin(), delimiter.end()); // geht noch einfacher, wenn delimiter ein char ist return string(input.begin() + start, iter); } string getSubstrAfterLastOccurrenceOf(const string& input, const string& delimiter) { string::const_reverse_iterator iter = search(input.rbegin(), input.rend(), delimiter.rbegin(), delimiter.rend()); return string(iter.base(), input.end()); }const char* s_convert_toUpper(const char* string); const char* s_convert_toLower(const char* string);Hatten wir ja schon.
const char* s_filter_numeral(const char* string, bool ovw /*= true*/, const char* ovw_s /*= "*"*/); const char* s_filter_specsym(const char* string, bool ovw /*= true*/, const char* ovw_s /*= "*"*/); const char* s_filter_string(const char* string, const char* fstring, bool ovw /*= true*/, const char* ovw_s /*= "*"*/);Ich hoffe, ich verstehe die Namen korrekt: Willst du jeweils nur Zeichen behalten, die Ziffern (numeral ist übrigens kein Wort), spezielle Symbole oder im String fstring vorhanden sind? Wenn ja, ist das wieder ein Dreizeiler mit std::copy_if:
template<typename Filter> string filter(const string& input, Filter filter) { string output; copy_if(input.begin(), input.end(), back_inserter(output), filter); return output; } string filterDigits(const string& input) { return filter(input, isdigit); } string filterCharacters(const string& input, const string& characters) { return filter(input, [&](const char c){return characters.find(c) != string::npos;}); }const char* s_append(const char* string, const char* addition, unsigned int position, bool ovw /*= false*/, const char* ovw_s /*= "*"*/); const char* s_append_atFront(const char* string, const char* addition, bool ovw /*= false*/); const char* s_append_atEnd(const char* string, const char* addition);Hat std::string schon.
const char* s_cut_out(const char* string, unsigned int from, unsigned int to /*= 0*/); const char* s_cut_off(const char* string, unsigned int from, unsigned int to /*= 0*/);Gibts bei std::string unter dem Namen erase.
unsigned int s_split(const char* string, const char* delimiter);Haben wir schon abgehandelt.
bool s_compare(const char* string_1, const char* string_2);Ist bei std::string der Gleichheitsoperator.
Und schon wurden 1500 Zeilen Code auf ein paar Dreizeiler runtergebrochen

Edit: Vervollständigt.
-
Ich habe eine sehr wichtig und entscheidende Frage an euch alle:
Inwiefern wird der Computer beim Ausführen in Echtzeit bei der Einbindung von all diesen Bibliotheken beansprucht?!
Wenn man soviel Funktionalität, wie die Standardbibliotheken einem bieten nicht benötigt, wieso kann man dann keine eigenen Algorithmen schreiben, welche dem Programmierer einen klareren Überblick über sein Vorhaben bereitstellen?
-
RussianTux schrieb:
Inwiefern wird der Computer beim Ausführen in Echtzeit bei der Einbindung von all diesen Bibliotheken beansprucht?!
So viel wie es dauert ~100kb von der Platte zu lesen. (= nix)
Allerdings wird die Standardbibliothek eh gelinkt, also bringt dir das nichts die nicht zu nutzen.
(Edit: Und das sind keine Bibliotheken, sondern Funktionen der Standardbibliothek.)RussianTux schrieb:
Wenn man soviel Funktionalität, wie die Standardbibliotheken einem bieten nicht benötigt, wieso kann man dann keine eigenen Algorithmen schreiben, welche dem Programmierer einen klareren Überblick über sein Vorhaben bereitstellen?
Du kannst doch eigene Algorithmen schreiben. Nur sollten die 1. nicht exakt identisch mit vorhanden Algorithmen sein und 2. intern vorhandene Algorithmen nutzen.
-
RussianTux schrieb:
Ich habe eine sehr wichtig und entscheidende Frage an euch alle:
Inwiefern wird der Computer beim Ausführen in Echtzeit bei der Einbindung von all diesen Bibliotheken beansprucht?!
Nach dem laden des Programms? 0. Im Fall von string und den Algorithmen ist es sogar so, dass die direkt im Binary stehen (bis auf toupper/tolower) und gar nicht zusätzlich geladen werden müssen. Letztere lädst du aber eh, da deine Umgebung ohne nicht funktioniert.
//edit kleines Beispiel:
das transform in unserem toupper wird, nachdem der Compiler da einmal durchgefegt hat nicht mehr sein als://annahme: string hat einen zeiger start_ und end_) char* input = str.start_; char* result = strresult.start_; while(input != str.end_){ *result = toupper(*input);//toupper kommt aus der c-Bibliothek ++input; ++result }Besser könntest du es mit einer handgeschriebenen Schleife auch nicht. Und dass du toupper nicht wirklich ersetzen kannst ist klar. Stichwort: Lokalisierung.
Wenn man soviel Funktionalität, wie die Standardbibliotheken einem bieten nicht benötigt, wieso kann man dann keine eigenen Algorithmen schreiben, welche dem Programmierer einen klareren Überblick über sein Vorhaben bereitstellen?
Weil es sich gezeigt hat, dass selber schreiben zu fehlerhaftem und schlecht wartbarem code führt. jeder weiß, was strlen ist. jeder c++ Programmierer kennt std::string. Aber deine neuen Funktionen müsste sich jeder Programmierer erst mal anschauen und überlegen was sie machen oder die doku lesen. Außerdem ist zu befürchten, dass sich deine Funktionen im laufe der Zeit immer mal wieder ändern, da da sicherlich nicht so viel Zeit im Interface steckt wie bei der Standardbibliothek. Also wird sich der ganze Code nochmal mit ändern müssen.
Zudem sind die Anforderungen der Standardbibliothek nicht so groß. je nachdem was du verwendest sind das nur wenige Kb mehr die deine Binary groß ist. Im Microcontroller Bereich kann man sich da mal über die iostream Bibliothek streiten, aber auf allen anderen Plattformen ist das völlig egal.
-
RussianTux schrieb:
Ich habe eine sehr wichtig und entscheidende Frage an euch alle:
Inwiefern wird der Computer beim Ausführen in Echtzeit bei der Einbindung von all diesen Bibliotheken beansprucht?!
Nur bei der Einbindung oder bei der Ausführung? Bei der Einbindung, wie andere schon geschrieben haben, so gut wie gar nicht. Bei der Ausführung ist anzunehmen, dass die Standardalgorithmen sogar besser/effizienter sind, als das was du selber zusammenbastelst. Und wenn mal völlig unerwartet neue Anforderungen kommen, bist du plötzlich überfordert. Was machst du, wenn jemand doch irgendwann mal Unicode benutzen will? Ohne macht eine String Bibliothek doch überhaupt keinen Sinn.
Konzetrier dich auf dein eigentliches Projekt und verschwende keine Zeit daran, das Rad neu zu erfinden. Als Viereck, weil du befürchtest, dass das Rad in Wirklichkeit gar kein Rad ist, und zu viele Ecken hat.
-
otze schrieb:
//edit oder für wide character unterstützung:
template<class CharT, class Alloc> void convert_toUpper(std::basic_string<CharT,Alloc>& str){ typedef std::basic_string<CharT,Alloc> String; String::iterator end = str.end(); std::locale loc; for(String::iterator pos = str.begin(); pos != end; ++pos){ *pos=std::toupper(*pos,loc); } }Wenn ich mich nicht täusche, hast du hier den Traits-Parameter vergessen.