Autor Beitrag
Sebastian R.
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 72
Erhaltene Danke: 1



BeitragVerfasst: Di 17.10.06 20:13 
Obwohl dieses Forum hauptsächlich sich um Delphi dreht, habe ich mich entschlossen meinen neuesten (kleinen) C++-Header hier zu posten. (Heißt ja schließlich "Entwickler-Ecke" und ich vermute, dass es hier auch einige C++-Programmierer gibt.)

Viele Pascal/Delphi-Programmierer greifen gerne (und oft) auf Funktionen wie StrToInt oder ExtractFilename zurück, während äquivalente Funktionen in C++ fehlen. Die PasLib enthält einige wichtige Funktionen, die für den Delphi-Programmierer gang und gäbe sind.
So ist es jetzt z.B. möglich Funktionen wie StrToInt, IntToStr, ExtractFilename, ExtractFilePath etc. auch in C++ zu benutzen. Alle Funktionen arbeiten identisch zu den Delphi-Funktionen und sind deshalb sehr einfach zu benutzen.

Hier der Quelltext.
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
#include <string>
#include <stdio.h>
#include <vector>
#include <sstream>

/* PasLib.h
   ========
   written by Sebastian Ruhleder © 2006, 2007 - All rights reserved

   This file is licensed under the GNU General Public License.
   To obtain a copy, either visit my page or search in Google. ;)

   Most Delphi/Pascal programmers use functions like IntToStr, StringReplace
   etc. while C++ programmers normally can't use them. This library contains
   the most important functions, written in C++ - ready to use.
   */


/* IntToStr
   - Converts a Integer value into a string */

std::string IntToStr(int intValue) {
  std::ostringstream strStream;
  strStream << intValue;
  std::string Result = strStream.str();
  return Result;
}

/* StrToInt
   - Converts a String value into a integer */

int StrToInt(std::string strValue) {
  std::istringstream strStream(strValue);
  int Result = 0;
  strStream >> Result;
  return Result;
}

/* StringReplace
   - Replaces sFindPattern with sReplace in the string sInput
   and finally returns it */

std::string StringReplace(std::string sInput, std::string sFindPattern, std::string sReplace) {
  std::string Result = sInput;
  int Length = sFindPattern.length();
  int Pos = Result.find(sFindPattern);
  while(Pos != 0) {
    Result.replace(Pos, Length, sReplace);
    Pos = Result.find(sFindPattern);
  }
  return Result;
}

/* explode
   - Nice explode-function. Similar to the php explode-function */

std::vector<std::string> explode(std::string s, std::string e) {
 std::vector<std::string> ret;
 int iPos = s.find(e, 0);
 int iPit = e.length();
 while(iPos>-1) {
   if(iPos!=0)
     ret.push_back(s.substr(0,iPos));
   s.erase(0,iPos+iPit);
   iPos = s.find(e, 0);
 }
 if(s!="")
   ret.push_back(s);
 return ret;
}

/* ExtractFilename
   - Extracts the filename */

std::string ExtractFilename(std::string sPath) {
  std::string Result = sPath;
  std::vector<std::string> Expl;
  #ifdef win32
    Expl = explode(Result, "\\");
  #endif
  #ifdef linux
    Expl = explode(Result, "/");
  #endif
  Result = Expl[Expl.size()-1];
  return Result;
}

/* ExtractFilePath
   - Extracts the path */

std::string ExtractFilePath(std::string sFilePath) {
  std::string Result = sFilePath;
  std::string FileName = ExtractFilename(Result);
  int Pos = Result.find(FileName);
  int Length = FileName.length();
  Result.replace(Pos, Length, "");
  return Result;
}

/* ExtractFileExt
   - Extracts the file extension */

std::string ExtractFileExt(std::string sFile) {
  std::string Result = sFile;
  std::vector<std::string> Expl = explode(Result, ".");
  Result = Expl[Expl.size()-1];
  return Result;
}


Ich hoffe der Header nützt einigen von euch - weitere Funktionen werden (wahrscheinlich) nach und nach eingebaut.

Mit freundlichen Grüßen, Sebastian Ruhleder.

Moderiert von user profile iconAXMD: Code- durch C#-Tags ersetzt


Zuletzt bearbeitet von Sebastian R. am Di 17.10.06 23:39, insgesamt 1-mal bearbeitet
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Di 17.10.06 21:33 
ausblenden C#-Quelltext
1:
using namespace std;					
"Wie breche ich einem C++-Entwickler das Genick", Regel Nummer 1: "Verwende using-Direktiven in Headerdateien.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
/* IntToStr
   - Converts a Integer value into a string */

string IntToStr(int intValue) {
  char Buf[255];
  itoa(intValue, Buf, 10);
  return Buf;
}
Uargs, wo hast du denn den Schrott aufgegabelt? Ich hoffe, daß hat dir kein C++-Entwickler gezeigt. itoa() ist eine C-Funktion, die in C++ nichts zu suchen hat. Der Korrekte Weg wäre ein std::ostringstream, in den du den Integer schreibst. Dann brauchst du auch keinen impliziten Typecast von char[255] auf std::string.


ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
/* StrToInt
   - Converts a String value into a integer */

int StrToInt(string strValue) {
  const char *Buf = strValue.c_str();
  return atoi(Buf);
}
Gleiches Spiel wie oben, std::istringstream wäre korrekt.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
/* ExtractFilename
   - Extracts the filename */

string ExtractFilename(string sPath) {
  string Result = sPath;
  vector<string> Expl = explode(Result, "\\");
  Result = Expl[Expl.size()-1];
  return Result;
}
Dieser Code ist nicht portabel! Üblicherweise fragt man das Betriebssystem (eventuell kennt POSIX eine passende Funktion).


Sorry, aber das ganze Teil ist nicht besonders C++-ig. Es sind alles Kleinigkeiten (abgesehen von dem ekligen itoa(), das ist schon eine halbe Katastrophe), aber so in der Form würde ich das nicht benutzen wollen, weil es einfach kein "schöner" C++-Code ist. Ganz abgesehen davon, daß ich von Vorhaben, Delphi-Schemata auf C++ anzuwenden, sowieso nichts halte. C++ ist genauso wenig perfekt wie Delphi, aber man soll wenn dann reinrassig C++ schreiben und nicht Verfahren von Delphi, C++ und C miteinander vermischen.

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
Sebastian R. Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 72
Erhaltene Danke: 1



BeitragVerfasst: Di 17.10.06 23:43 
Hi tommie-lie,
erstmal danke für deine Tipps und Ratschläge. Natürlich war der Typecast von char[255] nach string nicht gut und die Funktionen itoa bzw. atoi haben tatsächlich nichts darin verloren. Ich habe den Quelltext oben angepasst (und hoffentlich alle deine Ratschläge eingebaut/berücksichtigt).

tommie-lie hat folgendes geschrieben:
Ganz abgesehen davon, daß ich von Vorhaben, Delphi-Schemata auf C++ anzuwenden, sowieso nichts halte.


Es soll ja kein Delphi-Schemata auf C++ angewandt werden - als ich jedoch neulich ein Programm in C++ realisieren wollte, stellte ich fest, dass mir viele wichtige Funktionen (unter anderem auch StrToInt bzw. IntToStr) gefehlt haben. Deshalb habe ich mich entschlossen, diese in dem Header zu sammeln. ;)

MfG, Sebastian R.
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Mi 18.10.06 18:08 
user profile iconSebastian R. hat folgendes geschrieben:
Ich habe den Quelltext oben angepasst (und hoffentlich alle deine Ratschläge eingebaut/berücksichtigt).
Zum Glück ist das using da raus :-)


Sebastian R. hat folgendes geschrieben:
Es soll ja kein Delphi-Schemata auf C++ angewandt werden - als ich jedoch neulich ein Programm in C++ realisieren wollte, stellte ich fest, dass mir viele wichtige Funktionen (unter anderem auch StrToInt bzw. IntToStr) gefehlt haben.
Das ist mir noch nicht vorgekommen. Wann brauche ich IntToStr()? Eigentlich nur, wenn ich dem Anwender die Zahl ausgeben will. Das tue ich nicht, indem ich einfach eine Zahl ausgabe, sondern meist ist noch Begleittext dabei. Also schnapppe ich mit einen std::ostringstream und formatiere die gesamte Ausgabe darin, und nicht nur eine Zeile sondern auch mehrere, passe das Ausgabeformat für Fließkommazahlen an und so weiter. StrToInt() brauche ich normalerweise wenn ich von stdin lese, und dann erledigt std::cin die Konvertierung in einen int. Wenn ich Zahlen im Klartext in Dateien schreiben will, dann wähle ich meine Streams so, daß sie das auch tun (std::*fstream macht das normalerweise so, es sei denn man zwingt ihn mit read()/write() oder dem Binary Mode zu etwas anderem).

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
christian_u
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 30



BeitragVerfasst: Di 24.10.06 12:04 
Zitat:

Das ist mir noch nicht vorgekommen. Wann brauche ich IntToStr()? Eigentlich nur, wenn ich dem Anwender die Zahl ausgeben will. Das tue ich nicht, indem ich einfach eine Zahl ausgabe, sondern meist ist noch Begleittext dabei.


Dann kann man auch in Pascal Format verwenden, man nutzt auso auch in Pascal dioese Funktionen wenn man nur eine einzelne zahl ausgeben möchte...
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Di 24.10.06 12:23 
user profile iconchristian_u hat folgendes geschrieben:
Dann kann man auch in Pascal Format verwenden
Richtig. Das wird in C meiner Beobachtung nach auch deutlich häufiger getan. Das mag aber auch damit zusammenhängen, daß Sting-Concatenation in Delphi durch Compiler-Magic erledigt wird und in C noch echte Handarbeit ist, deswegen nimmt man lieber gleich den fertigen String anstatt sich Textfragmente und Zahlen später aneinanderzukopieren. Schon alleine weil itoa() genauso wie die standardisierte sprintf()-Funktion einfach eine Sicherheitslücke ist. Zu sprintf() gibt es keinen Ersatz (die auf einigen Plattformen vorhandenen (aber nicht standardisierte) snprintf()-Funktion mal ausgenommen), aber wenigstens auf itoa() kann man ja verzichten, wo es nur geht. Mit den scanf()-Funktionen sieht es ähnlich aus, bei falscher Benutzung reißen die sehr schnell Sicherheitslücken auf.

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
christian_u
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 30



BeitragVerfasst: Mi 25.10.06 09:39 
Ja :) Das ist auch son grund weshalb ich leiner Pascal programmier, wenn ich mir allein so anschau was es täglich an Patches nur mit sicherheitslücken in der Stringverarbeitung gibt stellt sich mit die Frage warum so viele Leute so C fixiert sind.