Anzahl Strings im AnsiString ermitteln
-
Hallo,
wie kann man in einem AnsiString Array die Anzahl an Strings ermitteln ?
AnsiString sTemp[] = {"string1","string2",string3"};
Mit sTemp->Length() bekomme ich nur die Länge des 1. strings, aber wie bekomme ich die Anzahl an strings ?
-
Du gibst die Länge doch an. Wenn du es auf die Art machst, musst du dir die Anzahl einfach merken.
Wenn du statt dessen einen std::vector<AnsiString> nutzt bekommst du die Anzahl mit size(), bei TStringList mit Count.
Schau doch mal in die Hilfe zu diesen Typen.
-
Das Array liegt hard kodiert in einem Include File und ist eine Liste mit bis zu 300 Strings (Fehlermeldungen), die ich über einen Index später im Programm auslese.
Mit StringList kann ich aber keine feste Liste erzeugen, oder ich müsste den AnsiString in eine StringList zur Laufzeit kopieren ?Die Fehlermeldungen ändern sich in der Anzahl ab und zu, und ich kopiere die Liste mit copy und paste von einer Textdatei in ein Include File, und ich wollte mir das Zählen sparen.
-
Trial schrieb:
Das Array ...
Arrays kann man nicht zählen, Punkt aus Ende (Die Länge eines C-Strings kann man auch nur durch die Definition ermitteln, dass das letzte Zeichen \0 ist).
Wenn du mit Arrays arbeitest, musst du dir wenn schon etwas anderes einfallen lassen (z.B. in dem du sagst das der letzte Eintrag ein Leerstring, oder irgendein konstanter Endestring ist).
cu André
-
@Trial
Lies deine Strings zur Laufzeit aus einer Textdatei ein. Dann kannst du auch TStringList verwenden.
-
#1
Setz einen Sentinel Eintrag an das Ende der Liste (z.B. "[ENDE]" ), dann kannst du per Indexzugriff so lange über die einzelnen Strings laufen, bis du auf diesen Eintrag triffst.#2
AnsiString ErrorMessages[] = {..... }; unsigned int uiCount = sizeof( ErrorMessages ) / sizeof( AnsiString )
#3
Benutze einen Vektor, in dem du die Fehlermeldungen ablegst. In meinen Applikationen benutze ich eine Lookup Table (std::map<unsigned int, std::string>), die jeder Fehlernummer einen Fehlertext zuordnet.Gruß,
Doc
-
@Braunstein
Das mit der separaten Textdatei möchte ich verhindern, das gibt irgendwann nur Durcheinander.@_DocShoe_
Die Geschichte mit der LookupTable hört sich so an wie das was ich suche. Kannst Du mir das etwas näher erklären ?Vielen Dank für eure Hilfe
-
An der Lookup Table gibt´s eigentlich nicht viel zu erklären... ist eine banale std::map<unsigned int, std::string>, die eine Zuordnung von ID nach Text implementiert. Ich benutze eine Kombination aus hard-coded Einträgen (durch Tool automatisch aus einer Datei erzeugt) und der Möglichkeit, diese Einträge aus einer Datei zu lesen. Im Groben sieht das Ganze so aus (die Daten kommen aus einer XML Datei, habe die Details zum Lesen/Schreiben ausgelassen):
#include <map> #include <string> #include <sstream> #include <iostream> // Typdefinition für map typedef std::map<unsigned int, std::string> LookupTable_t; LookupTable_t ErrorMessageTable; void create_default_messages( LookupTable_t& Table ); void load_error_messages( const std::string& strFileName, LookupTable_t& Table ); void save_error_messages( const std::string& strFileName, const LookupTable_t& Table ); std::string get_error_message( unsigned int uiErrorID, const LookupTable_t& Table ); void create_default_messages( LookupTable_t& Table ) { // Default Einstellungen sind hard-coded Table[1] = "Error #1"; Table[2] = "Error #2"; Table[5] = "Error #5"; } void load_error_messages( const std::string& strFileName, LookupTable_t& Table ) { // Meldungen aus Datei laden } void save_error_messages( const std::string& strFileName, const LookupTable_t& Table ) { // Meldungen in Datei schreiben } std::string get_error_message( unsigned int uiErrorID, const LookupTable_t& Table ) { LookupTable_t::const_iterator it = Table.find( uiErrorID ); if( Table.end() != it ) { return it->second; } std::ostringstream oss; oss << "Unbekannte Fehler ID: " << uiErrorID; return oss.str(); } int main() { create_default_messages( ErrorMessageTable ); load_error_messages( "c:/load.dat", ErrorMessageTable ); save_error_messages( "c:/save.dat", ErrorMessageTable ); std::string s = get_error_message( 1, ErrorMessageTable ); s = get_error_message( 5, ErrorMessageTable ); s = get_error_message( 9, ErrorMessageTable ); }
-
Die Array-Größe kann man doch nachträglich ermitteln (so wie es alle C-Freaks machen):
const int size = sizeof(sTemp) / sizeof(sTemp[0]);
Edit: Sorry, habe jetzt erst gesehen, daß _DocShoe_ dies ja schon erwähnt hat -)
-
@_DocShoe_
Danke für das Beispiel, das gibt mir schon eine Idee.@Th69
An sizeof hatte ich auch gedacht, aber nicht daran, dass jedes Stringelement über einen eigenen Pointer angesprochen wird. War der Meinung dass durch unterschiedliche Textlängen bei sizeof auch unterschiedliche Werte kommen. Naja, wieder was dazu gelernt
-
Trial schrieb:
@Th69
An sizeof hatte ich auch gedacht, aber nicht daran, dass jedes Stringelement über einen eigenen Pointer angesprochen wird. War der Meinung dass durch unterschiedliche Textlängen bei sizeof auch unterschiedliche Werte kommen. Naja, wieder was dazu gelerntDer sizeof Operator bestimmt die Grösse eines Objekts, im Fall von AnsiString hat das nichts mit dem Inhalt zu tun. Das Beispiel sollte klarmachen, warum das so ist:
struct StringTest { char* pszString; };
Die Grösse der Struktur ist immer konstant sizeof( StringTest ), ganz egal, auf was der Pointer zeigt.