BackSpace処理について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
( ゚д゚ )

BackSpace処理について

#1

投稿記事 by ( ゚д゚ ) » 14年前

お世話になっています。

今回はBackSpaceの処理を実装しようと思いコーディングをしている最中です。
文字を入力(とりあえず半角文字だけ)して、コンソール画面の一番端まで来たら次の行に改行します。
文字を消去しても前の行にもどりません。
なにかいい方法はありませんか><

文字入力は_getch();でやっています。

コード:


        input = _getch();
        // 入力文字数
         inplen += 1;

	// int型をchar型に変換
	sprintf( &p_name[*p_elem], "%c", input );

	// 次の要素へ
	elem+=1;

コード:

void BackSpace()
{
	// BackSpaceを押したら
	if( input == BACKSPACE ){

		// 要素を1つ戻す
		elem-=1;

		// 入力文字数を1文字減らす
		inplen-=1;

		// 0より小さければ0を入れる
		if( elem < 0 ){
			elem = 0;
		}

		// 現在の文字を\0に置き換える
		p_name[elem] = '\0';

		// 空白を表示し表示中の文字を消す
		//printf( " " );

		// カーソルを1つ戻す
		//printf( "\b" );
	}
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: BackSpace処理について

#2

投稿記事 by softya(ソフト屋) » 14年前

WindowsAPIのコンソール系APIを使わないと無理だと思います。
「Console Functions」
http://msdn.microsoft.com/en-us/library ... s.85).aspx

あっ、こっちが日本語版です。
「SetConsoleCursorPosition 関数」
http://msdn.microsoft.com/ja-jp/library/cc429740
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

( ゚д゚ )

Re: BackSpace処理について

#3

投稿記事 by ( ゚д゚ ) » 14年前

返信ありがとうございます。

カーソルの位置を好きな位置に変えれるようになりました。
現在のカーソル位置を取得する関数などはないのでしょうか。
検索をしてもそれっぽいのがでてきません。
お願いします。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: BackSpace処理について

#4

投稿記事 by softya(ソフト屋) » 14年前

( ゚д゚ ) さんが書きました:返信ありがとうございます。

カーソルの位置を好きな位置に変えれるようになりました。
現在のカーソル位置を取得する関数などはないのでしょうか。
検索をしてもそれっぽいのがでてきません。
お願いします。
これで取得できるはずです。
「GetConsoleScreenBufferInfo 関数」
http://msdn.microsoft.com/ja-jp/library/cc429297
「CONSOLE_SCREEN_BUFFER_INFO structure (Windows)」
http://preview.library.microsoft.com/en ... s.85).aspx
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

( ゚д゚ )

Re: BackSpace処理について

#5

投稿記事 by ( ゚д゚ ) » 14年前

おお、うまく動きました。
どうもありがとうございました。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: BackSpace処理について

#6

投稿記事 by softya(ソフト屋) » 14年前

( ゚д゚ ) さんが書きました:おお、うまく動きました。
どうもありがとうございました。
フォーラムルールですので、コードをぜひ掲載して下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

( ゚д゚ )

Re: BackSpace処理について

#7

投稿記事 by ( ゚д゚ ) » 14年前

失礼しました。
バグがまだ結構あると思います。

コード:

HANDLE hStdout;

const int BACKSPACE        = 8;	// BACKSPACE
const int LINEEND	        = 79;	// 行の最後

const int ASCLLBEGIN		= 0x20;
const int ASCLLEND			= 0x7E;
const int HALFKANABEGIN		= 0xA1;
const int HALFKANAEND		= 0xDF;
const int KANJIFIRSTBEGIN	= 0x81;
const int KANJIFIRSTEND		= 0x9F;
const int KANJIFIRSTBEGIN2	= 0xE0;
const int KANJIFIRSTEND2	= 0xFC;

int flag = 0;
int cnt = 0;

int codesize[512] = {0};

int CheckHalfSize( int *data )
{
	if(( ASCLLBEGIN <= *data ) && ( *data <= ASCLLEND ) || (( HALFKANABEGIN <= *data ) && ( *data <= HALFKANAEND ))){
		return 1;
	}
	return 0;
}

int CheckFullWidth( int *data )
{
	if(( KANJIFIRSTBEGIN <= *data ) && ( *data <= KANJIFIRSTEND ) || (( KANJIFIRSTBEGIN2 <= *data ) && ( *data <= KANJIFIRSTEND2 ))){
		return 1;
	}
	return 0;
}

void CheckInputCode( int input )
{
	if( flag == 0 ){
		// 全角文字なら(次は2バイト目がくるので文字数をカウントしなくていいので飛ばす)
		if( CheckFullWidth( &input ) ){
			// コードサイズを保存
			codesize[cnt] = 2;
			// 文字数
			cnt++;
			// 次の処理を飛ばす
			flag = 1;
			// 抜ける
			return;
		// 半角文字なら
		}else if( CheckHalfSize( &input ) ){
			codesize[cnt] = 1;
			// 文字数
			cnt++;
		}
	}else{
		flag = 0;
	}
}

void DrawDleat( int x, int y )
{
	COORD coord;

	cnt--;
	if( cnt < 0 ){
		cnt = 0;
	}
	coord.X = x;
	coord.Y = y;
	SetConsoleCursorPosition( hStdout, coord );
	printf( " " );
	SetConsoleCursorPosition( hStdout, coord );
}

int main(void)
{
	int input;

	BOOL bRet;
	COORD coord;
	CONSOLE_SCREEN_BUFFER_INFO info;

	// スクリーンのハンドルの取得
	hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

	while( 1 ){

		// 文字の取得
		input = _getch();

		// 文字数を調べる
		CheckInputCode( input );

		// BACKSPACEでなければ表示
		if( input != BACKSPACE ){
			printf( "%c", input );
		}

		// 現在のカーソルの位置の取得
		GetConsoleScreenBufferInfo( hStdout,&info );

		// BACKSPACEが押されたら
		if( input == BACKSPACE ){

			// 2バイト文字なら
			if( codesize[cnt-1] == 2 ){
	
				// 行の先頭なら
				if( info.dwCursorPosition.Y > 0 && info.dwCursorPosition.X == 2  ){
					
					// 表示している文字を消す
					DrawDleat( info.dwCursorPosition.X-2, info.dwCursorPosition.Y );

					// 一行戻す
					coord.X = LINEEND;
					coord.Y = info.dwCursorPosition.Y-1;
					SetConsoleCursorPosition(hStdout,coord);

				// それ以外は通常消去
				}else{

					// 表示している文字を消す
					DrawDleat( info.dwCursorPosition.X-2, info.dwCursorPosition.Y );
				}

			// 1バイト文字なら
			}else if(codesize[cnt-1] == 1){

				// 行の先頭なら
				if( info.dwCursorPosition.Y > 0 && info.dwCursorPosition.X == 0  ){
					
					// 表示している文字を消す
					DrawDleat( LINEEND, info.dwCursorPosition.Y-1 );

				// それ以外は通常消去
				}else{

					// 表示している文字を消す
					DrawDleat( info.dwCursorPosition.X-1, info.dwCursorPosition.Y );
				}
			}
		}
	}

	return 0;
}

閉鎖

“C言語何でも質問掲示板” へ戻る