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

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

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

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

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

8回答

5562閲覧

入力した文字列を1文字ずつ後ろから消して表示したい

bambino

総合スコア0

C

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

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2021/06/29 12:06

編集2021/06/29 13:52

前提・実現したいこと

キーボードから文字列を入力し、入力された文字列を後ろから1文字ずつ消して表示したいです。
表示例)
入力文字:ABCDE
実現したい表示内容↓
1行目 ABCDE
2行目 ABCD
3行目 ABC
4行目 AB
5行目 A

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

コンパイルはできていますが、実行すると以下の内容で表示されてしまいます。 abcdeaaaaaaaaaaaaaaaaaaaaa

該当のソースコード

C

1#include <stdio.h> 2void del(char x[]); 3 4int main(void){ 5 6 char a[20] = {0}; 7 8 printf("文字を入力->"); 9 fgets(a, 20, stdin); 10 11 del(a); 12} 13 14void del(char x[]){ 15 16 int i, j; 17 printf("%s", x); 18 19 for(i=0; i<=20; i++){ 20 for(j=0; j<=20-i; i++){ 21 printf("%c", x[j]); 22 } 23 puts(""); 24 } 25}

試したこと

for(j=0; j<=20-i; i++)→for(j=0; j<=5-i; i++)
上記のとおりfor文を変更しましたが表示内容がabcdeaaaaaaになっただけで、変化は見られませんでした。

for(j=0; j<=x[20]-i; i++)→for(j=0; j<=19-i; j++)
文末がi++となっていたのでj++に修正しました。
abcdeが15行文余計に表示された後、下記のようになり希望の表示内容になりませんでした。
abcde
abcd
abc
ab

補足情報(FW/ツールのバージョンなど)

パイザを使っています。

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

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

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

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

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

guest

回答8

0

C

1int main(void) 2{ 3 int n=0; 4 char a[20] = { 0 }; 5 printf( "input str : " ); 6 fgets( a, 20, stdin ); 7 8 for( n=0; (a[n]!='\n' && a[n]!='\0'); ++n ){} //まともな文字の個数nを数える 9 for( ; n>0; --n ){ printf( "%.*s\n", n, a ); } //nを減らしながら表示する 10 11 return 0; 12}

投稿2021/06/30 09:02

fana

総合スコア11996

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

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

fana

2021/06/30 09:09

( "%.*s" とかいう知らない書式指定方法を見つけたので使ってみた的な)
bambino

2021/06/30 13:38

丁寧にソースコードを記入いただきありがとうございます。 私も(%.*s)というのは初めて見ました。 改めて調べてみたいと思います。
guest

0

fgets(x, 20, stdin); のところで、ABCDE Enter と入力すると、
x = { 'A', 'B', 'C', 'D, 'E', '\n', '\0', ... } となります。
配列の添え字と値の関係はこうです。

|[0]|[1]|[2]|[3]|[4]|[5]|[6]|
|:--|:--:|--:|
|'A'|'B'|'C'|'D'|'E'|'\n'|'\0'|

次に、これを表示するために、添え字(インデックス)を書き出してみます。
右側は表示される文字列です。

[0] [1] [2] [3] [4] => ABCDE
[0] [1] [2] [3] => ABCD
[0] [1] [2] => ABC
[0] [1] => AB
[0] => A

つまり
1回目は[0]から[4]まで表示
2回目は[0]から[3]まで表示
3回目は[0]から[2]まで表示
4回目は[0]から[1]まで表示
5回目は[0]から[0]まで表示

おそらくループを学んで日が浅いのでしょう。「二重のforループでできそうだ」という見通しは間違いではありませんが、私に言わせればあてずっぽうで書いているように見えます。

  • 外側のループが何をするもので、いくつからいくつまで変化させればよいか
  • 内側のループが何をするもので、いくつからいくつまで変化させればよいか

プログラムにさせることを一度、上のように書き出してみて、考えを整理して、それからプログラムに書き変えてみてください。

投稿2021/06/29 23:34

編集2021/06/29 23:49
rubato6809

総合スコア1382

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

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

bambino

2021/06/30 01:13

丁寧に解説いただきありがとうございます。 改めて書きかえてみます。
guest

0

fgets(x, 20, stdin); のところで、ABCDE Enter と入力すると、
x = { 'A', 'B', 'C', 'D, 'E', '\n', '\0', ... } となります。

x の先頭から順に見ていき '\n' を見つけます。x[5] ですね。
そこに '\0' を入れて '\n' を削除して、x を表示すると ABCDE と出ます。

次に x[4] に '\0' を入れて 'E' を削除して、x を表示すると ABCD と出ます。
次に x[3] に '\0' を入れて 'D' を削除して、x を表示すると ABC と出ます。

このようにして、x[i] の i が 0 になったら終了です。

追記
質問に、「1文字ずつ後ろから消して」とあるので x[i] に '\0' を入れましたが、
そうではなく、「x[0]~x[i-1] を1文字ずつ表示する」でも構いません。

投稿2021/06/29 18:14

編集2021/06/30 02:23
kazuma-s

総合スコア8224

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

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

bambino

2021/06/30 01:15

fgetsでの文字入力について、解説いただきありがとうございます。 解説の内容を考慮して、改めて考えてみます。
guest

0

for(j=0; j<=20-i; i++){

よく見ましょう。 最後が、i++ です。
配列サイズのサイズが i<=20 --> i<20 とかもありますが、、、。

また、上記の修正だけでは、多分、期待する結果に足りないと思いますが、直してから、考えましょう。

投稿2021/06/29 12:16

pepperleaf

総合スコア6385

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

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

bambino

2021/06/29 13:42

的確なご指摘ありがとうございます。 修正したところ、表示内容が少し理想に近づきました。 また、お時間があるときにアドバイスいただけますと助かります。
guest

0

char a[20]

として定義したら、とり得るインデックスは、
a[0]からa[19]までです。
a[20]ではアクセス違反となります

でもひとつ、C言語における文字列、というのは、後端に'\0'が入っている文字配列です。
なので、20バイトの配列に入れることのできる文字列は19文字分まで、となります


C

1#include <stdio.h> 2#include <string.h> 3 4void heruprint(char*s) 5{ 6 for(int i=strlen(s)-1;i>=0;i--){ 7 puts(s); 8 s[i]='\0'; 9 } 10 } 11 12 13int main(void){ 14 char s[]="123456789"; 15 heruprint(s); 16 17} 18

投稿2021/06/29 12:09

編集2021/07/02 22:32
y_waiwai

総合スコア88042

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

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

bambino

2021/06/29 13:40

分かりやすく回答いただきありがとうございます。 ご指摘いただいた内容に修正しましたが、表示内容に変化はありませんでした。 お時間があるときに改めてアドバイスいただけますと幸いです。
guest

0

c

1#include <stdio.h> 2 3void del(char x[], int size); 4int len_a(char x[], int size); 5int main(void) { 6 char a[20] = {'\0'}; 7 8 printf("文字を入力->"); 9 fgets(a, sizeof(a), stdin); 10 del(a, sizeof(a)); 11} 12 13int len_array(char s[], int size) { 14 for (int i = 0; i < size; i++) { 15 if ((s[i] == '\0') || (s[i] == '\n') || (s[i] == '\r')) { 16 return i; 17 } 18 } 19 return size - 1 ; 20} 21 22void del(char s[], int size) { 23 for (int i = len_array(s, size); i > 0; i--) { 24 for (int j = 0; j < i; j++) { 25 printf("%c", s[j]); 26 } 27 printf("\n"); 28 } 29}

実行例
イメージ説明

投稿2021/07/02 22:10

katoy

総合スコア22324

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

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

0

自己解決

アドバイスいただいた内容を一緒に勉強している仲間と見て、完成させることができました。
アドバイスいただいた方々にお礼申し上げます。
一応、下記に完成させたソースコードを載せておきます、皆様からしたら少し回りくどい方法かもしれませんが興味がありましたらご覧ください。

C

1#include <stdio.h> 2 3void kesu(char s[], int a); 4 5int main(void){ 6 7 char moji[100]; 8 int i; 9 10 printf("文字を入力してください:\n"); 11 scanf("%s", &moji[0]); 12 13   for(i=0; moji[i]!='\0'; i++); 14 15 kesu(moji, i); 16} 17 18void kesu(char s[], int a){ 19 20 int b, f; 21 22 for(b=a; b>0; b--){ 23 for(f=0; f<=b-1; f++){ 24 printf("%c", s[f]); 25 } 26 printf("\n"); 27 } 28}

投稿2021/06/30 13:49

bambino

総合スコア0

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

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

0

(特にビギナのうちは)一つの関数でなんもかんもやろうと思わないのが肝心かも。

C

1#include <stdio.h> 2 3// [1] 文字列 x の長さを返す 4int length(char x[]) { 5 int i; 6 for ( i = 0; x[i] != '\0'; ++i ); 7 return i; 8} 9 10// [2] 文字列 x を n 文字分書いて改行 11void print_n(char x[], int n) { 12 for ( int i = 0; i < n; ++i ) { 13 printf("%c", x[i]); 14 } 15 puts(""); 16} 17 18// [1]と[2]を作っておけばあとは楽勝 19void del(char x[]) { 20 for ( int len = length(x); len > 0; --len ) { 21 print_n(x, len); 22 } 23} 24 25int main(void){ 26 char str[] = "abracadabra"; 27 del(str); 28 return 0; 29}

投稿2021/06/30 02:41

episteme

総合スコア16612

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問