stdin
Dartでコンソール入力を読み取るにはどうすればよいですか?
scanf
ダートにありますか?
stdinのreadLineSync()メソッドを使用すると、コンソールから文字列をキャプチャできます。
import 'dart:convert';
import 'dart:io';
void main() {
print('1 + 1 = ...');
var line = stdin.readLineSync(encoding: utf8);
print(line?.trim() == '2' ? 'Yup!' : 'Nope :(');
}
古いバージョン:
import 'dart:io';
main() {
print('1 + 1 = ...');
var line = stdin.readLineSync(encoding: Encoding.getByName('utf-8'));
print(line.trim() == '2' ? 'Yup!' : 'Nope :(');
}
以下は、stdinからの入力を読み取るための最新のdartコードである必要があります。
import 'dart:async';
import 'dart:io';
import 'dart:convert';
void main() {
readLine().listen(processLine);
}
Stream<String> readLine() => stdin
.transform(utf8.decoder)
.transform(const LineSplitter());
void processLine(String line) {
print(line);
}
import 'dart:io';
void main(){
stdout.write("Enter your name : ");
var name = stdin.readLineSync();
stdout.write(name);
}
出力
Enter your name : Jay
Jay
デフォルトでは、readLineSync()は入力を文字列として受け取ります。ただし、整数入力が必要な場合は、parse()またはtryparse()を使用する必要があります。
StringInputStreamのようなM3dartクラスが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. */);
}
Dart 2.12以降、null-safetyが有効になり、の代わりにをstdin.readLineSync()
返すようになりました。String?
String
これは明らかに多くの人々を混乱させてきました。null-safetyの意味を理解するには、 https://dart.dev/null-safety/understanding-null-safetyを読むことを強くお勧めします。
具体的には、最初にstdin.readLineSync()
チェックすることでこれを解決できます。ローカル変数の場合、これは自動的にに昇格します。ここではいくつかの例を示します。null
String?
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
aを返します。入力がなくなると戻ります。nullアサーション演算子( )を使用すると、実行時例外が要求されます。String?
null
!
あなたの呼び出しはブロックされ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 ;
});
}
次の行を使用して、ユーザーから文字列を読み取ることができます。
String str = stdin.readLineSync();
または次の行で数字を読みます
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");
* */
}
これらの非同期APIreadLine*()ベースのソリューションはすべて、同期ブロッキングなしですべてを実行できる構文糖衣構文を欠いていますが、同期コードのように記述されています。これは、同期的に実行するコードを作成する他の言語から来ると、さらに直感的になります。
import 'dart:convert';
import 'dart:io';
Future<void> main() async {
var lines = stdin.transform(utf8.decoder).transform(const LineSplitter());
await for (final l in lines) {
print(l);
}
print("done");
}
ここでの重要なポイントは、とを利用することasync
ですawait
。
async
await
非同期API呼び出しとのインターフェースに使用しているため、メソッドにが必要ですawait for
は、で「同期のような」コードを実行するStream
ための構文です(aに対応する構文Future
はちょうどですawait
)。何かを処理できるようになったら、次のコードを実行して、 /をawait
「アンラップ」するようなものと考えてください。これで、作業を行うためにメインスレッド()をブロックしなくなりました。Stream
Future
Isolate
詳細については、async/awaitのDartコードラボを参照してください。
(補足:関数の戻り値を宣言する正しい方法は、async
関数をで囲むことです。Future
したがって、Future<void>
ここにあります。)