conny< Geschrieben 7. August 2010 Teilen Geschrieben 7. August 2010 Hallo, ich lerne seit einigen Wochen C# und habe versucht eine Methode zu programmieren, mit der ich einen String aus dem Parameter, so zerlegen kann, dass die einzelnen Wörter ohne .,!,?,Zeilenumbrüche, usw. in einer ArrayList zurückgegeben werden. Bin aber leider an eine Schwelle meiner Ideen gekommen und hab mich nach einer Stunde verzweifelten Denkens, dazu entschieden ein paar Fachleute zu fragen. Wär echt toll wenn mir wer helfen könnte. Mein Code: public ArrayList WoerterEinlesen(String text) { Char[] trimArr = new Char[5]{' ', '!', '.', '?', '\n'}; ArrayList words = new ArrayList(); int pos = 0; int signs = 0; // D A S I S T E I N B E I S P I E L // 0 1 2 3 4 5 6 7 8 9 // Solange die Startposition nicht das Ende des Textes erreicht while (pos + signs < text.Length) { // wird die Anzahl der Zeichen bis zum nächsten Leerzeichen in signs gespeichert signs = text.IndexOf(" ", pos); if (signs < 1) signs = text.IndexOf(".", pos); if (signs < 1) signs = text.IndexOf("!", pos); if (signs < 1) signs = text.IndexOf("?", pos); // wenn signs 0 ist braucht man nichts zu tun if (signs > 0) { // ein neues CharArray, mit so vielen Plätzen // wie unser Wort lang ist wird erstellt Char[] chrArr = new Char[signs]; // Solange die Zählervariable i nicht die Länge des Wortes erreicht for (int i = 0; i < signs; i++) { // schreibe den Text in das CharArray chrArr[i] = text[pos + i]; // IndexOutOfRange Exeption... } // Anschließend wird aus dem CharArray ein String und der wird words(ArrayList) // angefügt words.Add(new String(chrArr).Trim(trimArr)); } pos = signs + 1; } return words; } Gruß Conny Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
DerDa71 Geschrieben 7. August 2010 Teilen Geschrieben 7. August 2010 (bearbeitet) Hi Conny, bin in C# auch kein Fachmann (habe auch erst vor einigen Monaten damit angefangen:cool:), aber hier mal zwei Alternativen. 1. Alternative private ArrayList getElementsFromString(String sText) { // diese Variante ersetzt die angegebenen Sonderzeichen durch Leerzeichen // und nutzt Split bei Leerzeichen um eine ArrayList zu erzeugen ArrayList aList = new ArrayList(); Char[] aReplace = new Char[] { '.', ',', '!', '?', ':', ';' }; foreach (Char c in aReplace) { sText = sText.Replace(c, ' '); } sText = sText.Trim(); // prüfen ob sText nach Trim der Leerzeichen am Anfang und/oder Ende // überhaupt einen Inhalt hat if (sText != "") { // hier werden nun doppelte Leerzeichen durch ein einfaches Leerzeichen ersetzt while (sText.Contains(" ")) { sText = sText.Replace(" ", " "); } // nun wird per Split der String an Leerzeichen geteilt // und jeder der gesplitteten Inhalte zur ArrayList als einzelne Werte hinzugefügt aList.AddRange(sText.Split(' ')); } return aList; } 2. Alternative private ArrayList getElementsFromString2(String sText) { // Diese Variante prüft jedes Zeichen und "baut" die einzelnen "Elemente" zusammen ArrayList aList = new ArrayList(); sText = sText.Trim(); if (sText != "") { String sElement = ""; // jedes Zeichen überprüfen, ob es ein // Buchstabe (ASCII-Wert zwischen 65 und 91, sowie 97 und 122) ist // (kann um weitere, erwünschte Werte z.B. Ziffern, Sonderzeichen usw. erweitert werden) for (int i = 0; i < sText.Length; i++) { // Char aus String holen Char cCompare = sText[i]; // Wert des Chars ermitteln int iValue = System.Convert.ToInt32(cCompare); // Vergleichen, ob Wert innerhalb des gewünschten Bereiches liegt if ((iValue > 64 && iValue < 92) || (iValue > 96 && iValue < 123)) { // ist eines der erlaubten Zeichen - zu sElement hinzufügen sElement += sText[i]; } else { // ist kein erlaubtes Zeichen // prüfen ob nicht am Anfang und sElement nicht leer ist if (i > 0 && sElement != "") { // aktuelles Zeichen ist kein erlaubtes Zeichen // letztes sElement zur ArrayList hinzufügen aList.Add(sElement); // sElement zurücksetzen für nächsten Durchlauf sElement = ""; } } } } return aList; } Dein Problem kommt davon, das du bei chrArr = text[pos + i]; über das Ende des Textes hinaus versuchst, auf den String zuzugreifen (irgendwann ist text[pos + i] hinter dem Ende des Textes). Ich hoffe, dass hat dir weitergehholfen. MFG DerDa71 Bearbeitet 7. August 2010 von DerDa71 Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
DerDa71 Geschrieben 7. August 2010 Teilen Geschrieben 7. August 2010 Hi, ich hatte in der 2. Variante noch einen Fehler bzw. etwas vergessen... private ArrayList getElementsFromString2(String sText) { // Diese Variante prüft jedes Zeichen und "baut" die einzelnen "Elemente" zusammen ArrayList aList = new ArrayList(); sText = sText.Trim(); if (sText != "") { String sElement = ""; // jedes Zeichen überprüfen, ob es ein // Buchstabe (ASCII-Wert zwischen 65 und 91, sowie 97 und 122) ist // (kann um weitere, erwünschte Werte z.B. Ziffern, Sonderzeichen usw. erweitert werden) for (int i = 0; i < sText.Length; i++) { // Char aus String holen Char cCompare = sText[i]; // Wert des Chars ermitteln int iValue = System.Convert.ToInt32(cCompare); // Vergleichen, ob Wert innerhalb des gewünschten Bereiches liegt if ((iValue > 64 && iValue < 92) || (iValue > 96 && iValue < 123)) { // ist eines der erlaubten Zeichen - zu sElement hinzufügen sElement += sText[i]; } else { // ist kein erlaubtes Zeichen // prüfen ob nicht am Anfang und sElement nicht leer ist if (i > 0 && sElement != "") { // aktuelles Zeichen ist kein erlaubtes Zeichen // letztes sElement zur ArrayList hinzufügen aList.Add(sElement); // sElement zurücksetzen für nächsten Durchlauf sElement = ""; } } } // Falls am Ende ein (oder mehrere) erlaubte(s) Zeichen war(en), // muss noch das letzte Element zur ArrayList hinzugefügt werden if (sElement != "") { // letztes sElement zur ArrayList hinzufügen aList.Add(sElement); } } return aList; } MFG DerDa71 Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
conny< Geschrieben 7. August 2010 Autor Teilen Geschrieben 7. August 2010 Joa, rießen dank!! Hab die Methode gleich in meinem Programm verbaut(Des nebenbei zählen soll wie oft jedes Wort in einem Text vorkommt...). Funktioniert super. Danke.... Gruß Conny Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
lbm1305 Geschrieben 8. August 2010 Teilen Geschrieben 8. August 2010 Moin, anstatt einer ArrayList würde ich eine Generische Liste (List<T>) verwenden, wenn es sich um den gleichen Datentyp handelt, den den Liste verwalten soll. Bei einer ArrayList müsste man noch Casten. Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Ze29 Geschrieben 8. August 2010 Teilen Geschrieben 8. August 2010 a) wie bereits gesagt sollten statt ArrayList generische Listen verwendet werden. Ansonsten lässt sich das ganze auch als Dreizeiler ausdrücken: public List<string> Split(string input) { var ignoredChars = new[] {"!", ".", ",", "?", "\n"}; var words = input.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); return words.Where(x => !ignoredChars.Contains(x)).ToList(); } Die String.Split Methode kann selbstständig leere Einträge herausfischen und die Where Methode sammelt dann alles auf, was nicht einem der ignorierten Chars entspricht. Falls es unbedingt ne Array List sein _muss_ kann man das Ergebnis der Methode auch in ne ArrayList stecken - return new ArrayList(words.Where(...)); Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
conny< Geschrieben 9. August 2010 Autor Teilen Geschrieben 9. August 2010 nochmal danke.. ich hab aber immer noch nicht ganz den Vorteil von generischen Listen gegenüber einer ArrayList verstanden.:confused: Ich glaub ich muss nochmal die LINQ-Abragen:upps wiederholen. Naja wennigstens kann ich jetzt ruhig weiterprogrammieren. Gruß Conny Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
lbm1305 Geschrieben 9. August 2010 Teilen Geschrieben 9. August 2010 ich hab aber immer noch nicht ganz den Vorteil von generischen Listen gegenüber einer ArrayList verstanden.:confused: Eine ArrayList nimmt alle Elemete auf, die vom Typ "Object" sind oder abgeleitet wurden (string, int aber auch eigene Datentypen). Das ist aber auch schon der Vorteil. Zum Auslesen musste Du zur Laufzeit den eigentlichen Datentyp bestimmten und in diesen Casten. Eine generische Liste kann nur den angegebenen Datentyp aufnehmen. (List<string>, List<int>, List<Person>. Damit entfällt das Casten beim auslesen und es können nur diese Datentypen aufgenommen werden. Es spart ein wenig Zeit, wenn man nicht casten muss. :-) Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
conny< Geschrieben 9. August 2010 Autor Teilen Geschrieben 9. August 2010 Ah okay, so kommt Licht ins dunkle meines Verstandes....:upps Gruß Conny Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Ze29 Geschrieben 9. August 2010 Teilen Geschrieben 9. August 2010 Wichtiger ist, dass generische Listen Typensicher sind und damit der Compiler mehr Fehler abfangen kann. In eine Array Liste kannste alles reinschmeißen und es knallt dann ggf. beim Casten zur Laufzeit. Das passiert dir mit ner generischen Liste nicht. Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
conny< Geschrieben 11. August 2010 Autor Teilen Geschrieben 11. August 2010 Boah ey.... programmieren ist echt nur ein Gehangle von Problem zu Problem... Ich glaub ich mir doch als erste Programmierpraxis ein Tick zu schwieriges Beispiel ausgesucht... Naja, ich beschreib mal mein Problem: Die Methode faerben(int index, Color currentColor) soll aus einer Listbox(lstAusgabe) an der Position index einen String auslesen. Die Liste schaut ungefähr so aus: 64 die 39 der 20 ist 12 man 9 er ... Nun muss ich logischerweise den String spliten und dann trimen. Von dem zurückgegebenen Array das letzte Element sollte das Wort beinhalten, welches ich im Text(der in txtHauptfeld(RichTextBox) steht) färben will(mit currentColor). Ich habe geschrieben: public void faerben(int index, Color currentColor) { // Erst alles wieder normal machen txtHauptfeld.SelectAll(); txtHauptfeld.SelectionBackColor = Color.White; int pos = 0; int suc = 0; if (index < words.Count) { String temp = Convert.ToString(lstAusgabe.Items[index]); String[] tempSplit = temp.Split(' '); int WordsToColor = Convert.ToInt32(tempSplit[0]); String WordToColor = tempSplit[tempSplit.Length - 1].Trim(); Boolean frontIsLetter = false; while (suc < WordsToColor) { int selectStart = txtHauptfeld.Text.IndexOf(WordToColor, pos); if (selectStart > 0 && selectStart < txtHauptfeld.Text.Length) { try { txtHauptfeld.Select(selectStart, WordToColor.Length); // ArgumentOutOfRangeException if (selectStart != 0) { int frontValue = Convert.ToInt32(txtHauptfeld.Text[selectStart - 1]); if ((frontValue > 64 && frontValue < 92) || (frontValue > 96 && frontValue < 123) || frontValue == 246 || frontValue == 228 || frontValue == 252 || frontValue == 220 || frontValue == 214 || frontValue == 196) frontIsLetter = true; } int backValue = Convert.ToInt32(txtHauptfeld.Text[selectStart + txtHauptfeld.SelectedText.Length]); if (!((backValue > 64 && backValue < 92) || frontIsLetter || (backValue > 96 && backValue < 123) || backValue == 246 || backValue == 228 || backValue == 252 || backValue == 220 || backValue == 214 || backValue == 196)) { txtHauptfeld.SelectionBackColor = currentColor; pos = selectStart + txtHauptfeld.SelectionLength; suc++; } else pos = selectStart + txtHauptfeld.SelectionLength; } catch (Exception e) { MessageBox.Show(e.Message); } } else pos = selectStart + txtHauptfeld.SelectionLength; } } } Ich schätze ich programmiere noch deutlich zu kompliziert... Ich bekomme nun bei dieser Codezeile, txtHauptfeld.Select(selectStart, WordToColor.Length); eine ArgumentOutOfRangeException. Dabei habe ich keinen Schimmer wie es dazu kommt. Die Methode wird ausschließlich durch das SelectedIndexChange von der lstAusgabe aufgerufen: private void lstAusgabe_SelectedIndexChanged(object sender, EventArgs e) { if (lstAusgabe.SelectedIndex != 0) if (farbig) faerben(lstAusgabe.SelectedIndex, Color.Red); } wär echt schön wenn mir da noch wer helfen könnte, dann könnte ich zumindest mein erstes Projekt abschließen. Gruß Conny Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
lbm1305 Geschrieben 11. August 2010 Teilen Geschrieben 11. August 2010 Neues Problem -> neuer Thread (neues Thema) Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
grueni Geschrieben 11. August 2010 Teilen Geschrieben 11. August 2010 Hier ist dann mal zu, da gehts weiter: http://forum.fachinformatiker.de/net/140809-woerter-richtextbox-faerben.html Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge