Vous recherchez l'équivalent C# de scanf
J'avais l'habitude de coder en langage C dans le passé et j'ai trouvé la fonction scanf
très utile.
Malheureusement, il n'y a pas d'équivalent en C#.
Je l'utilise pour analyser des fichiers texte semi-structurés.
J'ai trouvé un exemple intéressant de scanf
implémentation ici . Malheureusement, il semble vieux et incomplet.
Est-ce que quelqu'un connaît une implémentation scanf
C#? Ou au moins quelque chose qui fonctionnerait comme un string.Format
inversé?
9 réponses
Si les expressions régulières ne fonctionnent pas pour vous, je viens de poster un sscanf()
remplacement pour. NET. le code peut être consulté et téléchargé à http://www.blackbeltcoder.com/Articles/strings/a-sscanf-replacement-for-net .
Puisque les fichiers sont "semi-structurés", ne pouvez-vous pas utiliser une combinaison de méthodes ReadLine() et TryParse (), ou la classe Regex pour analyser vos données?
Vous pouvez utiliser scanf directement à partir des bibliothèques d'exécution C, mais cela peut être difficile si vous devez l'exécuter avec différents paramètres count. Je vous recommande d'utiliser des expressions régulières pour votre tâche ou de décrire cette tâche ici, peut-être qu'il existe d'autres moyens.
J'ai trouvé une meilleure solution que d'utiliser sscanf de C ou une partie réécrite par quelqu'un (sans offense)
Http://msdn.microsoft.com/en-us/library/63ew9az0.aspx jetez un oeil à cet article, il explique comment faire des groupes nommés pour extraire les données à partir d'un motif de chaîne. Méfiez-vous de la petite erreur dans l'article et la meilleure version ci-dessous. (le côlon ne faisait pas partie du groupe)
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string url = "http://www.contoso.com:8080/letters/readme.html";
Regex r = new Regex(@"^(?<proto>\w+)://[^/]+?(?<port>:\d+)?/",RegexOptions.None, TimeSpan.FromMilliseconds(150));
Match m = r.Match(url);
if (m.Success)
Console.WriteLine(r.Match(url).Result("${proto}:${port}"));
}
}
// The example displays the following output:
// http::8080
Vous pouvez importer msvcrt.DLL.
using System.Runtime.InteropServices;
namespace Sample
{
class Program
{
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int printf(string format, __arglist);
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int scanf(string format, __arglist);
static void Main()
{
int a, b;
scanf("%d%d", __arglist(out a, out b));
printf("The sum of %d and %d is %d.\n", __arglist(a, b, a + b));
}
}
}
Cela fonctionne bien sous. NET framework, cependant, pas sous Mono. Il affiche le message d'erreur:
Unhandled Exception:
System.InvalidProgramException: Invalid IL code in Sample.Program:Main (): IL_0009: call 0x0a000001
[ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidProgramException: Invalid IL code in Sample.Program:Main (): IL_0009: call 0x0a000001
Une autre façon qui fonctionne bien dans. NET framework et mono est de ne pas utiliser arglist
.
using System.Runtime.InteropServices;
namespace Sample
{
class Program
{
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int printf(string format, int a, int b, int c);
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int scanf(string format, out int a, out int b);
static void Main()
{
int a, b;
scanf("%d%d", out a, out b);
printf("The sum of %d and %d is %d.\n", a, b, a + b);
}
}
}
, Mais cette méthode est plus limitée.
Modifier 2018-5-24
L'ancienne méthode qui utilise arglist
ne fonctionne pas sous. net core. Il semble que l'appel de la fonction vararg de style C est considéré comme mauvais. Vous devriez utiliser le. net bibliothèque telle que string.format
à la place.
Il y a une bonne raison pour laquelle une fonction de type scanf est manquante dans c#. Il est très sujet à l'erreur, et pas flexible. L'utilisation de Regex est beaucoup plus flexible et puissante.
Un autre avantage est qu'il est plus facile de réutiliser tout au long de votre code si vous avez besoin d'analyser la même chose dans différentes parties du code.
Je pense que vous voulez que les fonctions de la bibliothèque C# analysent ou convertissent.
// here's an example of getting the hex value from a command line
// program.exe 0x00080000
static void Main(string[] args)
{
int value = Convert.ToInt32(args[1].Substring(2), 16);
Console.Out.WriteLine("Value is: " + value.ToString());
}
Vous pouvez utiliser System. IO. FileStream et System. IO. StreamReader, puis analyser à partir de là.
Bien que cela semble un peu brut, il fait le travail:
// Create the stream reader
sr = new StreamReader("myFile.txt");
// Read it
srRec = sr.ReadLine();
// Replace multiple spaces with one space
String rec1 = srRec.Replace(" ", " ");
String rec2 = rec1.Replace(" ", " ");
String rec3 = rec2.Replace(" ", " ");
String rec4 = rec3.Replace(" ", " ");
String rec5 = rec4.Replace(" ", " ");
String rec6 = rec5.Replace(" ", " ");
String rec7 = rec6.Replace(" ", " ");
String rec8 = rec7.Replace(" ", " ");
String rec9 = rec8.Replace(" ", " ");
// Finally split the string into an array of strings with Split
String[] srVals = rec9.Split(' ');
Vous pouvez ensuite utiliser le tableau srVals comme variables individuelles de l'enregistrement.