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

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

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

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

標準入力

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

Q&A

解決済

4回答

3125閲覧

指定された部分だけ大文字に、あとはそのまま表示

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

標準入力

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

0グッド

0クリップ

投稿2020/08/29 15:21

C言語の練習問題を解いています。
問題は1行目に数値n,mがスペース区切りで、そしてその下に文章が与えられます。n番目の文字からm番目の文字までを全て大文字にして、それ以外の部分はスペースや大文字・小文字を変えずにそのまま出力するというものです。スペースも一文字とします。

入力例は
2 6
this is a pen

この時の出力例は
tHIS Is a pen です。

私は次のように記述しました。

#include <stdio.h> int main(void){ char buf[1000]; char str; int n, m; int i; fgets(buf, sizeof(buf), stdin); sscanf(buf, "%d %d", &n, &m); for(i = 0; i < n - 1; i++) { fgets(buf, sizeof(buf), stdin);  printf("%c", buf[i]); } for(i = n - 1; i < m; i++) { fgets(buf, sizeof(buf), stdin); str = buf[i]; if(str >= 97 && str <= 122) { str = str - 32; printf("%c", str); } } for(i = m; buf[i] != '\0'; i++) { fgets(buf, sizeof(buf), stdin); // str = buf[i]; printf("%c", buf[i]); } return 0; }

これですと大文字にする範囲がスペースを跨ぐ時に、スペースを無視して詰めて大文字にしてしまっているようなのです。
スペースを無視している分大文字にする文字数にズレが生じること、そもそもスペースが消えてしまうことはどのように修正したら良いのでしょう。
ご教示頂けますでしょうか。

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

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

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

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

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

dodox86

2020/08/29 16:02

> どのように修正したら良いのでしょう。 質問者さんのコードをもとにした具体的な修正コードが知りたいのでしょうか。それとも「練習問題を解いている」ということで、考え方や、今のコードのどういった点が問題なのかを知りたいのでしょうか。
amiya

2020/08/29 16:35

このコードだと、スペースがどうのいぜんに、まともに動かないような気がするのですが… 本当に問題点は「スペースがおかしい」でよいのでしょうか?
guest

回答4

0

<ctype.h> の toupper を使えば簡単です。

C

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

投稿2020/08/31 03:44

kazuma-s

総合スコア8224

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

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

0

ベストアンサー

スペースを無視している分大文字にする文字数にズレが生じること、そもそもスペースが消えてしまうことはどのように修正したら良いのでしょう。

char str[100];で空白を含む1行丸ごと取得します。
str[]の中身 ※最後に改行とNULLが入っているので計14文字です。
イメージ説明

あとはfor()ループでstr[0]→str[12]まで判定と加工処理をすればOKです。
判定条件はiがn~m文字目 and 対象が小文字の場合です。


普段C++しか使っていないので不慣れですがご参考までに。
参考:
C言語での一行入力の方法
C言語 標準入力からの掛け算
C言語 文字列のための標準ライブラリ関数

補足追記

fgets関数の注意点として、入力の終わりを示すNULL文字が入力の末尾に追加されていますが、そのひとつ前には改行文字が入っています。

文字列数を取得する為に、#include <string.h> strlen()を使用しています。

C

1#define _CRT_SECURE_NO_WARNINGS 2#include <stdio.h> 3#include <string.h> 4 5int main(void) { 6 char buf[100]; 7 char str[100]; 8 int n, m; 9 size_t str_length; 10 11 fgets(buf, sizeof(buf), stdin); 12 sscanf(buf, "%d %d", &n, &m); 13 14 fgets(str, sizeof(str), stdin); 15 16 str_length = strlen(str) - 1; 17 18 for (int i = 0; i < str_length; i++) { 19 if (i >= n - 1 && i < m && str[i] >= 97 && str[i] <= 122) { 20 printf("%c", str[i] - 32); 21 } else { 22 printf("%c", str[i]); 23 } 24 } 25 26 getchar(); 27 return 0; 28} 29

input

12 6 2this is a pen

output

1tHIS Is a pen 2

投稿2020/08/30 00:45

編集2020/08/30 01:23
mjk

総合スコア303

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

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

退会済みユーザー

退会済みユーザー

2020/08/31 03:24

ありがとうございます!お陰様で記述できました! #include <stdio.h> int main(void){ char buf[1000]; char str; int n, m; int i; fgets(buf, sizeof(buf), stdin); sscanf(buf, "%d %d", &n, &m); for(i = 0; i < n - 1; i++) { fgets(buf, sizeof(buf), stdin);  printf("%c", buf[i]); } for(i = n - 1; i < m; i++) { fgets(buf, sizeof(buf), stdin); str = buf[i]; if(str >= 97 && str <= 122) { str = str - 32; printf("%c", str); } else { printf("%c", str); } } for(i = m; buf[i] != '\0'; i++) { fgets(buf, sizeof(buf), stdin); printf("%c", buf[i]); } return 0; }
guest

0

for文の中の fgets(...) をすべて削除し、
最初の for文の前に 1つだけ fget(...) を追加してみてください。

fgets は行入力ですから、1回実行すると、
buf には "this is a pen\n" という文字列が入ります。
あとはその buf の中を見て処理していくだけです。

2つ目の for文で、小文字の場合だけしか printf していないので、
スペースは表示されません。

投稿2020/08/29 23:14

編集2020/08/29 23:25
kazuma-s

総合スコア8224

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

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

0

なんで1文字づつ表示してるのかわかりませんが、それをやめて、
最後に文字列を一括して表示させましょう

投稿2020/08/29 21:44

y_waiwai

総合スコア88042

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問