Ответ 1
Если регулярные выражения не работают для вас, я только что опубликовал замену sscanf()
для .NET. Код можно просмотреть и загрузить в http://www.blackbeltcoder.com/Articles/strings/a-sscanf-replacement-for-net.
Я использовал код на языке C в прошлом, и я нашел, что функция scanf
очень полезна.
К сожалению, на С# нет эквивалента.
Я использую его для разбора полуструктурированных текстовых файлов.
Я нашел интересный пример реализации scanf
здесь. К сожалению, он выглядит старым и неполным.
Кто-нибудь знает реализацию scanf
С#? Или, по крайней мере, что-то, что работает как обратный string.Format
?
Если регулярные выражения не работают для вас, я только что опубликовал замену sscanf()
для .NET. Код можно просмотреть и загрузить в http://www.blackbeltcoder.com/Articles/strings/a-sscanf-replacement-for-net.
Так как файлы "полуструктурированы", вы не можете использовать комбинацию методов ReadLine() и TryParse() или класс Regex для анализа ваших данных?
Вы можете использовать scanf непосредственно из библиотек времени выполнения C, но это может быть сложно, если вам нужно запустить его с разными параметрами. Я рекомендую вам регулярные выражения для вашей задачи или описывать эту задачу здесь, возможно, есть и другие способы.
Я нашел лучшее решение, чем использование 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
Попробуйте импортировать 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
Если вам нужна совместимость с 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 Core. Кажется, что вызов функции C vararg не рекомендуется. String.Format
этого вы должны использовать .NET string API, например String.Format
.
Есть веская причина, по которой функция cssf отсутствует в С#. Он очень подвержен ошибкам и не является гибким. Использование Regex гораздо более гибкое и мощное.
Другим преимуществом является то, что проще использовать его во всем коде, если вам нужно разобрать одно и то же в разных частях кода.
Я думаю, что вы хотите, чтобы функции библиотеки С# выполнялись либо в Parse, либо в Convert.
// here 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());
}
Вы можете использовать System.IO.FileStream и System.IO.StreamReader, а затем проанализировать оттуда.
Хотя это выглядит грубо, он выполняет свою работу:
// 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 как отдельные переменные из записи.