質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

29285閲覧

Pythonにおける標準入力について(scanfみたいに使いたい)

sakakendo0321

総合スコア45

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2016/12/04 12:42

###今まで使っていた標準入出力
Pythonの標準入出力をcのscanfみたいに使いたいのですができないのでしょうか?
例えばスペース区切りのint型の数字を受け取るとき入力が以下の時

> 1 2 3 N=map(int,raw_input().split())

とすればいいところまでは自力で調べてわかりました

###入力する値が複雑になった時に対応してほしい標準入出力
######例えば入力値がカンマ区切り,改行区切りになった時に必要な情報だけを変数に入れてくれるもの

> 1,2,3 scanf("%d,%d,%d",&a,&b,&c); >1 >2 >3 scanf("%d\n%d\n%d",&a,&b,&c)

のかわりになるもの

#####もしくは文字に制限をかけるスキャン集合指定子みたいな作用をするもの
cでいうと以下のように使えるやつ

scanf("%[0123456789]" , str); scanf("%[^\n]" , str);

上記のような作用をしてくれる標準入力が欲しいんですが何か方法はありませんか?
いろいろ端折ってわかりにくくなっているところあると思いますがよろしくお願いします

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

scanf()は便利そうに見えて、実はそれほど便利ではありません。Cの標準関数は実装がしやすいかどうかで作られていった経緯があるため、使えないことは無いけど、そこまで実用的では無いという関数も多いです。そのうちの一つがscanf()だと思います。そのため、後の言語では全く採用しないか、外部ライブラリでひっそり用意するかになっています。

さて、それはおいといて解決策です。考え方は二つです。改行まで全てを受け取るところまでは同じで、その後に分解するか、正規表現でマッチングさせるかで変わります。さらに必要なものに変換するという形です。それぞれについて書きたいと思います。なお、raw_input()はPython3でなくなりinput()を使うようになりました。下記のコードは全てPython3での動作を前提としています。

###フォーマットにあわせて分解し、それぞれを変換する。

Python

1# scanf("%d,%d,%d",&a,&b,&c); 2a, b, c = map(int, input().split(",")) 3 4# scanf("%d\n%d\n%d",&a,&b,&c) 5a = int(input()) 6b = int(input()) 7c = int(input()) 8 9# scanf("%[0123456789]" , str); 10from itertools import takewhile 11str = "".join(takewhile(lambda c: c in "0123456789", input())) 12 13# scanf("%[^\n]" , str); 14str = input()

それぞれがCのscanf()と全く同じ訳では無い事に注意してください。3番目の例は後述の正規表現を使った方が簡単になると思います。

考え方は簡単です。始めにinput()で1行全てを読み込んで文字列にしてしまいます。あとは、その文字列を加工していくだけです。split()で分けたり、strip()で余計な空白を削除したり、int()float()で変換したりします。スペース区切りやカンマ区切りなどのデータであれば一番簡単でしょう。また、siplt()で分けた後は、個別に処理ができますので、2番目は整数または文字列といった処理もできます。

###フォーマットに対する正規表現でマッチングさせる。

3番目の例だけは正規表現の方が良いだろうとのことでした。

Python

1# scanf("%[0123456789]" , str); 2import re 3m = re.match(r'\d*', input()) 4str = m.group(0)

考えは先ほどとほぼ同じです。ただ、文字列の分解に正規表現を用いています。正規表現はscanf()のフォーマットとは比べものにならないぐらいとても強力です。しかし、それだけで本が一冊書けるほどの奥の深さがあります。ですが、どんなに複雑なフォーマットでも正規表現を使うと表現が可能であり、ほとんどの場合は簡潔に書くことができます。

投稿2016/12/04 22:33

raccy

総合スコア21735

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

公式っぽい説明は次の通り。

そのようなものはありません。

Pythonは「やりかたはひとつにする」という志向が強いので、正規表現でできるのならscanfはいらない、ということになるようです。

実際、reのマニュアルを読めば、ちゃんとやりかたが書いてあります。

あと、scanf系関数はあまり柔軟ではないという問題があります。想定外の入力があると簡単に失敗します (個人的には、Cでもscanf(3)/fscanf(3)/sscanf(3)を使おうと思ったことはないです)。正規表現を利用すればもっと柔軟な処理が処理ができます。たとえばトークナイザを書くことができますから、これを元に任意の構文規則をもつ入力を解析することができます。

上で「利用」と強調したのは、上例の通り、正規表現によるパターンマッチングだけで柔軟な処理ができるわけではないからです。マニュアルを読めば実例つきで解説があるのに、なぜか「○○する正規表現を教えて下さい」という質問をよくみかけますね。

もっとも、あまり柔軟でなくていい場合や特殊な用途には、専用の機能が用意されています。

以上を読んで、それでもscanf()を使いたい、自分にはscanf()しかない、と思うのなら、モジュールをインストールすればできます。

投稿2016/12/05 02:13

ikedas

総合スコア4317

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問