Stringarray inizialiesieren
-
Hallo.
Ich habe ein Problem und zwar will das hier nicht funktionieren:
std::string keywords[] = { "Eins" , "eins" , "EINS" , "Zwei" , "zwei" , "ZWEI" , "Drei" , "drei" , "DREI" , "Vier" , "vier" , "VIER" , "Fünf" , "fünf" , "FÜNF" , "Sechs" , "sechs" , "SECHS" , "Sieben" , "sieben" , "SIEBEN" , "Acht" , "acht" , "ACHT" , "Neun" , "neun" , "NEUN" , "Zehn" , "zehn" , "ZEHN" };Warum nicht und wie kann ich das lösen?^^
Mfg Hans

-
Jetzt wäre es natürlich noch nützlich zu wissen, wie sich dieses "funktioniert nicht" überhaupt bemerkbar macht. In dem Code sehe ich zumindest keinen Fehler.
-
Wenn ich das versuche wie folgt in der main zu definieren dann sagt der gcc:
/home/michael/Dokumente/Development Sector/Forge/Playground/Number/Number.cpp|47|error: expected primary-expression before ‘]’ token|
/home/michael/Dokumente/Development Sector/Forge/Playground/Number/Number.cpp|56|warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x|
-
Hmm, also bei mir funktionierte das Array problemlos. Das einzige Problem wäre, daß du eventuell ein
#include <string>vergessen haben könntest.
-
Okay vllt liegt der fehler auch doch wo anders.
Also ich habe in einer klasse "std::string keywords[];" als private, dass soll dan pasieren:Number::Number(string w) { this->written = w; Init(); ReadString(this->written); }void Number::Init() { this->keywords[] = { "Eins" , "eins" , "EINS" , "Zwei" , "zwei" , "ZWEI" , "Drei" , "drei" , "DREI" , "Vier" , "vier" , "VIER" , "Fünf" , "fünf" , "FÜNF" , "Sechs" , "sechs" , "SECHS" , "Sieben" , "sieben" , "SIEBEN" , "Acht" , "acht" , "ACHT" , "Neun" , "neun" , "NEUN" , "Zehn" , "zehn" , "ZEHN" }; }Mfg hans
-
Was ist keywords? Und was sollen die eckigen Klammern dahinter? Das ist doch keine Deklaration! Du machst es einem nicht leicht, Dir zu helfen. Wenn Du mehr verrätst (sowohl Code-technisch als auch was du überhaupt machen willst), kann man Sie auch besser helfen.

Tipp: Soll es eine konstante String-Tabelle werden, ist vielleicht
const char* const table[] = {"dings", "bums"};keine schlechte Idee, da Du Dir damit die dynamische Initialisierung der std::string-Objekte sparst. Als Faustregel würde ich sagen "Ziehe die Verwendung von std::string gegenüber char* vor -- es sei denn, es handelt sich um String-KONSTANTEN".
Einfach mehr verraten. Dir fehlt anscheinend einiges an Grundwissen.
-
Nein, an der Stelle kannst du es nicht so verwenden - eine Initialisierungsliste kannst du nur direkt bei der Definition einer Variable verwenden, nicht bei einer nachträglichen Zuweisung. (und einem kompletten Array kannst du auch nichts zuweisen)
Für deine Konstruktion wäre es eventuell eine gute Idee, dieses Array als statisches Element der Klasse zu definieren.
-
Als Faustregel würde ich sagen "Ziehe die Verwendung von std::string gegenüber char* vor -- es sei denn, es handelt sich um String-KONSTANTEN".
Warum const char* bei string konstanten? Da würde ich auch ein const std::string für sinnvoller halten

Nein, an der Stelle kannst du es nicht so verwenden - eine Initialisierungsliste kannst du nur direkt bei der Definition einer Variable verwenden, nicht bei einer nachträglichen Zuweisung. (und einem kompletten Array kannst du auch nichts zuweisen)
Für deine Konstruktion wäre es eventuell eine gute Idee, dieses Array als statisches Element der Klasse zu definieren.
Ah

Das ist mir wohl irgendwo entgangen
Habs aber mal ausprobiert und es geht immer noch nicht.#ifndef NUMBER_HPP #define NUMBER_HPP #include <string> namespace Playground { class Number { private: int normal; // The Digit std::string written; // The String static const std::string keywords[] = { "Eins" , "eins" , "EINS" , "Zwei" , "zwei" , "ZWEI" , "Drei" , "drei" , "DREI" , "Vier" , "vier" , "VIER" , "Fünf" , "fünf" , "FÜNF" , "Sechs" , "sechs" , "SECHS" , "Sieben" , "sieben" , "SIEBEN" , "Acht" , "acht" , "ACHT" , "Neun" , "neun" , "NEUN" , "Zehn" , "zehn" , "ZEHN" }; // Digits as Words public: Number(int n); Number(std::string w); int GetDigit() const; std::string GetString() const; void WriteString(int i); void ReadString(const std::string s); private: void Init(); // Inits keywords with Strings! }; } #endif // NUMBER_HPPFehlermeldung:
/home/michael/Dokumente/Development Sector/Forge/Playground/Number/Number.hpp|13|error: a brace-enclosed initializer is not allowed here before ‘{’ token|
/home/michael/Dokumente/Development Sector/Forge/Playground/Number/Number.hpp|22|error: invalid in-class initialization of static data member of non-integral type ‘const std::string []’|
||=== Build finished: 2 errors, 0 warnings ===|Warum das jetzt?
-
Ahja wer wissen will was das werden soll.
Eine Zahl die sich auch ausgeschrieben abrufen lässt.
Ich hab schon längere zeit nicht mehr programmiert und bin ein wenig eingerostet
-
Vom Design her ist es schon mal fraglich. Ich sehe den Sinn der eigenen Number-Klasse nämlich nicht. Für die Konvertierung Zeichenkette->Int tut es auch eine freie Funktion. Und diese freie Funktion könnte eine map<string,int> benutzen.
Dein Code funktioniert nicht, weil statische Datenelemente innerhalb der Klasse nur deklariert werden können. Die Definition findet außerhalb der Klasse statt. Und bei der Definition darfst Du dann auch eine Initialisierung mit angeben. C++ lässt Dich lediglich einen Initialisierer für Ganzzahlkonstanten angeben. Die gibt es hier aber nicht.
Bzgl String-Konstanten: Schreibst Du
const char* const p = "huhu";packt der Compiler in das Kompilat die Zeichenkette rein. Die Zeichenkette wird im statischen Speicherbereich liegen (man muss sich also nicht um die Speicherverwaltung kümmern) und der Zeiger zeigt einfach auf das erste Zeichen der Teichenkette. Schreibst Du dagegen
const std::string q = "huhu";auf globaler Ebene wird auch die Zeichenkette in das Kompilat mit eingefügt. Dazu kommt dynamischer Initialisierungscode. Bevor die Main-Funktion aufgerufen wird, muss dieses String-Objekt nämlich initialisiert werden. Der Konstruktor läuft also vor der main-Funktion (daher "dynamische Initialisierung") und Dieser Konstruktor reserviert nochmal extra Speicher aus dem Freispeicher und kopiert Zeichen für Zeichen von der String-Konstante aus dem statischen Speicher zum Freispeicher. Dieser Aufwand ist komplett überflüssig, wenn Du q zwischendurch nicht ändern möchtest.
Ein Array von Zeichenketten ist für Deine Anwendung auch nur bedingt sinnvoll. Du musst es hier linear durchlaufen und jedes Element mit der Eingabe vergleichen. Das ist für 30 Elemente noch okay, wird aber schnell zu aufwändig. Dafür gibt es nämlich so Dinge wie map<string,int>.
Also, Pseudocode...
string allesgross(string); string allesklein(string); map<string,int> erzeuge_sortierte_tabelle() { static const char* const konstanten[] = { "Null", "Eins", "Zwei", "Drei", "Vier" }; const int kanzahl = sizeof(konstanten)/sizeof(konstanten[0]); map<string,int> tab; for (int i=0; i<kanzahl; ++i) { tab[ konstanten[i] ] = i; tab[allesgross(konstanten[i])] = i; tab[allesklein(konstanten[i])] = i; } return tab; } map<string,int> const& meine_tabelle() { static map<string,int> tab = erzeuge_sortierte_tabelle(); return tab; } int konvertiere_wort_zu_zahl(string const& s) { map<string,int> const& t = meine_tabelle(); auto iterator = t.find(s); if (iterator==t.end()) throw ...einen fehler melden...; return iterator->second; }Man muss nicht alles als Klasse verpacken! Du darfst auch freie Funktionen schreiben und verwenden.