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

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

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

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

標準入力

標準入力(stdin)は、プログラムが標準的に用いるデータ入力元。リダイレクトしない限り、プログラムを起動した端末のキーボードが標準入力になります。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

標準出力

標準出力(stdout)は、プログラムが標準的に用いるデータ出力元。標準出力に書き込み要求を発行しすることにより、ディスプレイ装置にデータを表示することができます。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

Q&A

解決済

5回答

773閲覧

C言語:標準入力から読み取った文字列の間にだけ記号を入れたい

naco.

総合スコア5

C

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

標準入力

標準入力(stdin)は、プログラムが標準的に用いるデータ入力元。リダイレクトしない限り、プログラムを起動した端末のキーボードが標準入力になります。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

標準出力

標準出力(stdout)は、プログラムが標準的に用いるデータ出力元。標準出力に書き込み要求を発行しすることにより、ディスプレイ装置にデータを表示することができます。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

0グッド

0クリップ

投稿2020/04/14 10:40

前提・実現したいこと

C言語:標準入力から読み取った文字列の間にだけ記号を挿入したいです。

入力
3
Hello
World
Happy

出力
Hello_World_Happy

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

HelloWorldHappy

該当のソースコード

C

1#include <stdio.h> 2 3int main(void){ 4 char str[1000]; 5 char buf[20]; 6 int n; 7 8 fgets(str, sizeof(str), stdin); 9 sscanf(str, "%d", &n); 10 11 for (int i = 0; i < n; i++) { 12 fgets(str, sizeof(str), stdin); 13 sscanf(str, "%s", buf); 14 printf("%s", buf); 15 } 16 return 0; 17} 18

その他

色々検索してはみたのですが、該当するようなものが見つからず……。
初歩すぎるつまりだとは思うのですが、お答えいただけると大変助かります。
どうかよろしくお願いいたします。

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

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

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

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

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

jimbe

2020/04/14 11:31

間に '_' を挟むのは少ないかもしれませんが, ',' を挟むことは結構ありますので, その方向で探してみては如何でしょうか.
naco.

2020/04/14 11:47

なるほど! その記号を挟むことが多いのですね! 次行き詰まった時は、その方向で探してみようかと思います! ありがとうございます!
guest

回答5

0

こんなコードはいかがでしょうか?

C

1#include <stdio.h> // scanf, puts 2#include <string.h> // strlen 3 4#define STR_SIZE 1000 5#define BUF_SIZE 20 6#define fmt "%19s" 7 8int main(void) 9{ 10 char str[STR_SIZE]; 11 int n; 12 if (scanf("%d", &n) != 1) return 1; 13 for (int i = 0, j = 0; i < n; i++) { 14 if (j >= STR_SIZE - BUF_SIZE) return 2; 15 if (i > 0) str[j++] = '_'; 16 scanf(fmt, str + j); 17 j += strlen(str + j); 18 } 19 puts(str); 20}

追記
<string.h> など、ちょっと修正しました。

投稿2020/04/14 16:09

編集2020/04/14 16:23
kazuma-s

総合スコア8224

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

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

naco.

2020/04/14 17:15

回答ありがとうございます! なるほど、こういったコードもあるんですね! パッと見た感じで、すっきりした印象を受けました! #define は数値を変更しやすい、と教わったので、このコードだと書き換える際にわかりやすそうですね!
guest

0

ポインタを扱えれば, str 内で直接編集していくようにも出来ます.

c

1#include <stdio.h> 2#include <string.h> 3 4int main(void) { 5 char str[1000]; 6 int n; 7 8 fgets(str, sizeof(str), stdin); 9 sscanf(str, "%d", &n); 10 11 str[0] = '\0'; // str を空にする 12 for(int i=0; i<n; i++) { 13 if(i > 0) strcat(str, "_"); //2つめ以降の前に "_" を付ける 14 fgets(&str[strlen(str)], sizeof(str)-strlen(str), stdin); 15 str[strlen(str)-1] = '\0'; //改行を消す 16 } 17 18 printf(str); 19 return 0; 20}

すいません, 正確には上のコードは配列でした.
ポインタだと以下の感じですね.

c

1#include <stdio.h> 2 3int main(void) { 4 char str[1000]; 5 int n; 6 7 fgets(str, sizeof(str), stdin); 8 sscanf(str, "%d", &n); 9 10 char *p = str; 11 char *endp = str + sizeof(str); 12 *p = '\0'; // str を空にする 13 for(int i=0; i<n; i++) { 14 if(i > 0) *p++ = '_'; //2つめ以降の前に "_" を付ける 15 fgets(p, endp-p, stdin); 16 while(*p != '\n') p++; //改行まで移動 17 *p = '\0'; //改行を消す 18 } 19 20 printf(str); 21 return 0; 22}

投稿2020/04/14 12:11

編集2020/04/14 19:35
jimbe

総合スコア12543

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

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

naco.

2020/04/14 13:14

回答ありがとうございます! ポインタを使ったソースの書き方を教えていただいてありがとうございます! なるほど、ポインタですか……。 まだ、”学んだけどよくわかっていない”という地点なので、扱えるようになったらもっと便利になりそうですね!
naco.

2020/04/14 15:49

訂正ありがとうございます! なるほど、下のがポイントなんですね! そういえば、” * ”ついてるのがポインタでしたね……。 いい復習にもなりました! ありがとうございます!
guest

0

ベストアンサー

すみません。ソースコードが間違っていました。
こうすれば大丈夫です。

C

1#include <stdio.h> 2 3int main(void){ 4 char str[3];//3桁まで 5 char buf[1000/*10の3乗*/][20]; 6 char buf_[20];//一時的な保存 7 int n; 8 9 fgets(str, sizeof(str), stdin); 10 sscanf(str, "%d", &n); 11 12 for (int i = 0; i < n; i++) { 13 fgets(buf_, sizeof(buf_), stdin); 14 sscanf(buf_, "%s", buf[i]); 15 } 16 17 printf("%s",&buf[0]); 18 19 for(int i=1;i<n;++i){ 20 printf("_%s",&buf[i]); 21 } 22 return 0; 23}

投稿2020/04/14 11:18

Luke02561

総合スコア404

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

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

jimbe

2020/04/14 11:25

回答も編集出来ます.
Luke02561

2020/04/14 11:37

そうすれば良かったのか。ありがとうございます
naco.

2020/04/14 11:43

ソースコードの訂正ありがとうございます! おかげ様で解決することができました!
guest

0

少しむずかしくなりますが、配列を使ってみてはどうでしょうか。
以下のようなコードになります

C

1#include <stdio.h> 2 3int main(void){ 4 char str[3];//3桁まで 5 char buf[1000/*10の3乗*/][20]; 6 int n; 7 8 fgets(str, sizeof(str), stdin); 9 sscanf(str, "%d", &n); 10 11 for (int i = 0; i < n; i++) { 12 fgets(str, sizeof(str), stdin); 13 sscanf(str, "%s", buf[i]); 14 } 15 16 printf("%s",&buf[0]); 17 18 for(int i=1;i<n;++i){ 19 printf("_%s",&buf[i]); 20 } 21 return 0; 22}

投稿2020/04/14 10:47

Luke02561

総合スコア404

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

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

naco.

2020/04/14 11:12

回答ありがとうございます! 答えてくださったことを実行してみたのですが、出力したい結果のようにはならず……。 しかし、最初の文字列と、その次からの文字列を分けて考えるのだなという発想を得ることはできました! ありがとうございます! もしよろしければ、解決方法が見つかった際には、引き続き回答していただけると助かります……。
guest

0

まずループの中でアンダースコア(_)が出力される条件を考えましょう。nの数を見れば条件分岐でアンダースコアを出力すべきかどうか、判断できそうではありませんか?あとは実装してみましょう!

投稿2020/04/14 10:44

A_kirisaki

総合スコア2853

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

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

naco.

2020/04/14 11:17

回答ありがとうございます! すみません……。 せっかくヒントを頂いているのに、条件分岐といった言葉にもピンとすらきていません……。 もう一度最初から学びなおして、手掛かりがないか探してみようかと思います!
otn

2020/04/14 11:44

> 条件分岐 この場合、if文のことです。
naco.

2020/04/14 11:51

なるほど、if文のことでしたか! たしかに、 次に文字列がある場合 → "_"を挿入 次に文字列が無い場合 → 何もしない と分けることができますね! A_kirisakiさんが仰ってたのはこういうことだったんですね。 すっきりしました! ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問