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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

5回答

1117閲覧

入力によって、入力数が決められ、スペース入力の場合、どのようにscanfしたらいいでしょうか。

MOTOMUR

総合スコア195

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2018/03/16 14:13

編集2018/03/16 15:53

競技プログラミングの練習用のごくごく入門の問題を解いていたのですが、つまづいてしまったので質問です。

タイトル長くなりましたが、この場合どのように検索したらよかったのでしょう。

「C言語 空白複数入力」とか「C言語 スペース 入力」とかいろいろ検索してみましたが、解決方法が見つからず。
どのような入力パターンかというと。

4 1 3 5 2
6 7 1 3 5 2 4

このようなパターンです。

最初の数字が個数で、改行の入力であればforで回せば取得できるというのは知っていたのですが、空白入力の書き方が、入力数固定以外で知らなかったので、また検索仕方がわからなかったので、質問させていただきました。

ご指摘を受けて。

タグを修正しました。
scanfは改行も空白も同じであるとわかりました。

C++を競技プログラミングは採用しているので、C++らしいコードを書いた方がいいとご指摘を受けました。

今後競技プログラミング以外での使用を考えたときにはscanfではない方がいいということがわかりました。

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

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

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

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

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

guest

回答5

0

ベストアンサー

実用性はないが競プロに限ってゴリ押しするなら
scanfは「空白・タブも改行と同じ区切り文字として扱う」ので
適当でもどうにかなる

c

1#include <stdio.h> 2#include <stdlib.h> 3 4main(){ 5 int mx; 6 int *buf; 7 scanf("%d", &mx); 8 buf = malloc(mx * sizeof(*buf)); 9 for(int i = 0;i < mx; i++) 10 scanf("%d", buf+i); 11 // とりあえず、最終入力を表示 12 printf("=> %d\n", buf[mx - 1]); 13}

投稿2018/03/16 15:27

asm

総合スコア15147

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

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

MOTOMUR

2018/03/16 15:39

>「空白・タブも改行と同じ区切り文字として扱う」 ということを知りませんでした。簡単にごり押せたのですね。 %dは改行、%d %dのようにすると空白の判定だと勘違いしていました。 ポインタを作成して、アドレス値をずらすやり方で、入力を保存してると読んだのですが。配列を用意する場合と、ポインタの場合で何か処理速度などの違いがあったりするのでしょうか?
asm

2018/03/16 15:44

何も変わりません。 単純に &buf[i]と書くよりbuf + iの方が楽だっただけです。
MOTOMUR

2018/03/16 15:51

ありがとうございます。
guest

0

c言語であれば、strtok関数が使えると思います。
c++であれば、std::string::splitやstd::getlineが使えそうです。
「文字列 分割 空白」で検索しました。

投稿2018/03/16 14:31

kazto

総合スコア7196

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

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

MOTOMUR

2018/03/16 15:02

回答ありがとうございます。 入力の受け取り後に分けるというやり方ですね! 入力の受け取りの方法があまりたくさんいいのがなくて質問したのですが、 1000文字などの大きな数字のスペースの入力に対して受け取りをどうしたら良いかがわからないという質問でした! scanfのゴリ押しが文字数制限に引っかからずに済むと思ったので、その書き方を知りたかったです。もしくは別の文字数制限を気にしなくていいスペースを含む入力の得かたがあればお願いします。
guest

0

素直にstd::cinではいけませんか?

c++

1#include <iostream> 2#include <string> 3 4int main(void){ 5 std::ios_base::sync_with_stdio(false); 6 int n; 7 std::cin >> n; 8 9 std::string value; 10 for (auto i=0; i<n; i++) { 11 std::cin >> value; 12 std::cout << value << std::endl; 13 } 14 return 0; 15}

C言語の質問でしたか…

C++でもscanfの方がはやいからという理由で使われる方がいるようです。
std::ios_base::sync_with_stdio(false)
を入れることでstd::inを速くできます。

https://www.geeksforgeeks.org/fast-io-for-competitive-programming/
https://www.geeksforgeeks.org/cincout-vs-scanfprintf/

投稿2018/03/16 15:27

編集2018/03/16 15:47
mkgrei

総合スコア8560

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

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

MOTOMUR

2018/03/16 15:44

Cは学校で基礎の基礎をやっていたので読みやすいですが、C++の構文になった途端呪文に見えてしまいますね笑 勉強しないとコード自体読めそうもないですが、 std::が入力系統っぽいことはわかります。 std::cin >> nは入力値をnに代入していて、 forの中では受け取った文字列valueの中を空白までを処理して保存といった感じでしょうか? 予想があってるか間違っているはさておき、CやC++などの違いを理解することから始めようかと思います。 回答ありがとうございます!
guest

0

scanfなのに質問のタグがCではなくC#とC++、というのが解せないところではありますが。

競技プログラミングで変なデータが入ってないことが前提だったら、必要な回数分だけ

C

1/* int num; */ 2scanf("%d", &num);

を繰り返す手法でもいいんじゃないでしょうか。

投稿2018/03/16 15:23

okrt

総合スコア366

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

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

MOTOMUR

2018/03/16 15:32

回答ありがとうございます。 すいません。つい先ほど勉強始めたばかりでCやC+やC#やら区別もよくつかないまま質問してしまいました。修正しておきます。 改行、スペース共に差があると思って確認を怠っていました。 forで回しても、改行でなくてスペースの入力でもうまく動作するのですね。 確認すればよかったです。。
okrt

2018/03/16 15:47

C++でscanfを使うことも可能ですが、「C++らしいプログラム」ではないでしょうね。
MOTOMUR

2018/03/16 15:52

なるほど。 競技プログラミングではCではなくC++のみを採用してるところしかしらないのですが、 やはり、C++らしいプログラミングをかけた方が今後のプログラミングに役に立つのでしょうか??
okrt

2018/03/16 16:08

私は全然詳しくないですが、C言語では使えないけどC++では使える便利な機能が色々あります。 例えば文字列を扱う場合、C言語でcharの配列だのポインタだのを使うよりもC++でstd::stringを使うのが一般的には楽ですね。
guest

0

C言語の場合、入力にscanfを使うというのは筋が悪いです。
fgetsを使えば、1行の文字列が取得できますんで、その文字列を処理していろいろ出すのがいいと思います

投稿2018/03/16 14:36

y_waiwai

総合スコア87774

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

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

MOTOMUR

2018/03/16 14:55

回答ありがとうございます! fgets第二引数は一行の最大文字数とありますが、199文字までの制限があるのですね。 初めて存在を知って調べてみましたが、199文字制限だと競技プログラミングでは融通が効きません。 入力の数字数上限が今回躓いた問題では1000なので、これを満たした入力の受け取りとはならないのです。 他に入力をうまく受け取る方法ご存知でしたら教えてください。
y_waiwai

2018/03/16 15:04

その文字数制限ってどこに書いてありました?
y_waiwai

2018/03/16 15:05

fgetsには文字数制限なんかないはずですが。
MOTOMUR

2018/03/16 15:10

https://www.sejuku.net/blog/24615#fgetc ここに200文字って書いてありました。。。 と思ってちゃんと読み返すと256ビットでした。ビットでした。 2^255までの文字数を格納可能ってことですかね? 申し訳ないです、勘違いしておりました。
MOTOMUR

2018/03/16 15:12

それと第三引数について質問なのですが、競技プログラミング等の入力は標準入力として良いのでしょうか? 入力の違いについてあまり詳しくないのですが。
y_waiwai

2018/03/16 15:14

キーボード入力なら、第三引数は stdin としておけばいいです
MOTOMUR

2018/03/16 15:15

入力を文字列で得た際にスペース区切りはやはりstrtokが簡単でしょうか? 他に配列に入力を入れる際に簡単のありましたら、教えてください。
MOTOMUR

2018/03/16 15:15

ありがとうございます。
y_waiwai

2018/03/16 15:17

まあ、strtokを使っておけばいいでしょう。数値ばかりなら、strtoint で変換していくってテもありますが
MOTOMUR

2018/03/16 15:33

ありがとうございます。そのような使い方練習したいと思います。
otn

2018/03/16 17:09

> ここに200文字って書いてありました。。。 関数の仕様を調べるのに、公式リファレンスでなく、個人ブログの類いを見るというのも筋悪です。 > と思ってちゃんと読み返すと256ビットでした。ビットでした。 も間違いですが、そのページにはそもそもそんなこと書いてないので、濡れ衣ですね。URL記入ミスでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問