我过去曾经用 C 语言编写代码,我发现这个scanf
函数非常有用。不幸的是,C# 中没有等价物。
我正在使用它来解析半结构化文本文件。
我在这里scanf
找到了一个有趣的实现示例。不幸的是,它看起来又旧又不完整。
有谁知道scanf
C# 实现?或者至少可以作为反向的东西string.Format
?
由于文件是“半结构化的”,您不能使用 ReadLine() 和 TryParse() 方法的组合,或者 Regex 类来解析您的数据吗?
如果正则表达式不适合您,我刚刚发布了sscanf()
.NET 的替代品。该代码可以在http://www.blackbeltcoder.com/Articles/strings/a-sscanf-replacement-for-net查看和下载。
您可以直接从 C 运行时库中使用 scanf,但如果您需要使用不同的参数计数来运行它,这可能会很困难。我建议您为您的任务使用正则表达式或在此处描述该任务,也许还有其他方法。
我找到了比使用 C 中的 sscanf 或某些人重写的部分更好的解决方案(无冒犯)
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
c# 中缺少类似 scanf 的函数是有充分理由的。它很容易出错,而且不灵活。使用正则表达式更加灵活和强大。
另一个好处是,如果您需要在代码的不同部分解析相同的内容,则更容易在整个代码中重用。
尝试导入 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 函数。您应该改用 .NET 字符串 API,例如String.Format
。
我认为您想要 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());
}
您可以使用 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 用作记录中的单个变量。