2016-07-19 17 views
0

私はC#でLINQのを学び、少し単語頻度スクリプトを構築しています:C#の標準入力行で列挙型を取得する方法は?

using System; 
using System.Text.RegularExpressions; 
using System.IO; 
using System.Linq; 

class WordCounter 
{ 
    public static void Main(string[] args) 
    { 
     Regex wordRegex = new Regex(@"[\p{L}']+"); 
     File.ReadLines("../test/wordcount_input") 
      .SelectMany(line => wordRegex.Matches(line).Cast<Match>()) 
      .Select(x => x.Value.ToLower()) 
      .GroupBy(x => x) 
      .OrderBy(x => x.Key) 
      .ToList() 
      .ForEach(p => Console.WriteLine("{0} {1}", p.Key, p.Count())); 
    } 
} 

これは動作しますが、私は、標準入力とハードコードされたファイル名を置き換えたいです。残念ながら、私はこれを行う方法がわかりません。私は試しました

Console.In.ReadLines() 

しかし、その方法はConsole.Inに存在しません。ハードコードされたファイル名の代わりに標準入力を使用するにはどうすればよいですか?

(注:。。私は以前のLINQせずにこのスクリプトを書かれているので、質問はLINQのは、私は単純にLINQを学ぶためにしようとしている。この問題のために適切であり、これは良い実験を行うだろうと思ったかどうかではありません)

あなたはこのような方法で書くことができる
+0

処理する前にいくつの行を取得する必要がありますか? –

+2

コンソールで直接このようなことができるかどうかはわかりません。あなたはReactive Extensionsでそれをシミュレートしたり、独自の列挙型とループを構築することができます。 – DavidG

+0

次のようにしてみてください。ただし、メソッドが完了する前にstandardinputを閉じる必要があります。Stream stream = Console.OpenStandardInput(); StreamReader reader =新しいStreamReader(ストリーム); SelectMany(.... – jdweng

答えて

3

private static IEnumerable<string> GetConsoleInputLines() 
{ 
    while (Console.In.Peek() >= 0) 
     yield return Console.ReadLine(); 
} 

Console.ReadLine()の問題は、完全なラインが提供されるまでをブロックしていることです。上記の実装は、それ以上行がない場合は反復を停止します。

あなたがwhile条件を除外した場合、あなたがいる限り、ユーザ入力の新しい行としてこのIEnumerableを繰り返すことができますが、この列挙上の任意のforeachは永遠にブロックします。

+0

)私は、コマンドラインリダイレクト(またはコマンドラインを使用して)を計画しています。パイプの場合)ブロッキングは問題ではありません。リダイレクトせずにコンソール上で実行すると "永遠に"ブロックされても問題ありません。C#標準入力では扱いが違うようですが、Pythonではsysを使用できます。私はJavaで何か簡単にC#が余計な作業を必要とするとは思っていません。だから、( " 'Console.In.Lines()'のようなものがあれば知っていますか? –

+0

@RayToalいいえ、わかりません。Console.Inは['TextReader']です(https://msdn.microsoft.com /en-us/library/system.io.textreader(v=vs.110).aspx)、 'ReadLine()'メソッドしか提供していません。 –

関連する問題