Laden...

unbekannte Anzahl Parameter...

Erstellt von yngwie vor 19 Jahren Letzter Beitrag vor 19 Jahren 3.365 Views
Y
yngwie Themenstarter:in
238 Beiträge seit 2005
vor 19 Jahren
unbekannte Anzahl Parameter...

Hallo Leute,
ich fange gerade an C# zu lernen und hab's deswegen noch nicht so drauf...
Wie kann ich eine Funktion basteln, der mehrere doubles als Parameter übergeben werden, wenn die Zahl der Parameter noch nicht feststeht? Beispiel:
Eine Klasse für einen n-dimensionalen Vektor muss erstellt werden. Er hat Anfangs- und Endpunktkoordinaten und ihre Anzahl hängt ja davon ab ob das ein zwei-, drei-, oder n-dimensione Vektor ist. Nun möchte ich so etwas wie:

[public void CreateVector (double x, double y, usw......)
{
}

basteln. Aber mal sind es nur 2, mal 18 doubles, die übergeben werden müssen.
Natürlich könnte ich den Benutzer diese Eingaben auch interaktiv machen lassen,(übrigens was ist in C# die Entsprechung zu "scanf" aus C++) bin aber sicher dass es auch elegantere Lösungsmöglichkeiten gibt🙂
Wie kann ich dieses Problem lösen???
Danke für jeden Denkanstoss.

D
279 Beiträge seit 2004
vor 19 Jahren

Das kannst du mit dem Schlüsselwort 'params' machen,


private void asdf(params double[] values)
{
	for (int i = 0; i < values.Length; i++)
	{
		//tuwas
	}
}

H
704 Beiträge seit 2003
vor 19 Jahren

Original von yngwie
(übrigens was ist in C# die Entsprechung zu "scanf" aus C++) .

eine 1zu1 Portierung gibt es in der FCL nicht. Du kannst System.Console.ReadLine verwenden

Um einen string einzulesen machst du es so:


string s = Console.ReadLine();

und um Zahlen einzulesen:


int i = Convert.ToInt32(Console.ReadLine());

die Convert Klasse bietet natürlich noch mehr Funktionen als nur ToInt32.

Aber du kannst dir ja mit diesen Funktionen ein eigenes scanf schreiben, wenn du das wirklich willst ^^

[last.fm](http://www.last.fm/user/hauptmanAlpha/)
M
456 Beiträge seit 2004
vor 19 Jahren

Auf Codeproject gibt's ne Funktion die scanf emuliert:
http://www.codeproject.com/csharp/CsScanf.asp

I am Jack's smirking revenge.
I am Jack's raging bile duct.
I am Jack's cold sweat.
I am Jack's complete lack of surprise.
I am Jack's broken heart.
I am Jack's wasted life.

49.485 Beiträge seit 2005
vor 19 Jahren

Hallo yngwie,

ich würde gerne noch RegularExpressions in den Raum werfen. Im Kern geht es bei den RE darum festzustellen, ob ein bestimmter Text (z.B. eine Eingabe) auf ein bestimmtes Muster passt (also z.B. dem Format einer E-Mail-Adresse entspricht).

RE leisten aber noch viel mehr, insbesondere kann man sie gut benutzen, um einzelne Bestandteile aus einer Eingabe zu extrahieren.

Ein Beispiel:


using System;
using System.Text.RegularExpressions;

public static int Main (string [] astrArg)
{
   // Das Muster, auf das die Eingabe passen soll (Zahl und Wort, getrennt durch Leerzeichen)
   Regex reBsp = new Regex (@"(\\d+)\\s+([a-z0-9_]+)$", RegexOptions.IgnoreCase);
   // Test durchführen
   Match mBsp = reBsp.Match("123 abc");
   // Passt das Muster auf die Eingabe?
   if (mBsp.Success) {
      // Ja, es passt, dann holen wir uns die Bestandteile (Zahl und Wort)
      int    iZahl   = Convert.ToInt32 (mBsp.Groups [1].ToString ());
      String strWort = mBsp.Groups [2].ToString ();
      // Und geben sie aus
      Console.WriteLine("Inhalt der ersten Klammer: " + iZahl);
      Console.WriteLine("Inhalt der ersten Klammer: " + strWort);
   } else {
      // ggf. weitere Eingabeformate behanden oder Fehler behanden
      // oder inorieren
   }
}

Dabei wird eine Eingabe (hier der Einfachheit habler fest "123 abc"; sonst mit ReadLine o.ä. einlesen) darauf geprüft, ob sie sofort am Zeilenbegin '^' mit einer Ziffer '\d' beginnt, der weitere Ziffern folgen '\d+' ('+' bedeutet eine Folge von 1 oder mehr des angegebenen Zeichens), wobei diese Folge gemerkt werden soll '(\d+)'. Anschließend muss mindestens ein Leerzeichen (genauer White Space) folgen '\s+' und dann ein Wort bestehend aus Kleinbuchstaben 'a-z', wegen RegexOptions.IgnoreCase auch den entsprechenden Großbuchstaben, Ziffern '0-9' und/oder dem Unterstrich '', also zusammen die Zeichen '[a-z0-9]', die als Folge '[a-z0-9_]+' gemerkt werden soll '([a-z0-9_]+)'. Das Wort muss bis zum Zeilenende '$' gehen.

Auf die gemerkten, in Kammern stehenden Teile kann man über mBsp.Groups _ zugreifen, wobei i für die i-te Klammer im Muster steht.

Sicher muss man sich etwas mit den RE beschäftigen, aber wenn man die einmal drauf hat, hat man ein universelles, leistungsfähiges (String-)Analyse- und Bearbeitungswerkzeug an der Hand.

Wenn man sich so eine RE zum ersten Mal anguckt, sieht die sicher ziemlich krank aus, aber das Schreiben einer RE ist ziemlich einfach, weil man von links nach rechts einfach hinscheibt, was man an Eingabezeichen erwartet. Man muss also nicht den ganzen Ausdruck auf einmal entwerfen, sondern man schreibt die RE schrittweise von links nach rechts, wobei es reicht immer nur der aktuellen Position seine Aufmerksamkeit zu schenken.

Zum Thema Bearbeitungswerkzeug hier noch ein Beispiel aus der .NET-Doku, das einen Datumsstring von einem Format in ein anderes umwandelt:


static String MDYToDMY (String input)
{
   return Regex.Replace(input,
            "\\b(?<month>\\d{1,2})/(?<day>\\d{1,2})/(?<year>\\d{2,4})\\b",
            "${day}.${month}.${year}");
}

HTH

herbivore