ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

C言語とC++言語コミュの教えてください。

  • mixiチェック
  • このエントリーをはてなブックマークに追加
初めまして。
大学でC言語を習っている者です。
今は長期休みなので、自宅でC言語の問題を作っています。
柴田望洋さんの明解C言語中級編のプログラムを真似して勉強しているのですが、
#include <time.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "getputch.h"
int main(void)
{
int i;
char *str="How do you do?";
int len=strlen(str);
clock_t start,end;
init_getputch();
printf("このとおりタイプしてください。\n");
printf("%s\n",str);
fflush(stdout);
start=clock();
for(i=0;i<len;i++){
int ch;
do{
ch=getch();
if(isprint(ch)){
putch(ch);
if(ch!=str[i])
putch('\b');
}
}while(ch!=str[i]);
}
end=clock();
printf("\n%.1fでした。\n",(double)(end-start)/CLOCKS_PER_SEC);
term_getputch();
return 0;
}
このプログラムの最後のprintfが表示されないんです。

コメント(38)

getputch.hはこれです。
/*getch/putch用ヘッダ "getputch.h" */

#if !defined(__GETPUTCH)

#define __GETPUTCH

#if defined(_MSC_VER) || (__TURBOC__) || (LSI_C)


#include <conio.h>
static void init_getputch(void) { }
static void term_getputch(void) { }

#else

#include <curses.h>

#undef putchar
#undef puts
#undef printf
static char __buf[4096];

static int __putchar(int ch)
{
if(ch == '\n')
putchar('\r');
return (putchar(ch));
}

static int putch(int ch)
{
int result = putchar(ch);

fflush(stdout);
return (result);
}

static int __printf(const char *format, ...)
{
va_list ap;
int count;

va_start(ap, format);
vsprintf(__buf, format, ap);
va_end(ap);

for (count = 0; __buf[count]; count++) {
putchar(__buf[count]);
if (__buf[count] == '\n')
putchar('\r');
}
return (count);
}

int __puts(const char *s)
{
int i, j;

for(i = 0, j = 0; s[i]; i++){
__buf[j++] = s[i];
if(s[i] == '\n');
__buf[j++] = '\r';
}
return (puts(__buf));
}

static void init_getputch(void)
{
initscr();
cbreak();
noecho();
refresh();
}

static void term_getputch(void)
{
endwin();
}

#define putchar __putchar
#define printf __printf
#define puts __puts

#endif

#endif
1.OSなどの環境
2.使用しているコンパイラ
3.コンパイラへのパラメータ

最低限、これだけ分からないと何も答えられません。
使用しているOSはvine linux 4.2です。
コンパイラはGNU C Compilerを用いています。
パラメータは学校で習っていないのでよく分かりません。。
--------- 以下出力 ----------
このとおりタイプしてください。
How do you do?
How do you do?
5.2でした。
----------------------------
とりあえず当方は
windows 7
visual C++ 9

まさか…と思いますが 最後の return 0; の一行前に getch(); を置いた場合はどうでしょうか。
それで改善されてしまった場合改善されなかった場合でもレポートを求めます。
ruskさんありがとうございます。



return 0;の一行前に getch();を置いてみたんですが、改善はされなかったです。
やっぱり全て消えました。


[student@localhost List]$ ./list8-1
(この間に,このとおりタイプしてください。
How do you do?
は表示されて、How do you do?の最後の?を入力したところで全て消えます。)

[student@localhost List]$
5:
もう一行前、term_getputch(); の直前にgetch();を置いたらどうなります?
やってみたんですが、How do you do?と入力した後printfは表示されませんでした。
その後、何かひとつでも入力すると、やっぱり表示されていたのが全てきえました。
VS2008でやってみました。
出力は

このとおりタイプしてください。
How do you do?
How do you do?
7.4でした。

です。
実際にこのように出力されたらいいということなんでしょうか?
3度の飯より猫さんありがとうございます。
実行すると

このとおりタイプしてください。
How do you do?
How do you do

ここまで入力して最後の?を入力すると
[student@localhost List]$ ./list8-1
[student@localhost List]$

最後のprintfが表示されずにこういう風に表示されます。
8:
表示が全て消えたと言うことは、画面消去のエスケープコマンドか何か("ESC[*"のような)が出ていると思うんですが。
実行時に標準出力をファイルにリダイレクトしたら、何が書き込まれるでしょう?
[student@localhost List]$ ./list8-1
[student@localhost List]$

これはリナックスならあることらしいです
僕は使ったこと無いのでわからないのですが。
多分プログラム終了時にそれが表示されるということではないでしょうか?
http://markun.cs.shinshu-u.ac.jp/learn/linux/h_03-01.html

何かキーを押したらすべて消えるというのは
プログラムが終わった状態になっていて何かキーを押せば終了する
ようになっているからだと思われます。
ためしに何もしないプログラムで試してみてください。


そして最後のprintfで数字の表示を止めて文字だけの場合うまくいきますか?
12:

printfで文字だけの場合もやってみたんですが、今までと同じ様な結果になりました。
ubuntuで再現しました。

printf("\n%.1fでした。\n",(double)(end-start)/CLOCKS_PER_SEC);
refresh() ;
getch();
term_getputch();

こうすると、大体意図したように表示されます。(ただし、clock()が意図した値を返しません。)
end=clock(); のあたりで何か問題があるかもしれないのかな?
printfでstart=clock();の値を表示できたらいけるはずですが
いけない場合は
>14 みすとさんの言うとおり
意図したことをしてくれてない可能性がありますね。
How do you do?
-0.022411
How do you do?
-0.022411

それぞれのclock関数の直後に
printf("%f\n",start) ;
printf("%f\n",end) ;
として出力させてみました。start も end も同じ値になってますね。
みすとさんの言うとおりにするとprintfは表示されたんですけど、時間が0.0秒になって正確には出ませんでした。
他のgetputch.h を使わないプログラムで時間を計ったら、やはり0.0秒になって clock();が正確には使われていませんでした。
clock();に問題があるのでしょうか?
こちらを見ると、cursesを使うときにはprintf()の代わりにprintw()を使えと有るんですが。
http://www.fireproject.jp/feature/c-language/curses/window.html

また、refresh()をよばないと画面の変更が更新されない、ともあります。
これでもないとなるとホントわからないですね・・・
いくらかprintfを最後に追加してみるたりでも変わらないですか?
すいません。clock_tは整数型ですね。
printf("%ld\n",start) ;
printf("%ld\n",end) ;
としたら・・・両方 0 になりました。
両方0になったのならその後のCLOCKS_PER_SEC
で割り算をしているからですね。
0除算は出来ないので問題が起こって終わっているんですね

clock()については良くわからないのでお手上げです
力になれなくてすみません。
end=clock()
の前に
for(i = 0; i < 10000000; i++)
{
sum += i ;
}
と言う空ループを入れて、最適化を抑制してコンパイルすると、

4.7でした。

と表示されます。
どうも、clockはCPU消費時間を取得するのですが、元々のプログラムがほとんどCPU時間を消費しないために、0になってしまう、と言うことの様です。(windows環境だと、実経過時間を取得しているみたいですね)
#include <sys/time.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "getputch.h"

double gettimeofday_sec()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + (double)tv.tv_usec*1e-6;
}

int main(void)
{
int i;
char *str="How do you do?";
int len=strlen(str);
double start,end;
init_getputch();
printf("このとおりタイプしてください。\n");
printf("%s\n",str);
fflush(stdout);
start=gettimeofday_sec();
for(i=0;i<len;i++){
int ch;
do{
ch=getch();
if(isprint(ch)){
putch(ch);
if(ch!=str[i])
putch('\b');
}
}while(ch!=str[i]);
}

end=gettimeofday_sec();
printf("\n%.1fでした。\n",end-start);
refresh() ;
getch();
term_getputch();
return 0;
}

こんな感じですかねぇ・・・。
参考書にendwinは、ライブラリの後始末用の関数であり、Cursesライブラリの利用時に最後に呼び出さなければならない(通常の環境では、画面上の文字がすべて消えてしまう)。
ってあったんですけど、このせいで画面上の文字が消えているんですか?
curses環境ではprintw()を使えとあるんですが、これはひょっとしてprintf()したあとrefresh()してるんでしょうかね。
一応printwを使ってみたんですが、結果は同じでした。
私もendwinが気になるんですが、term_getputch()の中でよんでるんですよね。
そうなると、getputch.h内のprintf()の最後でrefresh()をよぶのが一番スマートでしょうか。
> 24:
おそらくそういうことなのでしょう。

initscr();
で一時的な画面を確保し、
endwin():
でその画面を開放する、と言う動作なんだと思います。

windowsでは、開放した直後、その画面を表示していてくれる。
linuxでは表示を維持せずに、元の画面に戻ってしまう、と言う仕様なのではないかと。
28:
windowsでは条件コンパイルでinit_getputch()もterm_getputch()も実装は空になってますね。
なので、unix系のcurses特有の仕様、と言うことでしょう。
あ、確かにそうですね。失礼しました。
>28:
ありがとうございます。
linuxでは表示されないんですね。

>27:getputch内のprintf()の最後でrefresh()をよんでみます。


今、xemacsでプログラム作っているんですけど、日本語をスペースで変換しようとしたら、変換したい文字が全て消えて、日本語入力モード?みたのが解除されたんですよ。
どうやったら直るんすか?
31:
環境はFreeBSDですが、こんなサイトが有りました。

http://suken.jp/~tet/freebsd/free18.html
>XEmacs では日本語入力の切り替えがデフォルトでは Ctrl + \
>31:

Ctrl+\で切替えた後に、変換をすると文字が消えるんですよ(泣)
33:
日本語環境の設定となると、このコミュの範囲外ですねぇ。
Linux関係やemacs関係のコミュの方が、詳しい人が多いかと。
わざわざxemacsの変換機能を使わなくていいのに
>33:
そうですね。
emacs関係のコミュに行ってみます。

>34:
どういうことですか?
パーマーさん、コメント番号が1つずつずれているようですが?
Solaris 9 on x86 では 元のプログラムで
0.0 と表示されますね。CPU 時間を消費しないので。

<sys/varargs.h> 追加しないと駄目ですが

ログインすると、残り1件のコメントが見れるよ

mixiユーザー
ログインしてコメントしよう!

C言語とC++言語 更新情報

C言語とC++言語のメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング