Buscando el equivalente C # de scanf

Solía ​​codificar en lenguaje C en el pasado y encontré la función scanf muy útil. Desafortunadamente, no hay equivalente en C #.

Estoy usando su uso para analizar archivos de texto semiestructurados.

Encontré un ejemplo interesante de la implementación de scanf aquí . Desafortunadamente, parece viejo e incompleto.

¿Alguien sabe una implementación scanf C #? O al menos algo que funcionaría como una string.Format invertida string.Format ¿ string.Format ?

Si las expresiones regulares no funcionan para usted, acabo de publicar un reemplazo de sscanf() para .NET. El código se puede ver y descargar en http://www.blackbeltcoder.com/Articles/strings/a-sscanf-replacement-for-net .

Dado que los archivos están “semiestructurados”, ¿no puede usar una combinación de métodos ReadLine () y TryParse () o la clase Regex para analizar sus datos?

Puede usar scanf directamente de las bibliotecas de tiempo de ejecución de C, pero esto puede ser difícil si necesita ejecutarlo con un recuento de parámetros diferente. Te recomiendo expresiones regulares para tu tarea o describas esa tarea aquí, tal vez haya otras formas.

He encontrado una mejor solución que usar sscanf de C o alguna parte reescrita por alguien (sin ofender)

http://msdn.microsoft.com/en-us/library/63ew9az0.aspx eche un vistazo a este artículo y explica cómo crear grupos con nombre para extraer los datos deseados de una cadena con patrones. Tenga cuidado con el pequeño error en el artículo y la mejor versión a continuación. (el colon no era parte del grupo)

 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(@"^(?\w+)://[^/]+?(?:\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 

Hay una buena razón por la que falta una función escaneada como de c #. Es muy propenso al error y no es flexible. Usar Regex es mucho más flexible y poderoso.

Otro beneficio es que es más fácil de reutilizar a través de su código si necesita analizar lo mismo en diferentes partes del código.

Puede importar 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)); } } } 

Funciona bien bajo .NET Framework, sin embargo, no bajo Mono. Muestra el mensaje de error:

 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 

Otra forma que funciona bien en .net framework y mono no es usar 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); } } } 

Pero este método es más limitado.

Editar 2018-5-24

La forma anterior que utiliza arglist no funciona en .net core. Parece que llamar a la función vararg estilo C se considera malo. Debería usar la biblioteca .net como string.format en string.format lugar.

Creo que quieres que las funciones de la biblioteca C # sean Parse o 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()); } 

Puede usar System.IO.FileStream y System.IO.StreamReader, y luego analizar desde allí.

Aunque parece un poco crudo, hace el trabajo:

 // 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(' '); 

Luego puede usar la matriz srVals como variables individuales del registro.