2017-06-11 7 views
1

Linuxのカーソルの前に端末の文字を削除するにはどうすればよいですか?過去に私は次のようなものを使用しました:C言語のLinux端末から文字を削除する方法

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

#define KEY_BACKSPACE 127 

int main(){ 
    printf("%s", "abc"); // add something so we can see if delete works 
    char * buf = malloc(3*sizeof(char)); 
    *(buf+0)=KEY_BACKSPACE; 
    *(buf+1)=' '; 
    *(buf+2)=KEY_BACKSPACE; 
    write(1,buf,3); 
    free(buf); 
} 

これはこのテクニックを実証する小さな例です。元のプログラムでは、標準モードを無効にして、すべてのキーストロークを自分で処理しました。だから私は文字を削除する必要があった。

元のプログラムでは、バックスペース、スペース、バックスペースを書き込んでも問題ありませんでした。今私は数年後に同じプログラムを実行すると、何も削除されませんでした。何が変わったの?これを修正するにはどうすればよいですか?

+2

「削除」キーコードを使用してバックスペースを行うのは変です。ほとんどのシステムでバックスペース ''\ b' 'を使う必要があります。 'write()'が画面の一部を上書きする前に 'abc'文字列を画面に表示するには' fflush(stdout) 'する必要があります。あるいは 'write()'を使って 'abc'文字列を出力してください。 –

+0

バッファを解放し、* printf *の代わりに* write *を使用しました。それは私が実証しようとした問題ではありませんでした。コメントが指摘するように、問題は文字127を使用していることです(なぜこれがこれまでに機能したのか分かりません)。 – user224348

+0

可能な説明は、未加工の127を解釈するために途中で終了した端末エミュレータ(または端末)を使用していたこと、そして今日の端末エミュレータの作物はもはやそれをしていないことです。 – user4815162342

答えて

2

私はcommentで述べたように、あなたは後方に移動する代わりに、'\177'(または'\x7F')のバックスペースを使用する必要があります。標準I/Oのバッファリングについても心配する必要があります。この例では、同じストリーム(標準出力)に標準I/Oとファイル記述子I/Oが混在しないようにすることがよくあります。いずれか一方を使用しますが、両方を使用することはできません。

これは動作します:

#include <unistd.h> 

int main(void) 
{ 
    char buff1[] = "abc"; 
    char buff2[] = "\b \b"; 
    write(STDOUT_FILENO, buff1, sizeof(buff1) - 1); 
    sleep(2); 
    write(STDOUT_FILENO, buff2, sizeof(buff2) - 1); 
    sleep(2); 
    write(STDOUT_FILENO, "\n", 1); 
    return 0; 
} 

それは(2秒間)最初に示しています(別の2秒間)、その後

abc 

ab 

それが終了します。最初はcの後にカーソルがあり、その後はbの後です。

2

コメントにジョナサン・レフラーで説明したように、あなたのコードは、2つの変更必要があります。一般的なターミナル(エミュレータ)が理解ラブアウト文字が'\b'(または8)、いない127

  • printf()ある

    • をTTYに書き込むときにデフォルトでラインバッファリングされます。つまり、printf()write()の呼び出しの間にfflush(stdout)に電話する必要があります。フラッシングなしの場合abcはプログラム終了時にのみ印刷されるため、削除順序はより前に発行され、の内容は無効になります。
  • 関連する問題