2008-10-14 7 views

Répondre

37

Vous devez utiliser Console.Read() et Console.ReadLine() comme si vous lisiez l'entrée utilisateur. Les tuyaux remplacent l'entrée de l'utilisateur de manière transparente. Vous ne pouvez pas utiliser les deux facilement (même si je suis sûr que c'est tout à fait possible ...).

Edit:

Un simple programme de style cat:

class Program 
{ 
    static void Main(string[] args) 
    { 
     string s; 
     while ((s = Console.ReadLine()) != null) 
     { 
      Console.WriteLine(s); 
     } 

    } 
} 

Et lorsqu'il est exécuté, comme prévu, la sortie:

 
C:\...\ConsoleApplication1\bin\Debug>echo "Foo bar baz" | ConsoleApplication1.exe 
"Foo bar baz" 

C:\...\ConsoleApplication1\bin\Debug> 
+1

Votre exemple fonctionne pour: echo "Foo bar baz" | ConsoleApplication1.exe | ConsoleApplication1.exe? –

+2

Oui. En utilisant une analogie de niveau inférieur, ce qui se passe réellement avec un canal est que le flux Stdout de la première application est branché sur le flux Stdin de l'application suivante dans le pipeline. Le stdin de la console passe à travers la première application, et la dernière application stdout est affichée. –

+0

Tommorow Je vais essayer ça !!! Thx :) –

2

Console.In est une référence à un TextReader enroulé autour du flux d'entrée standard. Lorsque vous envoyez de grandes quantités de données à votre programme, il peut être plus facile de travailler de cette façon.

1

Il y a un problème avec l'exemple fourni.

while ((s = Console.ReadLine()) != null) 

sera bloqué en attente d'entrée si le programme a été lancé sans données passepoilées. L'utilisateur doit donc appuyer manuellement sur n'importe quelle touche pour quitter le programme.

+0

qui est plus digne d'un commentaire, et d'autres ont abordé cela et une solution – barlop

13

Ce qui suit ne suspend pas l'application pour la saisie et fonctionne lorsque les données ou ne sont pas canalisées. Un peu un hack; et en raison de l'erreur d'attraper, la performance pourrait manquer lorsque de nombreux appels sont effectués, mais ... facile.

public static void Main(String[] args) 
{ 

    String pipedText = ""; 
    bool isKeyAvailable; 

    try 
    { 
     isKeyAvailable = System.Console.KeyAvailable; 
    } 
    catch (InvalidOperationException expected) 
    { 
     pipedText = System.Console.In.ReadToEnd(); 
    } 

    //do something with pipedText or the args 
} 
+0

Grand tour, merci pour cela! – Tao

+0

la réponse ici par hans passant http://stackoverflow.com/questions/3453220/how-to-detect-if-console-in-stdin-has-bien-redirected près de la fin, mentionne un moyen encore mieux 'System. Console.WriteLine (System.Console.IsInputRedirected.ToString()); ' – barlop

3

Voici une autre solution qui a été mise en place à partir des autres solutions plus un peek().

Sans le Peek(), j'apprenais que l'application ne retournerait pas sans ctrl-c à la fin en faisant "t.txt | prog.exe" où t.txt est un fichier multi-ligne. Mais juste "prog.exe" ou "echo hi | prog.exe" a bien fonctionné.

Ce code est destiné à traiter uniquement l'entrée canalisée.

static int Main(string[] args) 
{ 
    // if nothing is being piped in, then exit 
    if (!IsPipedInput()) 
     return 0; 

    while (Console.In.Peek() != -1) 
    { 
     string input = Console.In.ReadLine(); 
     Console.WriteLine(input); 
    } 

    return 0; 
} 

private static bool IsPipedInput() 
{ 
    try 
    { 
     bool isKey = Console.KeyAvailable; 
     return false; 
    } 
    catch 
    { 
     return true; 
    } 
} 
+1

la réponse ici par hans passant http://stackoverflow.com/questions/3453220/how-to-detect-if-console-in-stdin-has -been-redirigé vers la fin, mentionne un moyen encore mieux 'System.Console.WriteLine (System.Console.IsInputRedirected.ToString());' – barlop

6

C'est la façon de le faire:

static void Main(string[] args) 
{ 
    Console.SetIn(new StreamReader(Console.OpenStandardInput(8192))); // This will allow input >256 chars 
    while (Console.In.Peek() != -1) 
    { 
     string input = Console.In.ReadLine(); 
     Console.WriteLine("Data read was " + input); 
    } 
} 

Cela permet à deux méthodes d'utilisation. Lire à partir de l'entrée standard :

C:\test>myProgram.exe 
hello 
Data read was hello 

ou lire à partir de passepoilées entrée:

C:\test>echo hello | myProgram.exe 
Data read was hello 
7

dans .NET 4.5 il est

if (Console.IsInputRedirected) 
{ 
    using(stream s = Console.OpenStandardInput()) 
    { 
     ... 
+0

Salut, je ne peux pas sembler le faire fonctionner avec ce code, des idées ? –

0

Cela fonctionne également pour

c: \ MyApp.exe < input.txt

je devais utiliser un StringBuilder pour manipuler les entrées capturées à partir Stdin:

public static void Main() 
{ 
    List<string> salesLines = new List<string>(); 
    Console.InputEncoding = Encoding.UTF8; 
    using (StreamReader reader = new StreamReader(Console.OpenStandardInput(), Console.InputEncoding)) 
    { 
     string stdin; 
     do 
     { 
      StringBuilder stdinBuilder = new StringBuilder(); 
      stdin = reader.ReadLine(); 
      stdinBuilder.Append(stdin); 
      var lineIn = stdin; 
      if (stdinBuilder.ToString().Trim() != "") 
      { 
       salesLines.Add(stdinBuilder.ToString().Trim()); 
      } 

     } while (stdin != null); 

    } 
}