Suchfunktion wie bei Visual Studio Help



  • Hi

    strcmp vergleicht ob beide strings gleich sind und strstr ob ein teilstring im string enthalten ist. Mit welcher String Funktion kann ich das hier machen was ich vor hab ?

    ich möchte eine Suchfunktion schreiben welche bei jeder Tasteneingabe in ein TextEdit Feld, denn Inhalt einer Listbox durchsucht und bei Übereinstimmung die Zeile in meiner Listbox (CListCtrl) markiert. So funktioniert auch doch die Suchfunktion bei von Visual Studio NET Help wenn man nach dem Index sucht.

    Ich weiss nur nicht wie ich denn vergleich machen soll. Gibt es überhaubt eine String Vergleichs Funktion bei der ich sagen auf welcher postition verglichen werden muss ?

    😕



  • Ok, vielleicht hilft's weiter:

    Wenn du z.B. nach dem Wort string suchst, dann ist die Eingabe:
    s
    st
    str
    stri.. usw.

    Um das Problem relativ leicht zu lösen fällt mir momentan nur eins ein: Reguläre Ausdrücke.

    1. Eine Schleife um deine Suchbegriffe
    2. Eine kleine Funktion, etwa so:

    bool find(const TCHAR *s)
    {    
    	//   \ wird als \\ notiert!	
    	static const boost::regex e("[0-9][0-9]\\:[0-9][0-9]\\.[0-9][A|B]"); // hier dein regulärer Ausdruck, z.B. s*, st*, str*, usw.
    	return regex_match(s,e);
    }
    

    3. Wenn find == true, dann Suchbegriff anzeigen.

    Hier noch ein Link:
    http://www.c-plusplus.net/forum/viewtopic.php?t=61159&highlight=boost+regex

    Ich hoffe es hilft ein bißchen..
    MfG



  • wenn ich mich nicht täusche... ist das ne abfrage auf ein bestimmte eingabe bzw. ob die eingabe richtig eingegeben wurde.

    der string kann ja beliebig lang werden .. abhängig auch von dem string in der listbox.

    ich möchte lediglich einen String eingeben das bei jedem tastendruck einen string in der listbox vergleicht und bei jeder tasteneingabe die zeile solange der eingebene string übereinstimmt in der listbox markiert.

    ich verstehe ausserdem regex nicht. VC help steht nichts darüber



  • du shcon wieder 🙂

    ich denke du programmierst in c++ und nicht in c

    schon mal was von klassen, objekten etc gehört. sorry das musste jetzt sein.

    die klasse CString bietet doch alles an, was man so gebrauchen kann.
    also warum machst du dir das alles so schwer



  • lol

    ich probiers ja mit CString .. dachte es gibt eine Funktion welche mir erlaubt character postions bedingt zu suchen.
    sowas z.B.

    Wenn ich im Textfeld "C" drücke... dann musst in der Listbox das erste Item bzw. zeile markiert werden die mit "C" anfängt. Tippe ich "Cm" dann halt zum ersten wort welches mit "Cm" anfängt und diese dann auch markiert.



  • Servus,

    hatte ich mal in meinen ersten C++ Programmen geschrieben:

    CString strFind, strCopy;
    	int iPos = -1;
    	BOOL bExist = FALSE;
    	CArray <int, int&> arrPos;
    
    	m_ctrEdit.GetWindowText(strFind);
    	m_ctrListSearch.SelItemRange(0, 0, m_ctrListSearch.GetCount());
    
    	if (strFind.IsEmpty())
    		return;
    
    	iPos = m_ctrListSearch.FindString(iPos, strFind);
    	while (!bExist)
    	{
    		//Ist der Punkt schon vorhanden dann markiere ihn nicht
    		for (int i = 0; i < arrPos.GetCount(); i++)
    		{
    			if (arrPos[i] == iPos)
    			{
    				bExist = TRUE;
    				break;
    			}
    		}
    
    		if (!bExist)
    		{
    			arrPos.Add(iPos);
    			m_ctrListSearch.SetSel(iPos);
    			iPos = m_ctrListSearch.FindString(iPos, strFind);
    		}
    	}
    

    m_ctrListSearch = Member von der ListBox
    m_ctrEdit = Member vom Edit

    Listbox muss auf Selection->Multiple in den Properties gestellt werden. Der Rest erklärt sich von alleine....

    Viel Spass
    *winke*
    Hellsgore

    EDIT:

    Achso, du solltest den Kram in das OnChange Ereignis von deinem Edit schreiben.



  • du hast ne listbox benutzt ich hab eine leider eine CListCtrl benutzt 😞



  • CString::Find kann das doch 🙂



  • alder schwede 🙂

    ich hätte mal auf der hilfe drauf clicken sollen. da steht

    Searches this string for the first match of a character or substring.

    na ich hoffe es wirkt so wie ich es mir vorstelle. jedoch habe ich es bis jetzt noch nicht geschaft eine Reihe in der CListCtrl zu markieren. Muss ich das noch irgendwas setzten ein Flag, ne Variable. damit das möglich ist ?

    Was ist mit meinem Thréad dem exitcode 🙄



  • single selection in den properties auf false setzen



  • also ... ich denke das find denn zu suchenden string bzw character im gesamten string sucht und findet. ich glaube du hast nich verstanden was ich sagen wollte.

    Ich tippe "B" dann wird das in der Listbox gesucht welcher String mit "B" anfängt, dieser wird dann markiert und nicht der String soll markiert werden der nicht mit "B" anfängt aber irgendwo sonst ein "B" entählt.

    Ausserdem wird immer meine IF schleife ausgeführt, egal ob der string enthalten ist oder nicht. In der Listbox ist ein String welcher denn namen "Auto" enthält ich tippe "Z" und die if schleife wird trotzdem ausgeführt obwohl kein Z in Auto vorkommt. 😡

    void CListAllDlg::OnEnChangeSearch()
    {
    	CString m_Item="", m_Search="";
    	int length=0;
    	int pos=1;
    	int i=0;
    
    	length=GetDlgItemText(IDC_SEARCH,m_Search);//GetDlgItem return the length of the text
    	while(i<length)
    	{
    		m_Item=m_list_all.GetItemText(pos,1);
    		if((m_Item.Find(m_Search),0))!=-1)
    		{
    			m_list_all.SetSelectionMark(5);
    		}
    		i++;
    	}
    }
    


  • also das liegt ja wohl an deinem algorythmus

    du solltest dir glaub ich angewöhnen dein coding vorher richtig zu durchdenken

    Text "Auto"

    eingabe "B"

    //eine while schleife die z.b. auf länge der einträge der liste prüft

    //string aus liste lesen
    CString str = "Auto"; //das soll nur ein ersatz sein zur erklärung

    int iStelle = str.Find("B", 0);

    //nur prüfen ob es an der ersten stelle steht
    if (iStelle==0)
    {
    //makieren

    }

    /ende while schleife



  • hats geholfen?



  • sorry,

    habs anderst gelöst nur. schau mal 🙂 funktioniert wunderbar.

    void CListAllDlg::OnEnChangeSearch()
    {
    	CString m_ListItem="", m_Search="", m_String;
    	int length = 0;
    	int nItems=0;
    	bool found = false;
    
    	length = GetDlgItemText(IDC_SEARCH,m_Search);//GetDlgItem return the length of the text
    	nItems = m_list_all.GetItemCount();
    
    	for(int pos = 0; pos < nItems; pos++)
    	{
    		m_String="";
    		m_ListItem = m_list_all.GetItemText(pos,1);
    		for(int i = 0; i < length; i++)
    		{
    			m_String += m_ListItem.GetAt(i);
    		}//end for
    
    		if (strcmp(m_String,m_Search)==0)
    		{
    			m_list_all.SetItemState(pos, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
    			break;
    		}//end if
    	}//end for
    
    }//end OnEnChangeSearch()
    

    Die selection springt bei übereinstimmung des strings schön in der listbox rum. Bei jedem Taseten schlag wird der String überprüft. Nur das die selection der Zeile in der Listbox ist grau, also es ist nicht standardmässig blau 🙄 .. Irgendwie nich fokusiert oder so.. als wäre die listbox im hintergrund. click ich auf die listbox dann wirds blau. hoffe ich habs irgendwie erklärt 🙂



  • Moin,

    ich habe ein ähnliches Problem, welches ich mit euren Tipps leider nicht lösen kann...

    Ich habe ein CListCtrl und ein Edit Control, in welches die Suche eineggeben wird. Bei jeder Änderung der Suche soll überprüft werden, ob in der Liste in Feld Nr. 0 ("Kunde") ein Eintrag existiert, der mit den Suchbuchstaben anfängt und den ersten Eintrag davon selektieren.

    Hier ein Bild dazu (ca. 9kb):
    Tool

    Meine Funktion selektiert leider nur, wenn in der Suche der komplette Eintrag eingegeben wird...

    Hier die Funktion:

    void CToolDlg::OnEnChangeEsuche()
    {
    	UpdateData(true);
    	if(m_strVersionSuche == "")
    	{
    		m_ctlVersionen.SetItemState(0, LVIS_SELECTED | LVIS_FOCUSED, -1);
    		m_ctlVersionen.EnsureVisible(0,TRUE);
    	}
    	else
    	{
    		// LISTE DURCHSUCHEN!!!
    		int spKunde = 0; // Spaltennummer für Kunde
    		for(int i=0; i<m_ctlVersionen.GetItemCount(); i++)
    		{
    			CString strVergleichen = m_ctlVersionen.GetItemText( i, spKunde);
    			if(strVergleichen.MakeLower() == m_strVersionSuche.MakeLower())
    			{
    				m_ctlVersionen.SetItemState(i, LVIS_SELECTED | LVIS_FOCUSED, -1);
    				m_ctlVersionen.EnsureVisible(i,TRUE);
    			}
    		}
    	}
    }
    

    Wäre nett, wenn mir jemand dabei helfen könnte, ich hab heute Nacht das komplette Forum nach CListCtrl durchgesucht (11 Seiten).

    Mit freundlichen Grüßen, Manuel. 🙂



  • lol

    meine funktion macht genau das was du machst.

    jedoch sind die einträge in meiner CListCtrl schon alphabetisch aus der Datenbank ausgelesen worden. Deshalb wird automatisch der erste Eintrag markiert. Tipp ich "E" wird das erste wort mit "E" selektiert. "Ei" dann wird das nächste wort mit das mit"Ei" anfängt selektiert.

    hoffe es hat dir geholfen. Ansonsten würde ich dir raten die einträge zuerst mal in der listbox zu selektieren und dann so ähnlich wie ich das gemacht habe zu suchen und zu selektieren.

    gruss
    indian



  • Ich habe, bevor ich mit C++ angefangen habe, mir sehr gute PHP-Kenntnisse angelernt. Dort gibt es, wie bei C++ auch, die Funktion substr(). Leider gilt die Funktion substring() nicht für CString-Variablen... Sonst wäre das Vergleichen ziemlich einfach!

    <?php
      $suche = "Hallo";
      $liste_wert = "Hallo_du";
      $suche_anzahl_buchstaben = strlen($suche);
      if($suche == substr($liste_wert, 0, $suche_anzahl_buchstaben))
      {
        // Den Eintrag in der Liste markieren
      }
    ?>
    

    Und genau sowas brauche ich für C++. 🙂



  • Also mit Find() habe ich es schon mal hinbekommen, dass in der Liste die Einträge durchsucht werden und ein Eintrag selektiert wird, der die Suche enthält...

    Jetzt brauche ich aber trotzdem noch eine Funktion wie substr(), mit der ich den Text des Eintrags auf die Anzahl der Such-Buchstaben verkürzen kann, damit nur die Einträge selektiert werden, die nur am Anfang des Strings den Suchstring enthalten...

    void CToolDlg::OnEnChangeEsuche()
    {
    	UpdateData(true);
    	if(m_strVersionSuche == "")
    	{
    		m_ctlVersionen.SetItemState(0, LVIS_SELECTED | LVIS_FOCUSED, -1);
    		m_ctlVersionen.EnsureVisible(0,TRUE);
    	}
    	else
    	{
    		// TODO: Suchfunktion erweitern
    		int spKunde = 0; // Spaltennummer für Kunde
    		CString strVergleichen;
    		for(int i = 0; i < m_ctlVersionen.GetItemCount(); i++)
    		{
    			strVergleichen = m_ctlVersionen.GetItemText(i, spKunde);
    			if(strVergleichen.MakeLower().Find(m_strVersionSuche.MakeLower()) != -1)
    			{
    				m_ctlVersionen.SetItemState(i, LVIS_SELECTED | LVIS_FOCUSED, -1);
    				m_ctlVersionen.EnsureVisible(i, TRUE);
    				break;
    			}
    		}
    	}
    }
    


  • Hallo,

    Ellek schrieb:

    Jetzt brauche ich aber trotzdem noch eine Funktion wie substr(),

    schon gesehen, daß CString Member-Funktionen wie Left, Right und Mid besitzt (mit denen man das problemlos nachbauen kann)?

    MfG



  • Das hab ich natürlich nicht gewusst. :p

    Aber danke, jetzt hab ich die Funktion genauso, wie ich sie haben wollte. 🙂

    void CToolDlg::OnEnChangeEsuche()
    {
    	UpdateData(true);
    	if(m_strVersionSuche == "")
    	{
    		m_ctlVersionen.SetItemState(0, LVIS_SELECTED | LVIS_FOCUSED, -1);
    		m_ctlVersionen.EnsureVisible(0,TRUE);
    	}
    	else
    	{
    		// TODO: Suchfunktion erweitern
    		int spKunde = 0; // Spaltennummer für Kunde
    		CString strVergleichen;
    		for(int i = 0; i < m_ctlVersionen.GetItemCount(); i++)
    		{
    			strVergleichen = m_ctlVersionen.GetItemText(i, spKunde);
    			int nStringLaenge = CString::StringLength(m_strVersionSuche);
    			strVergleichen = strVergleichen.Left(nStringLaenge);
    			if(strVergleichen.MakeLower().Find(m_strVersionSuche.MakeLower()) != -1)
    			{
    				m_ctlVersionen.SetItemState(i, LVIS_SELECTED | LVIS_FOCUSED, -1);
    				m_ctlVersionen.EnsureVisible(i, TRUE);
    				break;
    			}
    		}
    	}
    }
    

    Vielen Dank an alle die mir geholfen haben! 👍


Anmelden zum Antworten