人に聞けない痔の悩み、これでスッキリ >>

現在、SolarisでC言語の簡単なアプリケーションを作成しています。
そこで、管理者以外の人に悪用されないようにという名目で、作ったプログラムを端末エミュレータで起動させ、それに標準入力からパスワードを入力させるようにしたいと考えています。
しかし、そのためには、入力したパスワードをターミナル上に表示されては困るので、ターミナルに入力された文字列を表示させないようにするにはどうしたらよいのでしょうか?
いろいろと調べたのですが、具体的な関数がよくわからなかったので、エコーバックをなくすような関数がありましたら、是非教えてただきたいと思います。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

結構、面倒です。

覚悟してください。入出力がファイルにリダイレクトされている場合の処置とか、途中でCtrl+Cを押された場合の始末とか、諸々を付け加えると100ステップを超えてしまうかもしれません。

#include <termio.h>
struct termio tbuf;
char passowrd [100];
ioctl (0, TCGETA, &tbuf);
tbuf.c_lflag &= ~ECHO;
ioctl (0, TCSETA, &tbuf);
fputs ("password: ", stdout);
fgets (password, stdin);
tbuf.c_lflag |= ECHO;
ioctl (0,TCSETA, &tbuf);
    • good
    • 0

パスワード入力のプロンプトになったら、標準出力を


close()してしまえば、画面には出力されなくなると
思いますが、だめでしょうか?
    • good
    • 0

ioctlってシステムコール使えばやれると思いますよ。


Linuxではやったことありますが、多分Solaris(Unix)でも
いけたはず・・・
ioctlの使い方はmanでも見て下さい。
    • good
    • 0

このソースを試してみてください。


ヒントになるでしょう。
Enterキー入力後にエコーバックします。
キーワードはsttyコマンドです。
----
#include <stdio.h>
main()
{
char bf[1000];
memset(bf, NULL, 1000);
printf("PASSWD:");
system("stty -echo >/dev/null 2>&1");
scanf("%s", bf);
system("stty echo >/dev/null 2>&1");
printf("\nエコーバック=>%s\n",bf);
}

この回答への補足

お答えありがとうございます!
しかし、system関数を使わずに、C言語の関数(ライブラリを含む)ですることはできるのでしょうか?

補足日時:2003/07/23 13:28
    • good
    • 1

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qlinux上でgetchを使いたい

linux上でgetch()を使おうと思い、<conio.h>をインクルードしたのですが、未定義のエラーが出てしまいます。どうやら、linuxでは、<conio.h>が無い?みたいなのですが、どうやったら、getch()を使用できるようになるのでしょうか??

Aベストアンサー

基本的には #1 さんの参考 URL の方法でいいですが,
mygetch() を呼ぶたびに tcgetattr(),tcsetattr() するのでちょっと無駄が多い.
(性能低下を招くほどではありませんが.)

アプリケーションの起動から終了まで,あるいは一定期間 raw モードだけを
使うのなら,次のサンプルのように一度端末モード設定をしてあとは普通に
getchar() を使う方が効率は (少しですが) いいです.

/*--------------------------------------------------------------------------
サンプル
・1文字入力するたびに標準出力に出力する.
・制御文字は16進で出力.
・CTRL-D を押すと終了.
--------------------------------------------------------------------------*/
#include <stdio.h>
#include <unistd.h>
#include <termios.h>

#define QUIT_CHAR 0x04 /* CTRL-D を押すと終了する.*/

// 端末設定保存用大域変数
struct termios CookedTermIos; // cooked モード用
struct termios RawTermIos; // raw モード用


int main(void)
{
  int c;

  // 初期状態の端末設定 (cooked モード) を取得・保存する.
  tcgetattr(STDIN_FILENO, &CookedTermIos);

  // raw モードの端末設定を作成・保存する.
  RawTermIos = CookedTermIos;
  cfmakeraw(&RawTermIos);

  // 端末を raw モードに設定する.
  tcsetattr(STDIN_FILENO, 0, &RawTermIos);

  // 1文字入力されるごとに標準出力にエコーする.
  while((c = getchar()) != QUIT_CHAR) {
    if(isprint(c)) {
      // 印字可能文字の場合:そのまま表示.
      putchar(c);
    } else {
      // 制御文字の場合:16進で出力.
      printf("<%02X>", c);
      if(c == '\n') fputs("\r\n", stdout);
    }
  }

  // 端末設定を元に戻す.
  tcsetattr(STDIN_FILENO, 0, &CookedTermIos);
  putchar('\n');
  return 0;
}

基本的には #1 さんの参考 URL の方法でいいですが,
mygetch() を呼ぶたびに tcgetattr(),tcsetattr() するのでちょっと無駄が多い.
(性能低下を招くほどではありませんが.)

アプリケーションの起動から終了まで,あるいは一定期間 raw モードだけを
使うのなら,次のサンプルのように一度端末モード設定をしてあとは普通に
getchar() を使う方が効率は (少しですが) いいです.

/*--------------------------------------------------------------------------
サンプル
・1文字入力するたびに...続きを読む

Qfgetsなどのときのstdinのバッファを消すには?

こんにちは,今C(C++でない)を使用しています。
たとえば,
char str[20]
fgets(str,sizeof(str),stdin)
としたときに20字以上を打つと,stdinのバッファに20字以上の分が残ったままになります。

C++などでは
fflush(stdin)で,うまくいきますが,普通のCでは対応がされていないみたいでうまくいきません。

よろしくお願いします。

Aベストアンサー

あ,テキスト入力だからこんな大掛かりなことしなくてもいいんだ.
末尾に'\n'が出るまで掃出せばいいんですよね.

fgets(str, sizeof(str), stdin);
if ( str[strlen(str)-1] != '\n' ){
while( getchar() != '\n' );
}

でいいんだ.失礼しました.

QC言語の標準入力で改行しない方法

端末で入力を受けて、改行せずに次の表示を行いたいのですが、

char str[32];
printf("ほげほげ");
fgets(str, sizeof(str), stdin);
str[strlen(str) - 1] = '\0';
printf("ホゲホゲ");

とすれば
「ほげほげ (入力した内容) ホゲホゲ」
と表示できると考えましたが、これでは改行されて
「ほげほげ (入力した内容)
ホゲホゲ」
になってしまいます。原因がわかりません…

使用している環境は Linux Ubuntu 10.10 で gcc でコンパイルしています。

改行しない方法を説明しているサイトのサンプルをコピペして実行してみても、改行されてしまいました…

Aベストアンサー

>原因がわかりません…
>fgets(str, sizeof(str), stdin);

の時点で、改行文字まで込みでエコーバックされているようですから無理じゃないですかね?
# つまりターミナル上ではfgets()から戻ってきた時点で改行処理が終わっている。

>使用している環境は Linux Ubuntu 10.10 で gcc でコンパイルしています。

http://oshiete.goo.ne.jp/qa/608841.html
ioctl()の利用でなんとかなるかもしれません。
フラグの設定方法次第かも知れませんけど。
# 改行だけエコーバックさせない…ってところでしょうか。
# ECHONLが関係しますかねぇ…。

>改行しない方法を説明しているサイトのサンプルをコピペして

それは「fgets()で取得した文字列から改行コードを取り除く」ではありませんか?
まぁ、fgets()で渡したバッファよりも長い文字列を入力した場合に誤動作すると思われますが。
# 改行コードかどうか判定してから削除しないと…ね。

Qfgetsで拾われる改行文字を削除したい

お世話になります

 C言語初心者のものです。今課題でC言語を用いたプログラミングを
Fedora上でやっています。問題は、fgetsでテキストファイルから、取得
した文字列の中から改行文字を削除できないことです。文字変数のアド
レスはわかっているのですが、終端文字に置換しようとすると、セグメ
ントエラーになってしまいます。これは如何にして解決すべきでしょう
か。よろしくお願いします。

Aベストアンサー

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが最大文字数に達したり、ファイルの最後になったりで、strに改行文字が含まれない場合には、このループは止まりません(Segmentension Falutになって止まる)

・そのような状態になってないか、予めチェックする
・ループを終了させる仕組みを用意しておく
: forの終了条件を記述する、for中で if(*(str+i)=='\0') { break;} 等としておく、等
といった対策が必要です。


あと細かいところを言えば
・strを配列で用意したなら *(s+i)じゃなくてs[i]でいいんじゃないかな
・あるいは char *pみたいにしておいて、 iのループでなく pでループを組む( for(p=str;*p!='\0';p++) )とか。

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが...続きを読む

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

Q入力関数を使うがコンソール上に表示しない

linux上でコンソール表示しない入力関数って無いんですか?
1~300までの値を入力すると画面に入力した値を表示せずに読み込みたいのですが、どうすればいいのでしょう??
わかる人は是非教えてください

Aベストアンサー

参考URLに CON デバイスを fopen して、getch 入力する方法が載っています。(「I/O リダイレクトされないコンソール入力」の欄参照)

参考URL:http://www.tmd.ac.jp/med/phy1/msc/msc.html

QC言語での方向キー入力判定

C言語でキーの入力判定をするプログラムを作ってい
ます。下の例だとeやエンターを押したときは認識できる
のに、方向キー↑を押したときはなぜか無反応です。

コンパイラはボーランドでOSはXPでコンパイルした
のですが、何がいけなかったのでしょうか?


#include <stdio.h>
#include <conio.h>
#include <windows.h>

void check(void){
int key;
key = getch();

switch (key){
case 'e':
puts("e");
break;
case VK_RETURN:
puts("ENTER");
break;
case VK_UP:
puts("UP");
break;
}

}

int main(void)
{
while(1){
check();
}
return 0;
}

Aベストアンサー

getch がVK_UPを返すのではないです。
↑の場合0と0x48の2つのコードが返ります

QC言語で文字列をかえす正しい書き方が知りたいです?

C言語で次の警告が表示されます。
文字列を返したいのですが、正しい書き方はどのようにすれば良いのでしょうか?


jci.h(20) : warning C4172; ローカル変数またはテンポラリのアドレスを返します。


char *test(char *a, int b)
{
char str[BUFSIZ];
return str; <------

}

Aベストアンサー

再入可能にするかどうかで、回答は変わります。

A.2度呼び出した場合に前のデータを破壊してもよいケース(再入不可能)

char *test(...)
{
static char str[BUFSIZ]; // static指定でメモリは静的に確保されます。

...

return str;
}

B.2度呼び出した場合に前のデータを破壊しないケース(再入可能)
B-1.mallocを使ってもいいケース
char *test(...)
{
char *str;
str = malloc(BUFSIZ);
if(str == NULL) return NULL; // エラー

...

return str;
}
この場合は、呼び出し元でちゃんとfreeしましょう。

B-2.呼び出し元でメモリを確保するケース
(注意:同じアドレスを指定して複数回呼び出すと、メモリ内容は当然破壊されます)
char *test(char *str, ...)
{

...

return str;
}
これは#1の方の回答と同じです。

B-3.B-1/B-2の複合
(注意:NULL以外の同じアドレスを指定して複数回呼び出すと、メモリ内容は当然破壊されます)
char *test(char *str, ...)
{
if(str == NULL)
{
str = malloc(BUFSIZ);
if(str == NULL) return NULL; //エラー
}

...

return str;
}

こんなところですかね。

再入可能にするかどうかで、回答は変わります。

A.2度呼び出した場合に前のデータを破壊してもよいケース(再入不可能)

char *test(...)
{
static char str[BUFSIZ]; // static指定でメモリは静的に確保されます。

...

return str;
}

B.2度呼び出した場合に前のデータを破壊しないケース(再入可能)
B-1.mallocを使ってもいいケース
char *test(...)
{
char *str;
str = malloc(BUFSIZ);
if(str == NULL) return NULL; // エラー

...

return str;
}
この場合は、呼び...続きを読む

Q"scanf"でエンターで改行させない方法

#include<stdio.h>
int main(void){
int x;
scanf("%d", &x);
printf("%d\n", x);
}

scanfの入力カーソルの所で何も入力せずにエンターを押すと1行下にカーソル位置が行ってしまいます。
それをエンターを押してもカーソル位置を変えないようにしたいのですがどうすればいいでしょうか?

Aベストアンサー

scanfの仕様上、回避不能だね。

ただ、ちょっとだけ別の逃げ方が有るよ。
それは直後に中身を調べて空っぽだったらカーソルを↑に移動するコントロールコードを出力する方法。

時々さ、プロンプトの処理なのに同じ行のまま「○%進行中」みたいのを維持してるのが有るでしょ?
あれはその方法で元の行に無理矢理戻して上書きしてるんだよ。

QEnterキーを押されたら次の処理に移るという事をしたい。

コンソールアプリケーション上で文字列を表示させた後、ユーザーがエンターキーを押したら次の文字列を表示するという仕様にしたいのですが、エンターキーだけ入力待ちにするっていうのはどのように書けばいいんでしょうか?

Aベストアンサー

#include <stdio.h>

int main(void)
{
char *str[] = {"abc", "def", "ghi", "jkl"};
int i;

for(i = 0; i < 4; i ++){
while(getchar() != '\n') ;
puts(str[i]);
}
return 0;
}


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング