Fehler C3767 bei HashTable



  • Hallo,

    wenn ich in der Funktion Auswerten_Click mit GetHash(key) auf den HashTable Anzahl zugreifen möchte kommt der Fehler:

    "System::Collections::Hashtable::GetHash": Auf mögliche Funktion(en) kann nicht zugegriffen werden.

    Anzahl -> ContainsKey(key) aus der selben HashTable Klasse kann aber genutzt werden. Woher kommt denn dieser Fehler?

    #pragma once
    
    namespace Logfileauswertung {
    
    	using namespace System;
    	using namespace System::ComponentModel;
    	using namespace System::Collections;
    	using namespace System::Windows::Forms;
    	using namespace System::Data;
    	using namespace System::IO;
    	using namespace System::Text;
    	using namespace System::Globalization;
    
    	/// <summary>
    	/// Zusammenfassung für Form1
    	/// </summary>
    	public ref class Form1 : public System::Windows::Forms::Form
    	{
    	public:
    		Form1(void)
    		{
    			InitializeComponent();
    			//
    			//TODO: Konstruktorcode hier hinzufügen.
    			//
    		}
    
    	protected:
    		/// <summary>
    		/// Verwendete Ressourcen bereinigen.
    		/// </summary>
    		~Form1()
    		{
    			if (components)
    			{
    				delete components;
    			}
    		}
    	private: System::Windows::Forms::Button^  Auswerten;
    	protected: 
    	private: System::Windows::Forms::TextBox^  txt_logfile;
    	private: System::Windows::Forms::Label^  label1;
    	private: System::Windows::Forms::OpenFileDialog^  ofd_logfile;
    
    	public: String^ converted_logfile; //wird an verschiedenen Stellen im header-file genutzt
    	public: String^ FileName; //wird an verschiedenen Stellen im header-file genutzt
    
    	private:
    		/// <summary>
    		/// Erforderliche Designervariable.
    		/// </summary>
    		System::ComponentModel::Container ^components;
    
    #pragma region Windows Form Designer generated code
    		/// <summary>
    		/// Erforderliche Methode für die Designerunterstützung.
    		/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
    		/// </summary>
    		void InitializeComponent(void)
    		{
    			this->Auswerten = (gcnew System::Windows::Forms::Button());
    			this->txt_logfile = (gcnew System::Windows::Forms::TextBox());
    			this->label1 = (gcnew System::Windows::Forms::Label());
    			this->ofd_logfile = (gcnew System::Windows::Forms::OpenFileDialog());
    			this->SuspendLayout();
    			// 
    			// Auswerten
    			// 
    			this->Auswerten->Location = System::Drawing::Point(78, 122);
    			this->Auswerten->Name = L"Auswerten";
    			this->Auswerten->Size = System::Drawing::Size(174, 77);
    			this->Auswerten->TabIndex = 1;
    			this->Auswerten->Text = L"Auswertung";
    			this->Auswerten->UseVisualStyleBackColor = true;
    			this->Auswerten->Click += gcnew System::EventHandler(this, &Form1::Auswerten_Click);
    			// 
    			// txt_logfile
    			// 
    			this->txt_logfile->Location = System::Drawing::Point(78, 43);
    			this->txt_logfile->Name = L"txt_logfile";
    			this->txt_logfile->Size = System::Drawing::Size(213, 20);
    			this->txt_logfile->TabIndex = 2;
    			this->txt_logfile->Click += gcnew System::EventHandler(this, &Form1::txt_logfile_Click);
    			// 
    			// label1
    			// 
    			this->label1->AutoSize = true;
    			this->label1->Location = System::Drawing::Point(12, 46);
    			this->label1->Name = L"label1";
    			this->label1->Size = System::Drawing::Size(41, 13);
    			this->label1->TabIndex = 3;
    			this->label1->Text = L"Logfile:";
    			// 
    			// ofd_logfile
    			// 
    			this->ofd_logfile->FileName = L"ofd_logfile";
    			// 
    			// Form1
    			// 
    			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
    			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
    			this->ClientSize = System::Drawing::Size(344, 253);
    			this->Controls->Add(this->label1);
    			this->Controls->Add(this->txt_logfile);
    			this->Controls->Add(this->Auswerten);
    			this->Name = L"Form1";
    			this->Text = L"Logfile Auswertung";
    			this->ResumeLayout(false);
    			this->PerformLayout();
    
    		}
    #pragma endregion
    
    	public: System::Void txt_logfile_Click(System::Object^  sender, System::EventArgs^  e) {
    
    			StringBuilder^ logfile = gcnew StringBuilder();
    			Stream^ myStream;
    			converted_logfile = ("");
    
    			OpenFileDialog^ openFileDialog1 = gcnew OpenFileDialog;
    			openFileDialog1 -> InitialDirectory = "c:\\";
    			openFileDialog1 -> Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
    			openFileDialog1 -> FilterIndex = 1;
    			openFileDialog1 -> RestoreDirectory = true;
    			FileName = openFileDialog1 -> SafeFileName;
    
    			  if ( openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK )
    			  {
    				 if ( (myStream = openFileDialog1->OpenFile()) != nullptr )
    				 {
    					try
    						  {
    							 array<Byte>^b = gcnew array<Byte>(1024);
    							 UTF8Encoding^ temp = gcnew UTF8Encoding( true );
    							 while ( myStream->Read( b, 0, b->Length ) > 0 )
    							 {
    
    								logfile -> Append (temp->GetString(b));
    
    							 }
    						  }
    
    						  finally
    						  {
    							 if (myStream)
    								delete (IDisposable^) myStream;
    
    						  }
    
    					myStream->Close();
    					converted_logfile = Convert::ToString(logfile);
    					converted_logfile -> Trim(); //entfernt alle Leerzeichen für die spätere Bearbeitung
    
    				 }
    			  }
    
    			  }
    
    	public: System::Void Auswerten_Click(System::Object^  sender, System::EventArgs^  e) {
    
    			String^ AusgabeFileName = FileName + "_Auswertung.txt";
    			StreamWriter^ sw = gcnew StreamWriter(AusgabeFileName);
    			// am Ende einfach den String schreiben
    
    			// Erstelle die Kopfzeile für txt
    			String^ kopfzeile = String::Format("{0,-12}{1,8}{3,14}\n", "Anzahl", "Kennung", "Beschreibung");
    
    			/*map<const int, int> m1;
    			m1.insert({ 1, 10 });*/
    
    			Hashtable ^Anzahl = gcnew Hashtable();
    			Hashtable ^Beschreibung = gcnew Hashtable();
    
    			array<Tuple<String^, String^, String^>^>^ errors = gcnew array<Tuple<String^, String^, String^>^> 
    				 { gcnew Tuple <String^, String^, String^>("", "", "")}; // für Strings Werte aus Hastable Anzahl und Beschreibung (im Namespace deklarieren und initalisieren) einfügen
    
    			int Fehleranzahl = 0;
    			int index_Start = 0;
    			int index_Ende = converted_logfile -> Length;
    			int index_akt = 0;
    
    			//String^ Kennung = "";
    
    			String^ c_dtc = "Current_DTC";
    			String^ h_dtc = "History_DTC";
    			String^ key = "";
    			array<Char> ^anyOf = gcnew array<Char>(2); // Array für Suchbegriffe
    
    			anyOf -> SetValue( c_dtc, 0 );
    			anyOf -> SetValue( h_dtc, 1 );
    
    			while(index_Ende > index_Start) {
    
    			index_akt = converted_logfile -> IndexOfAny(anyOf, index_Start); // sucht den ersten Fehler
    
    			Fehleranzahl = 0; //zurücksetzen
    
    				if(index_akt != index_Start){ // nur wenn die Nummern gleich sind, wurde ein Fehlercode gefunden
    
    					if (converted_logfile-> Substring(index_akt + 11 , 2) == "0x"){
    
    						key = converted_logfile -> Substring(index_akt + 11 , 8);
    
    						if(Anzahl -> ContainsKey(key)) { // Fehler ist schon aufgelistet
    
    							Anzahl -> Add(key, Fehleranzahl);
    							Fehleranzahl = Anzahl -> GetHash(key); // Fehleranzahl erhöhen !!!!!!!!!!!!!!!!!!!!!! FEHLER
    
    						}
    
    						Anzahl -> Add(key, Fehleranzahl); // nicht enhalten, also hinzufügen
    
    					}
    
    				}
    
    			index_Start = index_akt; //Fortsetzung bei aktueller Position
    
    			}
    		}
    
    };
    }
    


  • if(Anzahl -> ContainsKey(key)) {
    
         Anzahl -> Add(key, Fehleranzahl); // Wenn der Fehler schon gelistet ist füge ihn nochmal hinzu ?
        Fehleranzahl = Anzahl -> GetHash(key); // Die Fehleranzahl wird auf den Wert des Hashes gesetzt. Sinn ?
        // Außerdem ist GetHash protected, du darfst nicht von außen auf eine geschützte Funktion zugreifen.
        // Hättest du aber gefunden wenn du gesucht hättest.
    
    }
    

    So:

    if(Anzahl -> ContainsKey(key)) {
        Fehleranzahl = (int)Anzahl[key] + 1;
        Anzahl[key] = Fehleranzahl;
    }
    


  • GetHash ist protected. Was willst du denn auch mit dem Hashwert? Du willst wahrscheinlich einfach

    Anzahl[key]
    

    Bei näherer Betrachtung ist dieser Code:

    if(Anzahl -> ContainsKey(key)) { // Fehler ist schon aufgelistet
      Anzahl -> Add(key, Fehleranzahl);
      Fehleranzahl = Anzahl -> GetHash(key); // Fehleranzahl erhöhen 
    }
    Anzahl -> Add(key, Fehleranzahl); // nicht enhalten, also hinzufügen
    

    ziemlich unsinnig. Wenn das Element schon drin ist, muss (darfst) du es nicht nochmal hinzufügen. Und von "erhöhen" seh ich da nichts. Und danach fügst du es nochmal hinzu, schonmal von else gehört?

    Vorschlag (mal geraten: Du willst, dass der dem key zugeordnete Wert um Fehleranzahl erhöht wird)

    if (!Anzahl->ContainsKey(key)) {
      Anzahl->Add(key, 0);
    }
    Anzahl[key] += Fehleranzahl;
    

    (ungetestet, meld dich nochmal, wenn es nicht funktioniert)

    http://msdn.microsoft.com/de-de/library/system.collections.hashtable(v=vs.110).aspx

    edit: Achso, da muss man casten, weil du die nichtgenerische Hashtable verwendest. Dann eher so:

    Anzahl[key] = (int)Anzahl[key] + Fehleranzahl;
    

    Oder benutz gleich System.Collections.Generic.Dictionary.



  • Vielen Dank. Ich wollte wirklich nur auf das Objekt zugreifen.
    Wieso schaffe ich es eigentlich nicht im header-file mit den Klassen der c++ standartbib zu programmieren. Ich nutze die .NET Klassenbib, weil es funktioniert. Ist so die Idee hinter dieser Sprache? Im header programmiere ich mit .NET und wenn ich zusätzliche Funktionaliät implementieren möchte, kann ich dann im cpp-File die c++-bibs verwenden?


Log in to reply