如何在Dart中读取控制台输入/ stdin?

时间:2012-06-20 15:19:12

标签: dart dart-io

如何从Dart中的stdin读取控制台输入?

Dart中有scanf吗?

7 个答案:

答案 0 :(得分:18)

stdin readLineSync()方法允许从控制台捕获字符串:

import 'dart:io';

main() {
    print('1 + 1 = ...');
    var line = stdin.readLineSync(encoding: Encoding.UTF_8);
    print(line.trim() == '2' ? 'Yup!' : 'Nope :(');
}

答案 1 :(得分:6)

以下应该是最新的dart代码,用于从stdin读取输入。

import 'dart:async';
import 'dart:io';
import 'dart:convert';

void main() {
  readLine().listen(processLine);
}

Stream readLine() => stdin
  .transform(UTF8.decoder)
  .transform(new LineSplitter());

void processLine(String line) {
  print(line);
}

答案 2 :(得分:3)

使用像StringInputStream这样的M3 dart类替换为Stream,试试这个:

import 'dart:io';
import 'dart:async';

void main() {
  print("Please, enter a line \n");
  Stream cmdLine = stdin
      .transform(new StringDecoder())
      .transform(new LineTransformer());

  StreamSubscription cmdSubscription = cmdLine.listen(
    (line) => print('Entered line: $line '),
    onDone: () => print(' finished'),
    onError: (e) => /* Error on input. */);


}

答案 3 :(得分:2)

从 Dart 2.12 开始,启用了空安全,并且 stdin.readLineSync() 现在返回 String? 而不是 String

这显然让很多人感到困惑。我强烈建议您阅读 https://dart.dev/null-safety/understanding-null-safety 以了解空安全的含义。

特别是对于 stdin.readLineSync(),您可以通过首先检查 null 来解决此问题,对于 local 变量,它会自动将 String? 提升为 {{1 }}。以下是一些示例:

String
// Read a line and try to parse it as an integer.
String? line = stdin.readLineSync();
if (line != null) {
  int? num = int.tryParse(line); // No more error about `String?`.
  if (num != null) {
    // Do something with `num`...
  }
}
// Read lines from `stdin` until EOF is reached, storing them in a `List<String>`.
var lines = <String>[];
while (true) {
  var line = stdin.readLineSync();
  if (line == null) {
    break;
  }
  lines.add(line); // No more error about `String?`.
}

请注意,您应该不要盲目地做// Read a line. If EOF is reached, treat it as an empty string. String line = stdin.readLineSync() ?? ''; stdin.readLineSync()! 返回 readLineSync 是有原因的:当没有更多输入时它返回 String?。使用 null assertion operator (null) 会要求运行时异常。

答案 4 :(得分:0)

请注意,调用 stdin.readLineSync() 时,您的 isolate/thread 将被阻止,其他 Future 不会完成。

如果你想异步读取 stdin String 行,避免 isolate/thread 块,方法如下:

import 'dart:async';
import 'dart:convert';
import 'dart:io';

/// [stdin] as a broadcast [Stream] of lines.
Stream<String> _stdinLineStreamBroadcaster = stdin
    .transform(utf8.decoder)
    .transform(const LineSplitter()).asBroadcastStream() ;

/// Reads a single line from [stdin] asynchronously.
Future<String> _readStdinLine() async {
  var lineCompleter = Completer<String>();

  var listener = _stdinLineStreamBroadcaster.listen((line) {
    if (!lineCompleter.isCompleted) {
      lineCompleter.complete(line);
    }
  });

  return lineCompleter.future.then((line) {
    listener.cancel();
    return line ;
  });
}

答案 5 :(得分:0)

您可以使用以下行从用户处读取字符串

String str = stdin.readLineSync();

OR 以下行读取数字

int n = int.parse(stdin.readLineSync());

考虑以下示例:

import 'dart:io'; // we need this to use stdin
void main()
{
    // reading the user name
    print("Enter your name, please: ");
    String name = stdin.readLineSync();
  
    // reading the user age
    print("Enter your age, please: ");
    int age = int.parse(stdin.readLineSync());
  
    // Printing the data
    print("Hello, $name!, Your age is: $age");
  
  /* OR print in this way
   * stdout.write("Hello, $name!, Your age is: $age");
   * */
}

答案 6 :(得分:-1)

        <ListView
            Name="RootControl"
            ItemsSource="{Binding [icons]}"
            ItemTemplate="{StaticResource IconTemplate}">
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel
                        Width="{Binding ElementName=RootControl, Path=ActualWidth}"/>
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
        </ListView>

输出

import 'dart:io';

void main(){
  stdout.write("Enter your name : ");
  var name = stdin.readLineSync();
  stdout.write(name);
}

默认情况下,readLineSync()将输入作为字符串。但是,如果要输入整数,则必须使用parse()或tryparse()。