寻找C#相当于scanf

时间:2009-01-23 07:41:25

标签: c# scanf

我以前用C语言编写代码,发现scanf函数非常有用。 不幸的是,C#中没有相应的东西。

我正在使用它来解析半结构化文本文件。

我找到了scanf实施here的一个有趣的例子。不幸的是,它看起来陈旧且不完整。

有谁知道scanf C#实现?或者至少可以作为反转的string.Format

9 个答案:

答案 0 :(得分:9)

由于文件是“半结构化的”,你不能使用ReadLine()和TryParse()方法的组合,或者使用Regex类来解析数据吗?

答案 1 :(得分:7)

如果正则表达式不适合您,我刚刚发布了sscanf()替代.NET。可以在http://www.blackbeltcoder.com/Articles/strings/a-sscanf-replacement-for-net查看和下载代码。

答案 2 :(得分:5)

您可以直接从C运行时库中使用scanf,但如果您需要使用不同的参数计数运行它,则可能会很困难。我建议你为你执行正则表达式或在这里描述这个任务,也许还有其他方法。

答案 3 :(得分:4)

我找到了一个更好的解决方案,而不是使用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

答案 4 :(得分:4)

您可以导入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框架下运行良好,但不在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框架和单声道中运行良好的方法是不使用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核心下无效。似乎调用C风格的vararg函数被认为是坏的。您应该使用.net库,例如string.format

答案 5 :(得分:3)

有充分的理由说明c#中缺少类似scanf的函数。它很容易出错,而且不灵活。使用Regex更加灵活和强大。

另一个好处是,如果你需要在代码的不同部分解析相同的东西,那么在整个代码中重用会更容易。

答案 6 :(得分:2)

我认为你希望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());
}

答案 7 :(得分:0)

您可以使用System.IO.FileStream和System.IO.StreamReader,然后从那里进行解析。

答案 8 :(得分:-2)

虽然这看起来很粗糙,但确实可以完成工作:

// 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用作记录中的单个变量。