『scanfを使わずに_getch()でキーボードからファイル名を入力していき、入力した文字をprintfで表示する流れについて質問です。
表示された文字をバックスペースで消していっても打ち込んだ文字は消えないですよね?
間違ったファイル名を入力してしまった際に文字が残っているので、正しく入力し直しても間違ったファイル名となってします。
一度打った文字を消す方法はありますでしょうか?
』
以前このような質問をさせていただき、_getch()で得た文字のキーボード上での削除の仕方は分かりました。
今度はそのやり方をプログラムで作るとしたら、どう組んでいけば良いのか教えて頂けないでしょうか。
できればそのプログラムを教えて頂けたら嬉しいです。
今現在書いてるプログラムのgetchを使っている部分です。
ファイルがオープンできたら別の処理に移行しますが、その関数は長くなるので省略しています。
#include <stdio.h>
#include <conio.h>
int main() {
int key;
int i;
char file_name[256] = { 0 };
FILE *fp;
errno_t e;
while(1)
{
i = 0;
// エンタキーが押されるまで入力を続ける
do
{
printf("%c", key);
file_name[i] = key;
key = _getch();
i++;
} while(key != 0x0d);
printf("\n");
if(e = fopen_s(&fp, file_name, "rb") != 0) {
printf("ファイルが存在しません\n");
return 0;
}
else {
// 成功したらプログラムの処理をする関数に移行
return 1;
}
}
}
No.3
- 回答日時:
getch() で 取得したキーコードがBSだったら、iを減算すれば良いかと思います。
(そうなると、DELキーだったら、とか、そもそもファイル名に使えないコードだったら、なども心配になりますが、それは、いずれにしてもkey の値で、case文などを使うと良いかと思います。)
◆元のプログラムの部分:
printf("%c", key);
file_name[i] = key;
key = _getch();
i++;
◆改造案 (案なので、概念的に記述してあります。
key = _getch(); ← do whileの最初に持って来ないとまずいと思います。
switch( key ) {
case : ファイル名に使えるコード
printf("%c", key);
file_name[i++] = key;
break;
case : バックスペースキー
if ( i > 0 ) i--; iは0以上でないといけません。
break;
default: それ以外はなにもしない。
break;
}
こんな考え方でいかがでしょうか?
ご参考に。
こちらの考え方を参考にプログラムを組んでみたところ、こちらの方法でもちゃんと文字を消せるようにできました。
case文の"ファイル名に使えるコード"の定数部分をどうしようか若干悩みましたが、なんとか組み込めました。
ずっとif文で分岐させることしか考えてなかったんですが、switch文で組んでみると中々スッキリした記述になりますね。
ご回答ありがとうございました。
No.2
- 回答日時:
の続きですかね。
閉じずに向こうで続けるべきでしたけど。
>_getch()で得た文字のキーボード上での削除の仕方
が、何を意味しているのか不明…ですが……
画面の表示ですか????
>do
>{
> printf("%c", key);
> file_name[i] = key;
> key = _getch();
> i++;
>} while(key != 0x0d);
file_nameの1文字目が不定な文字が入るのは許容という仕様でいいのでしょうか?
最初に
> file_name[i] = key;
が実行される時のkeyには何が入っていますかね?
いきなりEnter押された場合にも問題になりそうですが……
バックスペースが入力されたら
file_name[i--] = '\0';
で1文字戻すのと消去を行えばよいでしょう。
ただし、iが0の時に上記の処理を行うと高確率で吹っ飛ぶのでその辺りのエラー処理は必要ですが。
# 入力位置は移動できないのですからDeleteキーの対応は不要…ですよね?
すみません、最初はあの方法で消せるならいいと思っていたんですが、やはりバックスペースを一回押すだけで消せるようにした方がスマートだなと思いまして。
>が、何を意味しているのか不明…ですが……
>画面の表示ですか????
これは、"BS,スペース,BS"で消せるのは分かりましたが、バックスペースを一回押すだけで消せるプログラムを作りたいという意味で書きました。
言葉が足りず申し訳ありませんでした。
>file_nameの1文字目が不定な文字が入るのは許容という仕様でいいのでしょうか?
投稿時に記述したプログラムは、元のプログラムから必要最低限の部分だけを抜粋して書き直していたので、最初にgetch()を使っているプログラム部分は含んでいませんでした。
なので別の部分に一文字目を入力する処理はあります。
>file_name[i--] = '\0';
この'\0'を入れてi--するという文法を思いつかなかったので大変参考になります。
># 入力位置は移動できないのですからDeleteキーの対応は不要…ですよね?
はい、今回はバックスペースだけ使えればいいのでDeleteキーは不要です。
ご回答ありがとうございました。
No.1ベストアンサー
- 回答日時:
#include <stdio.h>
#include <conio.h>
int main() {
int key;
int i;
char file_name[256] = { 0 };
FILE *fp;
errno_t e;
while(1)
{
i = 0;
// エンタキーが押されるまで入力を続ける
do
{
key = _getch();
if (key == '\b') { //このif文と次の行のif文を1行にまとめて
if (i) { //if ((key == '\b') && (i)) {にするとバグるので注意
printf("\b \b");
i--;
}
} else if (key != '\r') {
printf("%c", key);
file_name[i] = key;
i++;
}
file_name[i] = '\0';
} while(key != '\r');
printf("\n");
if(e = fopen_s(&fp, file_name, "rb") != 0) {
printf("ファイルが存在しません\n");
return 0;
}
else {
// 成功したらプログラムの処理をする関数に移行
return 1;
}
}
}
記述してくださったプログラムを自分のソースに組み込んでみたところ、文字が消せるようになっていました!
>//このif文と次の行のif文を1行にまとめて
>//if ((key == '\b') && (i)) {にするとバグるので注意
ここをまとめてみて実行してみましたが、最初の入力時に打ち間違えた時確かにバグが発生しますね。
多分、自分で組んでいたら分割した方がいいとすぐには思いつかなかったと思います。
本当にご回答ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Enterキーを押されたら次の処理...
-
#defineが使用するメモリ領域に...
-
C言語のプログラムで、途中で止...
-
char型2つを結合し、short型に...
-
エラーについて質問です。
-
static付き宣言の初期化
-
printf による16進表示について
-
Cでファイルの行数をカウントす...
-
c言語で文書を読み込み、単語の...
-
C言語でのCSVファイルの読み出...
-
HANDLEのエラー
-
reallocでエラー
-
構造体メンバの初期化
-
C言語についてです。
-
矢印キーを押下してコンソール...
-
リストの作成と出力(C言語)
-
c言語のプログラミングでキーボ...
-
空白を含んだ文字列がうまく格...
-
C言語で複数列のデータを1列の...
-
2÷3などの余りについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Enterキーを押されたら次の処理...
-
C言語で複数列のデータを1列の...
-
#defineが使用するメモリ領域に...
-
printf による16進表示について
-
空白を含んだ文字列がうまく格...
-
C言語のプログラムで、途中で止...
-
プログラミングの授業の課題です
-
char型2つを結合し、short型に...
-
C言語でのCSVファイルの読み出...
-
矢印キーを押下してコンソール...
-
【C言語】全角文字の配列を、全...
-
エラーについて質問です。
-
リストの作成と出力(C言語)
-
バイナリファイル(画像)のよみ...
-
[C]セグメンテーションエラー:...
-
WinInetのInternetOpenUrl関数...
-
VC++でSQLへSELECT文を送ったの...
-
受信データから必要な部分のみ...
-
c言語で文書を読み込み、単語の...
-
reallocでエラー
おすすめ情報