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

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

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

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

Q&A

6回答

3290閲覧

C言語:空白区切りのn個の整数を改行区切りにする

satumaimo001007

総合スコア0

C

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

0グッド

0クリップ

投稿2021/08/19 11:37

前提・実現したいこと

C言語初心者のため、意味不明なことを言っていたら申し訳ありません。

整数nが与えられて、その後にn個の整数が半角空白区切りで与えられるので、それを与えられた順番に改行区切りで出力したいです。

例:
<入力>
3 23 52 7
<出力>
23
52
7

発生している問題・エラーメッセージ

出力が、1つ目に与えられた整数がn回出てしまいます。

該当のソースコード

C言語
ソースコード
#include <stdio.h>
#include <string.h>

int main(void){
char buf[100];
fgets(buf, sizeof(buf), stdin);
int n;
sscanf(buf, "%d", &n);

char str[10]; fgets(buf, sizeof(buf), stdin); char *tp; for(int i=0; i<n; i++){ sscanf(buf, "%s ", str); tp=strtok(str, " "); printf("%s\n", tp); }

}

試したこと

やろうとしていることとしては、fgetsで入力を読み込んで、まずnの値を設定し、そこからstrtok関数で空白区切りできるかと思ったのでn回繰り返そうとしました。
よくわかっていない点としては、fgetsがどこまで読み込んでいるのか(改行まで?)、sscanfとstrtok関数の使い方についてです。どれが空白まで、改行まで読み込むのか、繰り返し動作を行う必要があるのかなどです。

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

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

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

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

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

BeatStar

2021/08/19 11:55

一つ、失礼を承知で書きます。 この質問のやつって、Paizaスキルチェックのやつじゃないですよね? もしそうなら**規約違反**です。 そうじゃないならスルーして結構です。 (マジで多いので)
BeatStar

2021/08/19 11:56

それと、コードは"<code>"または"<コード>"のボタンを押して出てくるやつの中に書きましょう。 今のままだと読みづらいです。
jimbe

2021/08/19 12:01

> fgetsがどこまで読み込んでいるのか ドキュメントに書いてあると思います。 > sscanfとstrtok関数の使い方について・・・ ドキュメントなりネットの情報なりからどのようにお調べになりましたでしょうか。
guest

回答6

0

たんに、空白文字を改行文字に置き換えればどうでしょう

C

1for(int i=0; buf[i]; i++){ 2 if(buf[i]==' ') buf[i]='\n'; 3} 4puts(buf);

投稿2021/08/19 11:46

y_waiwai

総合スコア87774

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

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

0

C

1#include <stdio.h> 2 3int main() 4{ 5 int c; 6 while((c=getchar())>=0 && c!=' '); 7 do{ 8 while((c=getchar())>=0 && c!=' ') putchar(c); 9 putchar('\n'); 10 }while(c >= 0); 11}

火も包丁も使わない料理法…じゃなくて、scanfもstrtokも使わない処理法。誤った入力への対応は規定されていないので、これでもokのはずです。

投稿2021/08/19 15:27

majiponi

総合スコア1720

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

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

0

同じ内容のbufに対して、sscanf(buf, "%s ", str);を何度実行しても同じbufの先頭から%sを探すので、何度実行しても同じ結果です。
既に読んだ部分を飛ばして、その次から読まないといけない。どこまで読んだかを調べるには%nを使います。

そもそも、この目的なら、sscanfstrtokを併用するのは間違っています。
strtokの使い方も間違ってます。

C

1int main(void){ 2 char buf[100]; 3 fgets(buf, sizeof(buf), stdin); 4 5 int n, pos; 6 sscanf(buf, "%d%n", &n, &pos); 7 8 char *bufp, *bufq; 9 bufp = bufq = buf+pos; 10 11 /* 案1:sscanf を使って分解する方法 */ 12 char str[10]; 13 while(sscanf(bufp, "%s %n", str, &pos)==1){ 14 printf("%s\n", str); 15 bufp += pos; 16 } 17 18 /* 案2:strtok を使って分解する方法 */ 19 char *tp; 20 tp = strtok(bufq, " \n"); 21 while(tp){ 22 printf("%s\n", tp); 23 tp = strtok(NULL, " \n"); 24 } 25}

投稿2021/08/19 12:30

編集2021/08/19 12:31
otn

総合スコア84538

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

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

otn

2021/08/19 12:43

切り出して何か処理するのじゃなくて、表示だけ出来れば良いのであれば、 sscanf(buf, "%d%n", &n, &pos); の後で、 for(bufp=buf+pos; *bufp; ++bufp) putchar(*bufp==' ' ? '\n' : *bufp); で。
guest

0

読み込むのは数値だけですから、scanf が簡単です。

C

1#include <stdio.h> // scanf, printf 2 3int main(void) 4{ 5 int n, x; 6 scanf("%d", &n); 7 for (int i = 0; i < n; i++) { 8 scanf("%d", &x); 9 printf("%d\n", x); 10 } 11}

入力エラーのチェックがあったほうがよいとすれば、

C

1#include <stdio.h> // scanf, printf 2 3int main(void) 4{ 5 int n, x; 6 if (scanf("%d", &n) != 1) return 1; 7 while (--n >= 0) { 8 if (scanf("%d", &x) != 1) return 1; 9 printf("%d\n", x); 10 } 11}

投稿2021/08/19 12:28

kazuma-s

総合スコア8224

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

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

0

strtok は内部に状態を持つ関数です。
使い方は、最初のトークンを所得する場合のみ対象の文字列を渡し、2つ目以降のトークンを取得する場合は NULL を渡します。
ですので、文字列を渡している限り、何度 strtok を呼んでも最初のトークンしか得られません。

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5int main(void) { 6 int n; 7 char buf[100]; 8 9 fgets(buf, sizeof(buf), stdin); 10 n = atoi(strtok(buf, " ")); //最初 11 12 for(int i=0; i<n; i++) { 13 printf("%s\n", strtok(NULL, " ")); //2つ目以降 14 } 15}

投稿2021/08/19 12:14

jimbe

総合スコア12646

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

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

0

まず、
fgets(buf, sizeof(buf), stdin);
fgets()は、行単位の入力です。従って、

Text

1<入力> 23 23 52 7

最初の 323 52 7 を別の行で入力すべきでは?

tp=strtok(str, " "); strtok()の動作はどうなっているでしょうか?
一回目の呼び出しでは、入力文字列を指定しますが、次から、strtok(NULL, " ")ではないでょうか?
とすると、

C

1 tp=strtok(buf, " "); 2 for(int i=0; i<n; i++){ 3 //sscanf(buf, "%s ", str); 4 //tp=strtok(str, " "); 5 printf("%s\n", tp); 6 tp=strtok(NULL, " "); 7 }

辺りか。

投稿2021/08/19 11:56

pepperleaf

総合スコア6383

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問