web-dev-qa-db-fra.com

Vous recherchez l'équivalent C # de scanf

J'avais l'habitude de coder en langage C dans le passé et la fonction scanf était 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 implementation here . Malheureusement, il a l'air vieux et incomplet.

Est-ce que quelqu'un connaît une implémentation de scanf C #? Ou au moins quelque chose qui fonctionnerait comme un string.Format inversé?

27
Larry

Si les expressions régulières ne fonctionnent pas pour vous, je viens de poster un remplacement de sscanf() pour .NET. Le code peut être visualisé et téléchargé sur http://www.blackbeltcoder.com/Articles/strings/a-sscanf-replacement-for-net .

7
Jonathan Wood

Les fichiers étant "semi-structurés", ne pouvez-vous pas utiliser une combinaison des méthodes ReadLine () et TryParse (), ou la classe Regex pour analyser vos données?

9
Mitch Wheat

Vous pouvez utiliser scanf directement à partir des bibliothèques d'exécution C, mais cela peut s'avérer difficile si vous devez l'exécuter avec un nombre de paramètres différent. Je vous recommande d'utiliser des expressions régulières pour votre tâche ou de décrire cette tâche ici. Il existe peut-être un autre moyen.

5
okutane

J'ai trouvé une meilleure solution que d'utiliser sscanf de C ou une partie réécrite par quelqu'un (aucune infraction)

http://msdn.Microsoft.com/en-us/library/63ew9az0.aspx jetez un oeil sur cet article, il explique comment créer des groupes nommés pour extraire les données utiles d'une chaîne à motif Méfiez-vous de la petite erreur dans l'article et de 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
4
jurik

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 dans le cadre de .net, cependant, pas dans Mono. Il montre 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 manière qui fonctionne bien dans les environnements .net et mono consiste à 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.

Edit 2018-5-24  

La méthode précédente 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 une mauvaise opération. Vous devez utiliser la bibliothèque .net telle que string.format à la place.

4
Jason Lee

Il y a une bonne raison pour laquelle une fonction de type scanf est manquante dans c #. C'est très sujet aux erreurs, et pas flexible. Utiliser Regex est beaucoup plus flexible et puissant.

Un autre avantage est qu'il est plus facile de réutiliser tout votre code si vous devez analyser la même chose dans différentes parties du code.

3
sprite

Je pense que vous voulez que les fonctions de la bibliothèque C # soient Parse ou Convert.

// 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());
}
2
Nichol Draper

Vous pouvez utiliser System.IO.FileStream et System.IO.StreamReader, puis analyser à partir de là.

0
SMB