Forum: PC-Programmierung C# Wie auf einen String zugreifen


von Johann (Gast)


Lesenswert?

Hallo Leute.

ich will auf auf die Elemente eines Strings zu greifen, wie macht man 
das?

Das steht in dem String drin. Am Ende will ich ein Ergebnis int =103;

string Test ="V1.03"

Theoretisch ist mir klar zuerst muss ich einen neuen String machen in 
dem
steht "103" und dann mit Convert einen Int draus machen.

Nur weiss ich nicht wie man von dem String "V1.03" auf den String "103" 
kommt.

von Peter II (Gast)


Lesenswert?

string Test ="V1.03"
string test2 = Test.Substring(1,1) + Test.Substring(3,2);

von ich (Gast)


Lesenswert?

jedes Zeichen anschauen und prüfen obs eine Ziffer ist. Falls ja, an 
neuen String anhängen.

von Sam .. (sam1994)


Lesenswert?

Wenn nur V, . und Zahlen im Strnig sind reicht auch das:
String version = Test.Replace("V", "").Replace(".","");

von asdf (Gast)


Lesenswert?

ich schrieb:
> jedes Zeichen anschauen und prüfen obs eine Ziffer ist. Falls ja, an
> neuen String anhängen.

genau das. code nicht getestet.
1
            string before = "V1.03";
2
            string after = "";
3
            char currentChar;
4
            for (int i = 0; i < before.Length; i++)
5
            {
6
                currentChar = before.ToCharArray()[i];
7
                if ((currentChar > 47) && (currentChar < 58))  //is integer?
8
                {
9
                    after += currentChar;
10
                }
11
            }
12
            int result = int.Parse(after);

von asdf (Gast)


Lesenswert?

evtl noch checken ob ueberhaupt zahlen enthalten waren:

if(after.Length > 0)
{
//parse int
}

von Peter II (Gast)


Lesenswert?

asdf schrieb:
> genau das. code nicht getestet.

schöner code - aber schelcht umgesetzt. Der code ist viel zu lansame!!!!

- der Aufruf von before.ToCharArray() erfolgt viel zu oft
- for ist langsamer als foreach
- string verkettung ist langsam und hier nicht notwendig - wir wollen 
ein int


Man sollte auch bei kleinen dinge etwas auf Performace achten.

[c]
string s = "V1.03";
int i = 0;
foreach( char c in s ) {
   if ( char.IsDigit(c) ) {
  i = i * 10 + int.Parse( c.ToString() );
   }
}
[\c]

von Sam .. (sam1994)


Lesenswert?

In C++ wär das was für Zeiger. Hier mal was mit Indexer:
1
int version(string str)
2
{
3
    int ret = 0;
4
    int pos = -1;
5
    while(++pos < str.Length)
6
        while(pos < str.Length && str[pos] > 47 && str[pos] < 58)
7
            ret = 10 * ret + str[pos++] - 48;
8
    return ret > 0 ? Convert.ToInt32(ret) : -1;
9
}

Wenn man schon Int.Parse vermeiden will, warum dann nicht ganz?

PS: Meine müsste ca. 5-6 mal schneller sein als deine.

von Sam .. (sam1994)


Lesenswert?

Samuel K. schrieb:
> PS: Meine müsste ca. 5-6 mal schneller sein als deine.

Sry, hab falsch gemessen. Eher 2-3mal.

von Peter II (Gast)


Lesenswert?

Samuel K. schrieb:
> Wenn man schon Int.Parse vermeiden will, warum dann nicht ganz?

weil ich mich bei unicode nicht genau auskenne und mit der festen 
codierung (-48) verhindest du die unicode zeichen für zahlen.

Warum kein iterrator in C++ verwenden, dürfte noch etwas mehr speed 
bringen, damit könnte man den index zugriff sparen.

von Markus V. (valvestino)


Lesenswert?

Peter II schrieb:
> Warum kein iterrator in C++ verwenden, dürfte noch etwas mehr speed
> bringen, damit könnte man den index zugriff sparen.

Weil die Sparache des TO C# ist... ;-)

Gruß
Markus

von Sam .. (sam1994)


Lesenswert?

Markus Volz schrieb:
> Peter II schrieb:
>> Warum kein iterrator in C++ verwenden, dürfte noch etwas mehr speed
>> bringen, damit könnte man den index zugriff sparen.
>
> Weil die Sparache des TO C# ist... ;-)

Deswegen hab ich es ja mit Indexer gemacht. In c++ könnte man einfach 
str++ schreiben um zum nächten Zeichen zu gelangen. In c# sind Zeigern 
relativ kompliziert und ich hab ehrlich gesagt noch nichts damit 
gemacht.

von Peter R. (gelb)


Lesenswert?

gibt es in C# keine regulären Ausdrücke?

Test = regex(Test, "s/\D//g");

würde alle nicht-Zahlen-Zeichen entfernen.

Grüße, Peter

von bluppdidupp (Gast)


Lesenswert?

Doch gibt es: http://msdn.microsoft.com/de-de/library/c75he57e.aspx

Ich hätte es so gelöst:
1
public int ParseNumber(string s)
2
{
3
  StringBuilder sb = new StringBuilder();
4
  // sb.Append("0"); 
5
6
  foreach (char c in s)
7
  {
8
    if (Char.IsDigit(c))
9
    {
10
      sb.Append(c);
11
    }
12
  }
13
14
  return Int32.Parse(sb.ToString());
15
}

von Markus V. (valvestino)


Lesenswert?

Peter Roth schrieb:
> gibt es in C# keine regulären Ausdrücke?

Doch, gibt es. Die Syntax der Regular Expressions im .NET Framework ist 
allerdings leicht anders:
1
using System.Text.RegularExpressions;
2
...
3
int version;
4
bool parsed = int.TryParse( Regex.Replace( "V1.03",@"\D+","" ),out version );

Gruß
Markus

von Jasch (Gast)


Lesenswert?

Johann schrieb:
> Hallo Leute.
>
> ich will auf auf die Elemente eines Strings zu greifen, wie macht man
> das?

Willst Du an dieser Stelle nicht. ;-)

Aber falls doch: string[0], string[1], etc.

> Das steht in dem String drin. Am Ende will ich ein Ergebnis int =103;

Hmm, hmm, nein, willst Du vermutlich auch nicht.

> string Test ="V1.03"
>
> Theoretisch ist mir klar zuerst muss ich einen neuen String machen in
> dem
> steht "103" und dann mit Convert einen Int draus machen.
>
> Nur weiss ich nicht wie man von dem String "V1.03" auf den String "103"
> kommt.

Ganz falsche Herangehensweise.

Du (und so ziemlich alle bisherigen Antworten auch) nimmst einfach an 
dass alle Versionsstrings (in alle Ewigkeit) dem Muster 
V<Major>.<Minor-with-leading-zero> folgen. Das wird erfahrungsgemäss 
nicht so sein.

Was Du wirklich willst ist sowas:

switch (Test) {
    case "V.1.03":
        foo = 103;
        break;

    case "v1.4":
        foo = 104;
        break;

    default:
        PANIC_CRASH_AND_BURN(); // UNKNOWN SHIT FOUND!
}

(schlauerweise mit definierten Konstanten für die Versionen).

Oder ein Äquivalent mit Hashtabellen oder so falls Du sehr viele 
Versionen hast und das zeitkritisch wäre.

von asdf (Gast)


Lesenswert?

Jasch schrieb:
>
> Du (und so ziemlich alle bisherigen Antworten auch) nimmst einfach an

les dir den thread vielleicht erstmal durch bevor du so einen quatsch 
schreibst

von Sam .. (sam1994)


Lesenswert?

Jasch schrieb:
> Was Du wirklich willst ist sowas:

Ich würde nicht gerne bei jeder neuen Version da noch etwas anhängen. 
Wenn man dann mal bei 100 Einträgen angekommen ist, sieht man ein das es 
Unsinn war.

von Jasch (Gast)


Lesenswert?

Samuel K. schrieb:
> Jasch schrieb:
>> Was Du wirklich willst ist sowas:
>
> Ich würde nicht gerne bei jeder neuen Version da noch etwas anhängen.
> Wenn man dann mal bei 100 Einträgen angekommen ist, sieht man ein das es
> Unsinn war.

Du wirst realistisch niemals 100 dann steinalte Versionen in einer SW 
unterstützen.

Was mit so einer "flexiblen" Lösung passiert ist aber folgendes:

- die andere Seite ändert das Nummernschema, z.B. fliegt die führende 
Null raus weil das jemandem Probleme bei Version 1.08 gemacht hat 
(Bonuspunkte wer erkennt wieso ;-), jetzt folgt plötzlich 
Integer-Versionsnummer 18 auf 107...

- die andere Seite bringt eine neue Version raus, keiner merkt es 
erstmal, bis sich rausstellt es funktioniert irgendwas plötzlich nicht 
mehr, viel Geschrei resultiert

- will man wirklich einfach neue (Fremd-)Versionen im Einsatz haben ohne 
zu testen - und bei der Gelegenheit wäre ein Hinzufügen einer neuen 
Versionsnummer trivial?

Wie gesagt, das ist was ich aus meiner Erfahrung sagen kann, jeder kann 
natürlich machen was er für richtig hält.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.