Vector + Array
-
Ich mach wahrscheinlich wieder den größten Bockmist aber mal schauen was ihr sagt und hoffentlich hab ich diesmal mich auch dran gehalten alles vernünftig dazustellen und zu erklären also mein vorhaben:
Ich möchte meinen vector<TokenType> Toki durch gehen und für jedes Token mit der Funktion Search die passende Übersetzung aus meinem 2D array (oder mehrdimensional?) suchen. Das ganz soll dann in dem vector<char> Trans gespeichert werden.Fehler:
oopjs.cpp:140:31: Warnung: Vergleich zwischen vorzeichenbehafteten und vorzeichenlosen Ganzzahlausdrücken [-Wsign-compare] oopjs.cpp:141:22: Fehler: ungültige Typen »unsigned char[int]« für Feldindex
Der Fehler verwirrt mich und ich finde auch nichts bei Google.
(Ach so schon alleine durch das erstellen des Beitrages habe ich aus anfänglichen 6 Fehler es auf einen Fehler + Warnung gebracht. )Falls mein Ansatz komplett falsch ist und das so überhaupt nicht funktioniert bitte ich um Tipps wie ich es machen könnte. Danke!
.cpp
#include "oopjs.h" #include <algorithm> #include <vector> #include <string> #include <iostream> #include <iterator> void Scanner::TranslateVeci(){ for(std::vector<TokenType>::iterator it; Toki.begin() < Toki.end(); it++){ int Scanner::Search(TokenType *it,unsigned char* TArray, size_t()); } } int Scanner::Search(TokenType *it , unsigned char* TArray, size_t()){ for(int i = 0; i < size_t(); i++){ //Warnung if(*TArray[i][2] == *it){ //Fehler Trans.push_back(i); } } return -1; } unsigned char* TArray[][2] = { {(unsigned char*)TT_LBRACKET,(unsigned char*)"("}, {(unsigned char*)TT_RBRACKET,(unsigned char*)")"}, {(unsigned char*)TT_LBRACE,(unsigned char*)"{"}, {(unsigned char*)TT_RBRACE,(unsigned char*)"}"}, {(unsigned char*)TT_COMMA,(unsigned char*)" "}, {(unsigned char*)TT_SEMI,(unsigned char*)";"}, {(unsigned char*)TT_COLON,(unsigned char*)":"}, {(unsigned char*)TT_DOT,(unsigned char*)"."}, {(unsigned char*)TT_PUBLIC,(unsigned char*)"this"}, {(unsigned char*)TT_FUNC,(unsigned char*)"prototype"}, {(unsigned char*)TT_CONS,(unsigned char*)"console"}, {(unsigned char*)TT_QUOTE,(unsigned char*)"'"}, {(unsigned char*)TT_STRING,(unsigned char*)"bla"}, {(unsigned char*)TT_CLASS,(unsigned char*)"function"}, {(unsigned char*)TT_HELLO,(unsigned char*)"hello"}, {(unsigned char*)TT_BYE,(unsigned char*)"bye"}, {(unsigned char*)TT_GREET,(unsigned char*)"greet"}, {(unsigned char*)TT_NIL,(unsigned char*)" "} };
.h
#ifndef OOPJS_H #define OOPJS_H #include <iostream> #include <string> #include <vector> #include <map> enum TokenType{ // token definition TT_LBRACKET, TT_RBRACKET, TT_LBRACE, TT_RBRACE, TT_COMMA, TT_SEMI, TT_COLON, TT_DOT, TT_PUBLIC, TT_FUNC, TT_CONS, TT_QUOTE, TT_STRING, TT_CLASS, TT_HELLO, TT_BYE, TT_GREET, TT_NIL }; static const char *TokenTypStr[] = { // for error message "TT_LBRACKET", "TT_RBRACKET", "TT_LBRACE", "TT_RBRACE", "TT_COMMA", "TT_SEMI", "TT_COLON", "TT_DOT", "TT_PUBLIC", "TT_FUNC", "TT_CONS", "TT_QUOTE", "TT_STRING", "TT_CLASS", "TT_HELLO", "TT_BYE", "TT_GREET", "TT_NIL" }; class Token{ private: TokenType myType; int myValue; public: Token(TokenType type = TT_NIL, int value = 0); TokenType getType() const { return myType; } int getValue() const { return myValue; } const char *toString() const { return TokenTypStr[myType]; } // error message bool equal(TokenType type) const { return myType == type; } //comparison }; class Scanner{ public: void veci(); Scanner(const std::string& input); Token getNextToken(); void TranslateVeci(); int Search(TokenType *it,unsigned char* TArray, size_t()); private: unsigned char* TArray[][2]; std::vector<TokenType> Toki; std::vector<char> Trans; std::string myInput; unsigned int myPos; //Position at input char myCh; //last char void skipSpaces(); void readNextChar(); }; #endif
-
for(std::vector<TokenType>::iterator it; Toki.begin() < Toki.end(); it++){ int Scanner::Search(TokenType *it,unsigned char* TArray, size_t()); }
Bitte gib uns den richtigen Code, nicht irgendwelchen Unsinn.
Der direkte Fehler:
TArray ist vom Typ unsigned char*. Von welchem Typ ist dann TArray[i]? Was ist dann TArray[i][2]? Oder gar *TArray[i][2]?Das Programm ist so furchtbar, über den Rest verkneif ich mir mal jeden Kommentar. Hast du das selber programmiert?
-
Hallo, ich hab jetzt nicht deinen ganzen Code durchgesehen aber bei der Warnung scheint dir sowas passiert zu sein:
int var = -3; unsigned un = 5; if(un==var) // Erzeugt hier die Warnung { } un = var; cout<<un<<endl; // Nööööö da kommt nicht -3 raus ;D
Warnung: Vergleich von signed- und unsigned-Werten
Jetzt sollte dir was auffallen.
-
Schau dir mal Zeile 11 an, die sieht komplett widersinnig aus. Was soll das bedeuten? Sieht so aus, als wolltest du eine Funktion aufrufen, hast aber einfach den Kopf der Funktionsdefinition aus Zeile 15 kopiert...
Zeile 15: was ist der dritte Parameter? Du musst einen Typ und ggf einen Namen angeben für den Parameter. Schrägerweise ist das, was du dort angegeben hast, sogar ein Typ: Der Typ einer Funktion, die ein size_t zurückgibt und keine Argumente erwartet. Ziemlich sicher nicht das, was du willst. In Zeile 16 taucht nochmal size_t() auf, an der Stelle bedeutet es aber was anderes: ein default-Konstruiertes Objekt vom Typ size_t, bedeutet also 0u (eine vorzeichenlose Null). Sicher auch nicht das was du willst.
Den Krempel mit dem mehrdimensionalen Array würde ich komplett weglassen, das bringt nichts außer Kopfschmerzen, mal davon abgesehen, dass du unten beim Befüllen in der ersten Spalte immer ein TokenType in einen unsigned char* castest, was bestenfalls sehr komisch riecht.
Wieso benutzt du keine std::map?
-
int i = 0; i < size_t(); i++
int
ist vorzeichenbehaftet,size_t
ist es nicht. Darum meckert er hier mit der Warnung, aber was dassize_t()
soll frag ich mich auch .int Scanner::Search(TokenType *it,unsigned char* TArray, size_t());
Was soll das sein und warum zur Hölle benutzt du
size_t
immer mit den Klammern?if(*TArray[i][2] == *it)
Übrigens rufst du hier das Element mit dem Index 2 in einem Array mit 2 Elementen (dass es mehrere Dimensionen hat ist hier irrelevant) auf. Siehste den Fehler? Aber den wirst du erst zur Laufzeit mitbekommen.
Was den Fehler angeht: Du hast
TArray
zum Zeitpunkt der Benutztung noch gar nicht deklariert.Abgesehen davon, dass der Code wie schon erwähnt wurde grauenvoll aussieht hier noch einige kleine Hinweise von mir:
Einige dich, ob du zuerst
private
oder zuerstpublic
Member deklarierst, sonst wird das ein elendiges Durcheinander.
Typecasts sind meist eine Fehlerquelle, die du meist erst zur Laufzeit bemerkst. -> vermeiden
Wenn eine Funktion nur einen Rückgabewert hat kannst du sie auch gleich alsvoid
vereinbaren.
C-Strings sind nicht ohne Grund veraltet und man hat auch nicht ohne Grundstd::string
entwickelt.
-
Erstmal danke für alle antworten.
SeppJ schrieb:
Der direkte Fehler:
TArray ist vom Typ unsigned char*. Von welchem Typ ist dann TArray[i]? Was ist dann TArray[i][2]? Oder gar *TArray[i][2]?Der Tobi schrieb:
if(*TArray[i][2] == *it)
Übrigens rufst du hier das Element mit dem Index 2 in einem Array mit 2 Elementen (dass es mehrere Dimensionen hat ist hier irrelevant) auf. Siehste den Fehler? Aber den wirst du erst zur Laufzeit mitbekommen.
Was den Fehler angeht: Du hast
TArray
zum Zeitpunkt der Benutztung noch gar nicht deklariert.So richtig hab ich das noch nicht verstanden. Also muss das Array vor den Funktionen stehen?
Muss ich also TArray[i][2] vorher deklarieren?Der Tobi schrieb:
int i = 0; i < size_t(); i++
int
ist vorzeichenbehaftet,size_t
ist es nicht. Darum meckert er hier mit der Warnung, aber was dassize_t()
soll frag ich mich auch .int Scanner::Search(TokenType *it,unsigned char* TArray, size_t());
Was soll das sein und warum zur Hölle benutzt du
size_t
immer mit den Klammern?pumuckl schrieb:
Zeile 15: was ist der dritte Parameter? Du musst einen Typ und ggf einen Namen angeben für den Parameter. Schrägerweise ist das, was du dort angegeben hast, sogar ein Typ: Der Typ einer Funktion, die ein size_t zurückgibt und keine Argumente erwartet. Ziemlich sicher nicht das, was du willst. In Zeile 16 taucht nochmal size_t() auf, an der Stelle bedeutet es aber was anderes: ein default-Konstruiertes Objekt vom Typ size_t, bedeutet also 0u (eine vorzeichenlose Null). Sicher auch nicht das was du willst.
Bassmaster schrieb:
Hallo, ich hab jetzt nicht deinen ganzen Code durchgesehen aber bei der Warnung scheint dir sowas passiert zu sein:
int var = -3; unsigned un = 5; if(un==var) // Erzeugt hier die Warnung { } un = var; cout<<un<<endl; // Nööööö da kommt nicht -3 raus ;D
Warnung: Vergleich von signed- und unsigned-Werten
Jetzt sollte dir was auffallen.
Gut also ich glaube da muss ich mir noch mal ein Kopf zu machen und es fliegt nun erstmal raus das size_t.
pumuckl schrieb:
Den Krempel mit dem mehrdimensionalen Array würde ich komplett weglassen, das bringt nichts außer Kopfschmerzen, mal davon abgesehen, dass du unten beim Befüllen in der ersten Spalte immer ein TokenType in einen unsigned char* castest, was bestenfalls sehr komisch riecht.
Wieso benutzt du keine std::map?Hab ich über legt, mein Ausbilder hat mir den Tipp gegeben mit dem Array ich werd mir das aber jetzt mal mit einer std::map anschauen.
Der Tobi schrieb:
Abgesehen davon, dass der Code wie schon erwähnt wurde grauenvoll aussieht hier noch einige kleine Hinweise von mir:
Einige dich, ob du zuerst
private
oder zuerstpublic
Member deklarierst, sonst wird das ein elendiges Durcheinander.
Typecasts sind meist eine Fehlerquelle, die du meist erst zur Laufzeit bemerkst. -> vermeiden
Wenn eine Funktion nur einen Rückgabewert hat kannst du sie auch gleich alsvoid
vereinbaren.
C-Strings sind nicht ohne Grund veraltet und man hat auch nicht ohne Grundstd::string
entwickelt.private public hab ich geändert.
Welche Funktion meinst du? Die Search?
und wo hab ich C-Strings?SeppJ schrieb:
Das Programm ist so furchtbar, über den Rest verkneif ich mir mal jeden Kommentar. Hast du das selber programmiert?
Ja hab ich sonst würdest du das wahrscheinlich nicht so doof finden.
Alles im allen hab ich wohl noch viel falsch. Ich schau mir das jetzt noch mal mit der std::map an und überleg mir was neues. Danke soweit!
-
Mit dem Rückgabewert meint er ziemlich sicher die Search-Methode, da die bei dir immer -1 zurück gibt, egal was passiert. Was die C-Strings angeht meint er wohl die ganzen const char* im Header und die Stringliterale in der .cpp - Ob man für die Konstanten wirklich std::string verwenden sollte ist strittig, ich denke da gibts erstmal viel wichtigere Baustellen (z.B. dem Code erstmal einen Sinn zu geben...)
-
Was mir eigentlich Übelkeit bereitete waren die ganzen übergaben von
const unsigned char*
.Muss ich also TArray[i][2] vorher deklarieren?
Du solltest am besten gar kein Array verwenden, sondern, wie schon gesagt
std::map
. Von Globalen Variablen allgemein: Hände weg!Gut also ich glaube da muss ich mir noch mal ein Kopf zu machen und es fliegt nun erstmal raus das size_t
Je nachdem,
size_t
ist für die Länge von Dingen (besser kann ichs grad nicht formulieren) gedacht, wie der Name schon sagt, sollte man es am besten für Längen (z.B. von Strings, Vektoren u.ä.) verwenden, da diese schlecht negativ werden können und man somit eine feste Länge für alle solche Objekte hat. Aber der Einfachheit halber würd ich für nicht-negative Zahlen immerunsigned int
und für den Restint
benutzen (Wobeisize_t
meist nur eintypedef
aufunsigned int
bzw. etwas ähnlich großes ist).
-
Ich hab nun noch mal bisschen rum gespielt und rum gedacht. Da kam mir die Idee das einfach direkt als das Zeichen in einen vector zu pushen wie ich es möchte. Problem ist nun dabei das es mit einem vectorstd::string geht es nicht. Mit einem vector<char> klappt es nur nicht mit längeren Zeichenketten. Was ja auch logisch ist. Jemand dazu eine Idee ob ich ihm das irgendwie umwandeln kann oder wie ich das hin bekomme.
Ach so es geht um den vector<char> Trans;
Token Scanner::getNextToken(){ std::string buf; skipSpaces(); //to skip chars which are not used switch(myCh){ case '(': readNextChar(); Toki.push_back(TT_LBRACKET); Trans.push_back('('); return Token(TT_LBRACKET); case ')': readNextChar(); Toki.push_back(TT_RBRACKET); Trans.push_back(')'); return Token(TT_RBRACKET); case '}': readNextChar(); Toki.push_back(TT_RBRACE); Trans.push_back('}'); return Token(TT_RBRACE); case '{': readNextChar(); Toki.push_back(TT_LBRACE); Trans.push_back('{'); return Token(TT_LBRACE); case ',': readNextChar(); Toki.push_back(TT_COMMA); Trans.push_back(','); return Token(TT_COMMA); case ';': readNextChar(); Toki.push_back(TT_SEMI); Trans.push_back(';'); return Token(TT_SEMI); case ':': readNextChar(); Toki.push_back(TT_COLON); Trans.push_back(':'); return Token(TT_COLON); case '.': readNextChar(); Toki.push_back(TT_DOT); Trans.push_back('.'); return Token(TT_DOT); case '"': readNextChar(); Toki.push_back(TT_QUOTE); Trans.push_back('"'); return Token(TT_QUOTE); //read as long its a letter case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': while(isalpha(myCh)){ buf += myCh; readNextChar(); if(buf == "class"){ buf += myCh; readNextChar(); Toki.push_back(TT_CLASS); Trans.push_back('prototype'); return Token(TT_CLASS); } if(buf == "function"){ buf += myCh; readNextChar(); Toki.push_back(TT_FUNC); Trans.push_back('function'); return Token(TT_FUNC); } if(buf == "public"){ buf += myCh; readNextChar(); Toki.push_back(TT_PUBLIC); Trans.push_back('this'); return Token(TT_PUBLIC); } if(buf == "hello"){ buf += myCh; readNextChar(); Toki.push_back(TT_HELLO); Trans.push_back('hello'); return Token(TT_HELLO); } if(buf == "bye"){ buf += myCh; readNextChar(); Toki.push_back(TT_BYE); Trans.push_back('bye'); return Token(TT_BYE); } if(buf == "greet"){ buf += myCh; readNextChar(); Toki.push_back(TT_GREET); Trans.push_back('greet'); return Token(TT_GREET); } if(buf == "console"){ buf += myCh; readNextChar(); Toki.push_back(TT_CONS); Trans.push_back('console'); return Token(TT_CONS); } } Toki.push_back(TT_STRING); Trans.push_back('bla'); return Token(TT_STRING); default: if(myCh != 0){ std::cerr << "Error: not used Char '" << myCh << "'" << std::endl; } break; } return Token(TT_NIL); };
-
Was ist deine Frage? Dass eine Liste von Zeichenketten etwas anderes bedeutet als eine Liste von Zeichen sollte doch wohl klar sein, oder? Oder ist dir insgesamt nicht bekannt, wie sich char, string, char* und char[] zueinander verhalten?
-
SeppJ schrieb:
Was ist deine Frage? Dass eine Liste von Zeichenketten etwas anderes bedeutet als eine Liste von Zeichen sollte doch wohl klar sein, oder? Oder ist dir insgesamt nicht bekannt, wie sich char, string, char* und char[] zueinander verhalten?
Ich hab doch sogar geschrieben das es klar ist, dass das so nicht funktioniert. Meine Frage ist dem nach ob man jetzt das irgendwie hin bekommt das man das ganz "Wort" dort rein bekommt.
-
Hallo Enno,
warum sollte es denn mit einem vectorstd::string nicht gehen?
Aber wofür benötigst du überhaupt den vector 'Trans'?
-
Th69 schrieb:
Hallo Enno,
warum sollte es denn mit einem vectorstd::string nicht gehen?
Aber wofür benötigst du überhaupt den vector 'Trans'?Also ich hab es nicht hinbekommen mit vectoestd::string nicht hinbekommen das mich push_back dort rein zu bekommen.
Na in vector<char> Trans soll das rein kommen?EDIT:
Hab was gefunden was mir hilft:std::copy("function","function"+8,std::back_inserter(Trans));