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é?

27
demandé sur I82Much 2009-01-23 10:41:25

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 .

7
répondu Jonathan Wood 2011-02-25 06:17:14

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?

9
répondu Mitch Wheat 2012-01-27 18:51:22

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.

5
répondu okutane 2009-01-23 07:54:15

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
4
répondu jurik 2017-04-03 09:30:53

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.

4
répondu Jason Lee 2018-05-24 02:14:35

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.

3
répondu sprite 2010-06-22 06:38:52

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());
}
2
répondu Nichol Draper 2009-09-30 21:46:53

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

0
répondu SMB 2009-01-23 07:58:08

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.

-2
répondu whatsRegex 2016-01-06 01:48:22