Ищете C # эквивалент Scanf - PullRequest
       13

Ищете C # эквивалент Scanf

29 голосов
/ 23 января 2009

Раньше я программировал на языке Си, и функция scanf оказалась очень полезной. К сожалению, в C # нет эквивалента.

Я использую его для разбора полуструктурированных текстовых файлов.

Я нашел интересный пример реализации scanf здесь . К сожалению, оно выглядит старым и неполным.

Кто-нибудь знает реализацию scanf C #? Или, по крайней мере, что-то, что будет работать как обратный string.Format?

Ответы [ 9 ]

9 голосов
/ 23 января 2009

Поскольку файлы "полуструктурированы", вы не можете использовать комбинацию методов ReadLine () и TryParse () или класс Regex для анализа ваших данных?

7 голосов
/ 25 февраля 2011

Если регулярные выражения не работают для вас, я только что опубликовал замену sscanf() для .NET. Код можно просмотреть и загрузить по адресу http://www.blackbeltcoder.com/Articles/strings/a-sscanf-replacement-for-net.

5 голосов
/ 07 августа 2013

Я нашел лучшее решение, чем использование sscanf из C или какой-либо переписанной части кем-то (без обид)

http://msdn.microsoft.com/en-us/library/63ew9az0.aspx взгляните на эту статью, она объясняет, как создавать именованные группы для извлечения нужных данных из шаблонной строки. Остерегайтесь маленькой ошибки в статье и лучшей версии ниже. (двоеточие не входило в группу)

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
5 голосов
/ 23 января 2009

Вы можете использовать scanf напрямую из библиотек времени выполнения C, но это может быть сложно, если вам нужно запустить его с другим количеством параметров. Я рекомендую вам регулярные выражения для вашей задачи или опишите эту задачу здесь, может быть, есть другие способы.

4 голосов
/ 05 января 2017

Вы можете импортировать 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));
        }
    }
}

Хорошо работает в .net framework, но не в Mono. Показывает сообщение об ошибке:

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

Еще один способ, который хорошо работает как в .net framework, так и в mono, это не использовать 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);
        }
    }
}

Но этот метод более ограничен.

Изменить 2018-5-24

Первый способ, который использует arglist, не работает под ядром .net. Кажется, что вызов функции vararg в стиле C считается плохим. Вместо этого вам следует использовать библиотеку .net, например string.format.

3 голосов
/ 22 июня 2010

Есть веская причина, почему в c # отсутствует функция, подобная scanf. Это очень подвержено ошибкам, и не гибкий. Использование Regex гораздо более гибкое и мощное.

Еще одним преимуществом является то, что проще повторно использовать весь код, если вам нужно проанализировать одно и то же в разных частях кода.

2 голосов
/ 01 октября 2009

Я думаю, что вам нужны функции библиотеки C #: Parse или 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());
}
0 голосов
/ 06 января 2016

Несмотря на то, что это выглядит довольно грубо, работа будет выполнена:

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

Затем вы можете использовать массив srVals как отдельные переменные из записи.

0 голосов
/ 23 января 2009

Вы можете использовать System.IO.FileStream и System.IO.StreamReader, а затем анализировать оттуда.

...