掲示板

掲示板を置いてみました。ご自由に書き込んで下さい。
ただし、私は根性なしなので、閑古鳥が鳴いたり、荒れてきたと
思ったらとっとと閉鎖する可能性があります。


より新しい記事へ ← 500 件の投稿中 450件目〜401件目を表示 → より前の記事へ
表示件数: 件/頁 


450 Re^3: C言語体当たり学習におけるfgetsの扱いについて コメント数:  2件
  かずま  | sakamoto@sm.sony.co.jp 2002/07/24 (水) 18:07
> fflush()をstdinに適用したときの、動作は未定義だったのでは
> なかったでしょうか?
>
> 世の中の処理系のほとんどはできるようになっているのかもしれませんが...

K&R2 付録B 標準ライブラリ B1.1 の fflush のところに
「入力ストリームに対しては、その効果は不定である。」とあります。

#include <stdio.h>

int main()
{
  char buf[5];

  if (fgets(buf, sizeof buf, stdin) == NULL) return puts("EOF"), 1;
  fflush(stdin);
  printf(":%s:\n", buf);
  if (fgets(buf, sizeof buf, stdin) == NULL) return puts("EOF"), 1;
  printf(":%s:\n", buf);
  return 0;
}

キーボード入力 "abcdef\nxyz\n" に対して、
gcc 2.95 "abcd", "ef\n"
VC++ 6.0 "abcd", "xyz\n"
BC++ 5.5 "abcd", "xyz\n"
LCI C-86 "abcd", "xyz\n"

ファイル入力 "abcdef\nxyz\n" に対して、
gcc 2.95 "abcd", "ef\n"
VC++ 6.0 "abcd", EOF
BC++ 5.5 "abcd", "ef\n"
LCI C-86 "abcd", "ef\n"

これから、分かることは、
gcc: 何もしない。
VC++: キーボード入力もファイル入力も捨てる。
BC++: キーボード入力のみ捨てる。
LSIC: キーボード入力のみ捨てる。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


449 Re^2: C言語体当たり学習におけるfgetsの扱いについて コメント数:  3件
  本多  | manybook@msc.biglobe.ne.jp 2002/07/24 (水) 17:14
> > 入力ストリームをフラッシュすることはできないのでしょうか?
> fflush(stdin);
> でフラッシュできます。

できないんじゃないですか?

fflush()をstdinに適用したときの、動作は未定義だったのでは
なかったでしょうか?

世の中の処理系のほとんどはできるようになっているのかもしれませんが...
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


448 Re: C言語体当たり学習におけるfgetsの扱いについて コメント数:  4件
  xiu 2002/07/24 (水) 10:53
> このように,バッファサイズを超えたとき入力ストリームには何か残っているのでしょうか?

(バッファサイズ)バイト以降のストリームです。

> 入力ストリームをフラッシュすることはできないのでしょうか?

fflush(stdin);
でフラッシュできます。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


447 Re^2: 構造体参照 コメント数:  0件
  xiu 2002/07/24 (水) 10:46
> 関数が構造体の値を返した場合がそうです。

なるほど。そう言われればそうですね。気が付きませんでした。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


446 C言語体当たり学習におけるfgetsの扱いについて コメント数:  6件
  どもども 2002/07/24 (水) 06:43
p228.に「本書の例では,fgets()を使っていても,バッファサイズを超えた場合の処理をやっていないので,(危険だ)。」とかいてありますが,この辺の処理の仕方がわかりません。
このように,バッファサイズを超えたとき入力ストリームには何か残っているのでしょうか?
入力ストリームをフラッシュすることはできないのでしょうか?
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


445 Re: 構造体参照 コメント数:  1件
  かずま  | sakamoto@mc.catv.ne.jp 2002/07/24 (水) 02:46
> 左辺値でない式に対して構造体参照を行うことがあるのでしょうか?
> また、そういったものについては結果が左辺値にならないというのは、
> どういう例があるのでしょうか?

関数が構造体の値を返した場合がそうです。

#include <stdio.h>

struct S { int x, y; };

struct S f(void) { struct S s = { 3, 5 }; return s; }

int main(void)
{
  printf("(%d, %d)\n", f().x, f().y);
  /* f().x = 7; */
  return 0;
}
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


444 一応気がついたので コメント数:  1件
  喜びの壁  | qf7t-mrt@asahi-net.or.jp 2002/07/24 (水) 01:53
体当たり〜p334 getcharの説明文
標準出力から --> 標準入力から

表になかったので。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


443 構造体参照 コメント数:  2件
  xiu 2002/07/23 (火) 14:22
K&R 参照マニュアルA7.3.3に
「また、最初の式が左辺値であって第二の式の型が配列型でなければ、当の式は左辺値である」
とありますが、左辺値でない式に対して構造体参照を行うことがあるのでしょうか?
また、そういったものについては結果が左辺値にならないというのは、どういう例があるのでしょうか?
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


442 Re^2: sqrt()について コメント数:  0件
  Qo-ge 2002/07/16 (火) 20:15
ありがとうございました。
-lmオプションをつけたらコンパイル
することができました。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


441 Re^2: 左辺値 コメント数:  0件
  かずたん 2002/07/13 (土) 22:12
> > 下記のプログラムをコンパイルすると、
> > main()
> > { 
> >  char *a[] = {
> >  "a",
> >  "b",
> >  "c",
> >  ""
> >  };
> > void test(char *a[])
>
> http://member.nifty.ne.jp/maebashi/programmer/pointer.html
> の「その他」の部分を参考にしたらいいのではないでしょうか。
>
> mainの中で定義した「a」は配列だから、インクリメントはできません。
> ポインタはインクリメントできますが、配列はできません。


見落としていました。
助かりました、ありがとうございます。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


440 Re: 左辺値 コメント数:  1件
  本多  | manybook@msc.biglobe.ne.jp 2002/07/13 (土) 21:50
> 下記のプログラムをコンパイルすると、
> main()
> { 
>  char *a[] = {
>  "a",
>  "b",
>  "c",
>  ""
>  };
> void test(char *a[])

http://member.nifty.ne.jp/maebashi/programmer/pointer.html
の「その他」の部分を参考にしたらいいのではないでしょうか。

mainの中で定義した「a」は配列だから、インクリメントはできません。
ポインタはインクリメントできますが、配列はできません。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


439 左辺値 コメント数:  2件
  かずたん 2002/07/13 (土) 20:36
下記のプログラムをコンパイルすると、
#include <stdio.h>

main()
{ 
 char *a[] = {
 "a",
 "b",
 "c",
 ""
 };
 while(*a[0])
 {
  printf("%s\n", *a++);
 }
}

cc: Error: b.c, line 13: In this statement, "a" is not an lvalue, but occurs in a context that requires one. (needlvalue)
printf("%s\n", *a++);
--------------------------------^


また、下記のソースは上手くいきます。なにか違いがあるのでしょうか?
私にはよくわかりません。
#include <stdio.h>

void test(char *s[]);
main()
{
 char *a[] = {
 "a",
 "b",
 "c",
 ""
 };
 test(a);
}

void test(char *a[])
{
 while(*a[0])
 {
  printf("%s\n", *a++);
 }
}
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


438 Re: sqrt()について コメント数:  1件
  (ぱ)   | PXU00211@nifty.ne.jp 2002/07/04 (木) 02:39
 http://member.nifty.ne.jp/maebashi/
> /tmp/ccaN66Pf.o(.text+0x55c): undefined reference to `sqrt'

これはおそらくリンクの時点で出ているエラーだと思われます。
#includeは関係ありません。

C FAQにありますよ。
http://www.catnet.ne.jp/kouno/c_faq/c14.html#3

> と出てしまいました。math.hをemacsで開いて「double sqrt(」でサーチ
> しても見つかりませんでした。これ一体どういう事なのでしょうか?

math.hが別のヘッダを#includeしているかもしれないし。
古いコンパイラ向けに、
extern double sqrt _PARAMS((double));
みたいに、変なマクロが噛んであるかもしれないし。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


437 sqrt()について コメント数:  2件
  Qo-ge 2002/07/03 (水) 21:33
#include<math.h>をしてプログラム中でsqrt(double型の変数)を記述し
コンパイルしたら
/tmp/ccaN66Pf.o(.text+0x55c): undefined reference to `sqrt'
と出てしまいました。math.hをemacsで開いて「double sqrt(」でサーチ
しても見つかりませんでした。これ一体どういう事なのでしょうか?
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


436 Re^4: 共用体の初期化について コメント数:  0件
  xiu 2002/06/25 (火) 09:58
> union u{int a;double b;} x = { 0};
> の様な{}は、不要なんでしたっけ?
>
> これは、構造体だけでしたっけ?

いるみたいです。つけたらコンパイルが通りました。
それと、よく調べて見ると
「初期値式は同じ型の単一の式か、あるいは最初のメンバへの
 大括弧つきの初期値式のいずれかである」
らしいです。どうも、お騒がせしました。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


435 Re^3: 共用体の初期化について コメント数:  1件
  本多  | manybook@msc.biglobe.ne.jp 2002/06/24 (月) 23:13
> しかし、VCでも
> union u{int a;double b;} x = 0;
> は通らなかった気がしますが。

共用体の初期化のときって、
union u{int a;double b;} x = { 0};
の様な{}は、不要なんでしたっけ?

これは、構造体だけでしたっけ?
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


434 Re^2: 共用体の初期化について コメント数:  2件
  xiu 2002/06/24 (月) 22:01
> ちなみにxiuさんはどのコンパイラで試してみたのですか?
いや、コンパイラというか、仕様上はどうなっているか
ちょっとわからなかったのです。

しかし、VCでも
union u{int a;double b;} x = 0;
は通らなかった気がしますが。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


433 Re: 共用体の初期化について コメント数:  3件
  レプラコーン 2002/06/24 (月) 21:15
> Cの文法上の疑問なんですが、共用体を含む型の
> 変数の初期化はできないのでしょうか?
VC++で試しましたが、共用体に初期化子を指定しても初期化できましたよ。
初期化される値は、共用体で最初に定義されるメンバの型になることも確認しました。
ちなみにxiuさんはどのコンパイラで試してみたのですか?
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


432 共用体の初期化について コメント数:  4件
  xiu 2002/06/24 (月) 16:43
Cの文法上の疑問なんですが、共用体を含む型の
変数の初期化はできないのでしょうか?

まあ、できたらどうだっていうこともないんですけど。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


431 Re^2: 多次元配列の生成について コメント数:  0件
  本多  | manybook@msc.biglobe.ne.jp 2002/06/20 (木) 22:38
> > 多次元配列の要素数をユーザの指定した数量だけ確保できるように
> > したいのですが、どのようにしたら良いかどうも思いつきません。
> m×nの配列もどきlistはmallocを使って、以下の様に実装するのが、
> 一般的でしょうか(malloc()のエラーチェックは省略)
> [方法1]
> int **list;
> int i;
> list = malloc( sizeof(int) * m);
> for(i=0;i<m;i++)
> list[i] = malloc( sizeof(int) * n);

すいません、一箇所間違っていました。
誤) list = malloc( sizeof(int ) * m);
正) list = malloc( sizeof(int *) * m);

簡単に書くために省略してますけど、
malloc()のエラーチェックは必ず入れてくださいね。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


430 Re^2: 多次元配列の生成について コメント数:  0件
  Qo-ge 2002/06/20 (木) 17:05
> m×nの配列もどきlistはmallocを使って、以下の様に実装するのが、
> 一般的でしょうか(malloc()のエラーチェックは省略)
>
> [方法1]
>
> int **list;
> int i;
>
> list = malloc( sizeof(int) * m);
> for(i=0;i<m;i++)
> list[i] = malloc( sizeof(int) * n);

ありがとうございました。こうやれば良かったのですね(^^
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


429 Re: 多次元配列の生成について コメント数:  2件
  本多  | manybook@msc.biglobe.ne.jp 2002/06/20 (木) 07:21
> 多次元配列の要素数をユーザの指定した数量だけ確保できるように
> したいのですが、どのようにしたら良いかどうも思いつきません。

m×nの配列もどきlistはmallocを使って、以下の様に実装するのが、
一般的でしょうか(malloc()のエラーチェックは省略)

[方法1]

int **list;
int i;

list = malloc( sizeof(int) * m);
for(i=0;i<m;i++)
list[i] = malloc( sizeof(int) * n);

この配列を実際に使うときは以下の様にします。
list[ i][ j] = n*i+j;

[方法2]
int *list;
list = malloc( sizeof(int) * m * n);

この配列を実際に使うときは以下の様にします。
list[ n * i + j] = n*i+j;

【新規投稿】 【この投稿にリプライ】 【投稿者削除】


428 多次元配列の生成について コメント数:  3件
  Qo-ge 2002/06/19 (水) 23:22
はじめて書き込みさせていただきます。
只今Cを勉強中の学生です。

多次元配列の要素数をユーザの指定した数量だけ確保できるように
したいのですが、どのようにしたら良いかどうも思いつきません。
良いアイディアがありましたら教えてください。
よろしくお願いします。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


427 Re: scanf()について コメント数:  0件
  (ぱ)   | PXU00211@nifty.ne.jp 2002/06/16 (日) 01:01
 http://member.nifty.ne.jp/maebashi/
> 「ちなみに,scanf()に複雑な変換指定子を指定してこの問題を
>回避することもできます」
> の一文がとても気になっています。
> どういう方法なのでしょうか??

「数値の後に入れた改行をscanf()が食べ残す」ということが問題である
わけですから、代入抑止を使って

scanf("%d%*1[\n]", &a);

のようにすると、List2-1の問題は回避できます。
…その程度の意図で書いていたのですが、ちょっと誤解を招くかも。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


426 Re: scanf()について コメント数:  0件
  のぐー  | bxm06466@nifty.ne.jp 2002/06/11 (火) 04:21
 http://homepage1.nifty.com/nogue/
> また先輩には,fflush(stdin);を使うことをすすめられましたが,どうなんでしょうか?(笑)

fflush()は、入力ストリームに使うと「未定義」です。
またrewind()を使うことをすすめる人もいるようですが、rewind()は、
位置決め不可能なストリームに対して「未定義」です。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


425 scanf()について コメント数:  2件
  Yu-ta 2002/06/10 (月) 21:11
「C言語ポインタ完全制覇」の78ページには,
fgets()とsscanf()を組み合わせて使うことを進められていますが,
その後にある,
「ちなみに,scanf()に複雑な変換指定子を指定してこの問題を回避することもできます」
の一文がとても気になっています。
どういう方法なのでしょうか??
また先輩には,fflush(stdin);を使うことをすすめられましたが,どうなんでしょうか?(笑)
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


424 Re^16: ファイル操作 コメント数:  0件
  レプラコーン 2002/06/09 (日) 16:20
> 肝心のnFileIndexHighとfi1.nFileIndexLowが得られません。
試しに作成してみましたが、うちの環境ではショートカットから
物理ファイルと同じSerial値、Index値が正しく取得できることもありました。
しかし、ショートカットを作成しなおしたりすると
途中からSerial値も変わってしまったりして、確実とは言えないみたいですね。
ふたつ目のショートカットは最初からSerial値もIndex値も異なっていました。
OSはWIn98SEです。

Serial値は物理ボリュームに付与される一意の値かと思っていたので、
値が変わるのが謎です。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


423 Re^15: ファイル操作 コメント数:  1件
  のぐー  | bxm06466@nifty.ne.jp 2002/06/09 (日) 07:40
 http://homepage1.nifty.com/nogue/
Win32sの場合、32ビットの範囲内では、どうあがいても不可能というような気が
しました。
GetFileInformationByHandle()は、API自体は成功しますが、肝心のnFileIndexHigh
とfi1.nFileIndexLowが得られません。ファイルサイズやタイムスタンプ等はとれる
ので、これを比較して「同一ファイルの可能性があります。強行すると元ファイル
も失う可能性があります」とかメッセージを出すのが関の山でしょうか?
(この場合もftLastAccessTimeは無視した方が良いと思います。)
たいていのCライブラリにはUNIX互換のstat(), fstat()がありますが、stat構造体
のst_inoが未使用なため使えません。(タイムスタンプ等はとれる)
開始クラスタ番号を直接知ろうにも、DeviceIoControl()も未サポートのようです。
どうしても厳密にやりたければ、16ビットのモジュール(exeでもdllでも可。dllだ
とサンク経由になるためexeのほうが楽だろう)を作成してそれを32ビットexeから
呼び出すことになると思います。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


422 Re^14: ファイル操作 コメント数:  2件
  のぐー  | BXM06466@nifty.ne.jp 2002/06/09 (日) 07:37
 http://homepage1.nifty.com/nogue/
二つのパスが同一ファイルか否か、Win32での確認方法の結論です。
Windows 95以降もしくはWindows NTなら、GetFileInformationByHandle()で得た
BY_HANDLE_FILE_INFORMATION構造体のnFileIndexHighとfi1.nFileIndexLowと、
念のためdwVolumeSerialNumberを比較します。
なおこのとき、構造体の全メンバを比較してはいけません。
GetFileInformationByHandle()を実行するには、前提としてCreateFile()でファ
イルをオープンする必要がありますが、この時ftLastAccessTimeが更新されるか
らです。特に「旧バージョンのMS-DOS」でファイル作成して、直後にWin95で
CreateFile()した時。

【新規投稿】 【この投稿にリプライ】 【投稿者削除】


421 Re^13: ファイル操作 コメント数:  3件
  太田 2002/06/08 (土) 03:08
のぐー様、レプラコーン様、投稿ありがとうございました。

> ユーザが「書き込み側と読み込み側が同一ファイルである」ことに気づか
> ずにOKを出すことは、充分に考えられることです。

「書き込み側と読み込み側が同一ファイルである」ことを考えていたので、
上書きなどの警告で十分だと思いこんでしまいましたが、
普通は、そんなことに注意していないので、
警告は無意味だとわかりました。
ありがとうございました。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


420 Re^12: ファイル操作 コメント数:  4件
  のぐー  | BXM06466@nifty.ne.jp 2002/06/07 (金) 01:46
 http://homepage1.nifty.com/nogue/
> しかし、実際には、書き込み用のファイルを開くには、
> 同名ファイルが存在しないか、
> 上書きしてもいいかを確認していることが
> 前提になるのではないでしょうか?

たとえそれをやってたにしても、上書きしても良いと判断してOKを出した
瞬間に、 「読み込み側が」壊れることまで、ユーザは想定してないと思
います。

ユーザが「書き込み側と読み込み側が同一ファイルである」ことに気づか
ずにOKを出すことは、充分に考えられることです。UNIXならディレクト
リにシンボリックリンク張ってたりすると特に。
DOSやWindowsだと、自分でSUBSTを実行しておきながら、それを忘れて
「ドライブ名が違うから大丈夫」なんて勘違いしてしまうとか。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


419 Re^12: ファイル操作 コメント数:  0件
  レプラコーン 2002/06/06 (木) 21:50
そう言われればそうですね!
UIについての部分がすっかり抜け落ちてました。

ファイルの存在チェックをするfexist()みたいな関数を作成すれば、
システムコールもファンクションコールも意識しないで済みますね。
もし仮にSafeCopy()を作っても、コピー元ファイルがなかったり、
コピー先が存在していた場合は戻り値で判断させられますものね。

本質を見抜けずに技巧だけに囚われたしまったのが
ちょっと恥ずかしいかも・・・。

貴重な投稿、ありがとうございました。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


418 Re^11: ファイル操作 コメント数:  6件
  太田 2002/06/06 (木) 17:07
本多様、投稿してくださったことに感謝いたします。

一連の議論では、いきなり、書き込み用ファイルと
読み込み用ファイルが、名前は違うけれど、
実際には同一である場合を問題にしていると思います。
しかし、実際には、書き込み用のファイルを開くには、
同名ファイルが存在しないか、
上書きしてもいいかを確認していることが
前提になるのではないでしょうか?
それなら、プログラマがリンク先を認識しているか、
ユーザがリンク先に上書きを望んだかになると思います。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


417 Re^3: 可変長引数をとる関数のラッパー関数を作りたい コメント数:  0件
  本多  | manybook@msc.biglobe.ne.jp 2002/06/06 (木) 16:38
> > 文字列変換後の文字列に適切な大きさの領域を確保して
> > 返却値としてポインタを返してくれる関数
> 手元の環境(NetBSD, FreeBSD, Linux)には
> int asprintf(char **ret, const char *formt, ...)
> というのがありますが,これがお望みのものでは?
 まさに、これです!
 やっぱり、あるんですね。

> The functions snprintf() and vsnprintf() first appeared in 4.4BSD.
> The functions asprintf() and vasprintf() are modeled on the ones
> that first appeared in the GNU C library.
 ANSIでもPOSIXでもないんですね。残念!
 情報ありがとうございました。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


416 Re^2: 可変長引数をとる関数のラッパー関数を作りたい コメント数:  1件
  相模  | sagami@brains.co.jp 2002/06/06 (木) 14:59
皆様,始めまして,新米プログラマの相模といいます。
日ごろのページには勉強させてもらってばかりですが,たまたま知っていることがあったものでしゃしゃり出てきました。よろしくお願いします。

> 文字列変換後の文字列に適切な大きさの領域を確保して
> 返却値としてポインタを返してくれる関数

手元の環境(NetBSD, FreeBSD, Linux)には
int asprintf(char **ret, const char *formt, ...)
というのがありますが,これがお望みのものでは?

NetBSD1.5 man によると
asprintf() and vasprintf() return a pointer to a buffer sufficiently
large to hold the string in the ret argument. This pointer should be
passed to free(3) to release the allocated storage when it is no
longer needed. If sufficient space cannot be allocated, these
functions will return -1 and set ret to be a NULL pointer.

だそうです。

ただ,
HISTORY
The functions snprintf() and vsnprintf() first appeared in 4.4BSD.
The functions asprintf() and vasprintf() are modeled on the ones
that first appeared in the GNU C library.

ということなので,使える環境は限られるようです。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


415 Re^10: ファイル操作 コメント数:  7件
  本多  | manybook@msc.biglobe.ne.jp 2002/06/06 (木) 08:45
> 1. ファイルの内容、用途などを暗示する、
> わかりやすいファイル名を使う。
> 2. 紛らわしいリンクなどをしない。
> 上記の2点に注意すれば、
> 特に問題はないと思うのですが、
> 楽観しすぎでしょうか?
 きっと、それは、楽観しすぎでしょう(笑)
 自分しか使わないプログラムなら何してもいいですが。

 一般には、プログラムを作る人と使う人は違いますから。
 紛らわしいリンクをしてないお客様にしか使われない保証のある
 プログラムなんて、少ないでしょう?

 例えば、Freewareとして不特定多数に配ったりしたら、
 どんなアホな使われ方しても、
 せいぜい、「エラーメッセージ表示して終了」くらいしてくれないと。
 いきなり、大事なファイルを上書きしました〜なんて
 起こったら、そんなプログラム...使いませんよね?

 って、そういう話じゃない?
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


414 Re^9: ファイル操作 コメント数:  0件
  レプラコーン 2002/06/05 (水) 19:47
> よって、汎用的なCOPY関数を作るより、汎用的な
> BOOL SamePath(path1, path2)
> のような二つのパスが同一か否かを判断する関数を作ったほうが
> 色々と応用がきくと思いますが。
このSamePathに似た関数を呼び出すコピー関数を作ろうと思ってたのですが。
そうすれば、プラットフォームを移動したときに
コピー関数も持っていけますし・・・。

構成的にはこうですかね。

SafeCopy()
 SamePath()
  MS-DOSならint21H:Func60Hを呼び出す
  UNIXならstat()でst_inoをを見る
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


413 Re^9: ファイル操作 コメント数:  8件
  太田 2002/06/05 (水) 19:36
> この問題はコピーに限らず、二つのファイルを一方は読込みで,
> もう一方は書込みでオープンする必要があるすべてのアプリに関わりがあ
> ります。

1. ファイルの内容、用途などを暗示する、
わかりやすいファイル名を使う。

2. 紛らわしいリンクなどをしない。

上記の2点に注意すれば、
特に問題はないと思うのですが、
楽観しすぎでしょうか?
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


412 Re^3: 可変長引数をとる関数のラッパー関数を作りたい コメント数:  0件
  本多  | manybook@msc.biglobe.ne.jp 2002/06/05 (水) 16:33
ラッパー関数を作成するのは難しいですけど、

もし、運がよく開発環境が
可変引数マクロに対応していたら、
以下の様なマクロをラッパー代わりに使えるかもしれません。

#define wrapper_macro(n,dw,sw,pFmt, ...) \
{\
pre_check ( n,dw,sw,pFmt, __VA_ARGS__);\
 func ( n,dw,sw,pFmt, __VA_ARGS__);\
post_check( n,dw,sw,pFmt, __VA_ARGS__);\
}

返却値がなくなっちゃったり、副作用の心配があるなど、
色々問題はありますが、
検討の価値はあるかも?

可変引数マクロってC99の規格だったかしら?>詳しい人
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


411 Re^4: 可変長引数をとる関数のラッパー関数を作りたい コメント数:  0件
  tf 2002/06/05 (水) 12:47

リプライありがとうございます

> 確認ですが、ラッパ関数とDLL関数で引数int swがなくなっているのですが
> これでただしいのでしょうか?
抜けです。すみません。m(_ _;m

> しかし、上スレッドでもありましたけど、いずれにしても真っ当な方法では
> できないような気がします。
> どちらかといえば、DLLチェックの位置を変えたほうが簡単なような。
>
> 動的にサイズ変更可能なオブジェクト型というのがCにあれば無理やりですが
> できるんでしょうけど。
>
> #こんな感じ?(以下戯れ言)
> VARIABLE_OBJECT args;
> memcpy(&args...
> func( n, dw, pFmt, args );
>
> いずれにせよ、Cじゃ無理です。
うーん。そうですか。わかりました。やっとすっきりしました。
できないなら、しょうがないですものね(^_^)
なにか別の方法を考えるなり、つくりを変えるなり
してみます。

皆様、どうもありがとうございました。m(_ _)m


【新規投稿】 【この投稿にリプライ】 【投稿者削除】


410 Re^3: 可変長引数をとる関数のラッパー関数を作りたい コメント数:  1件
  xiu 2002/06/05 (水) 11:40
確認ですが、ラッパ関数とDLL関数で引数int swがなくなっているのですが
これでただしいのでしょうか?

しかし、上スレッドでもありましたけど、いずれにしても真っ当な方法では
できないような気がします。
どちらかといえば、DLLチェックの位置を変えたほうが簡単なような。

動的にサイズ変更可能なオブジェクト型というのがCにあれば無理やりですが
できるんでしょうけど。

#こんな感じ?(以下戯れ言)
VARIABLE_OBJECT args;
memcpy(&args...
func( n, dw, pFmt, args );

いずれにせよ、Cじゃ無理です。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


409 Re^2: 可変長引数をとる関数のラッパー関数を作りたい コメント数:  3件
  tf 2002/06/05 (水) 09:36
本多さん。リプライありがとうございます。
vsprintf。いまさらながら思い出しました(^_^;;

それと、説明が適切でなかった点をお詫びいたします。
皆様、もう少しだけお付き合いいただけないでしょうか?
現在の状態は次のようなものなのです...。

誰かが作成したDLLがあります。
私は、Dllの存在確認、ロード、関数呼び出しについて
責任を持ってくれるラップクラスを作成することにしました。

ここで、DLLの中に、ひとつだけ次のような宣言の関数があったのです。

void WINAPI EXPORT Foo(
int n, DWORD dw, int sw, char* pFmt, ...
);

私は次のようにしました

typedef void (WINAPI *PFUNC)( int, DWORD, int, char*, ... );

void CProxyDll::Foo(
int n DWORD dw, int sw, char* pFmt, ...
)
{
PFUNC func = GetFuncPtr( "Foo" );
ASSERT( func != NULL );
if ( func == NULL )
{
::AfxThrowProxyDllException(); }

// ここで、Dllに定義された関数にもらった引数をまるなげしたい。
func( n, dw, pFmt, /*?????*/ );
}

上記のようなことをしたい場合、どうすればよいのでしょうか??

説明が下手で申し訳ないのですが、リプライいただければ幸いです。


【新規投稿】 【この投稿にリプライ】 【投稿者削除】


408 Re^8: ファイル操作 コメント数:  0件
  のぐー  | bxm06466@nifty.ne.jp 2002/06/05 (水) 01:34
 http://homepage1.nifty.com/nogue/
> 同じ関数は使用できないことが判りましたが、
> ソースを分ける必要はありません。
>
> #ifディレクティブを使用して適切なルーチンを
> コンパイルするようにすれば大丈夫です。

で、具体的にどういう関数を使えばよいのでしょうか?
dosやwindows3.1ならint21h function 60h
UNIXならstat()もしくはfstat()
というところまではわかったのですが、WIN32の場合が
いまだにわかりません。
できればWindows3.1+Win32sでも使える方法希望。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


407 Re^8: ファイル操作 コメント数:  10件
  のぐー  | BXM06466@nifty.ne.jp 2002/06/05 (水) 01:29
 http://homepage1.nifty.com/nogue/
>  これを書いたときは、一般的なアプリケーションがデータファイルを
>  上書き保存する際に、元のファイルをback upファイルとする場合の
>  ことを考えておりました。
>  この場合、バックアップファイルを作成するのに
>  move機能があれば、copy機能は使うことはありえないと思ったわけです。

ていうか、この問題はコピーに限らず、二つのファイルを一方は読込みで,
もう一方は書込みでオープンする必要があるすべてのアプリに関わりがあ
ります。ファイルが充分に小さいならメモリに全部読み込んでから書込み
ファイルをオープンするという方法が使えますが。

よって、汎用的なCOPY関数を作るより、汎用的な
BOOL SamePath(path1, path2)
のような二つのパスが同一か否かを判断する関数を作ったほうが
色々と応用がきくと思いますが。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


406 Re^2: 動的に引数の数を変更する関数呼び出し コメント数:  0件
  xiu 2002/06/05 (水) 01:09
やっぱり無理ですか。
まあ、普通はポインタで解決しますし(というか
可変引数自体printf系くらいにしか使いませんが)、
特に必要性はないのかもしれません。

ただちょっとダークサイド?に興味があったもので。

前橋さん、本田さん、どうもありがとうございました。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


405 Re: 動的に引数の数を変更する関数呼び出し コメント数:  0件
  (ぱ)   | PXU00211@nifty.ne.jp 2002/06/05 (水) 00:28
 http://member.nifty.ne.jp/maebashi/
> 何か抜け道はないのでしょうか?

http://www.catnet.ne.jp/kouno/c_faq/c15.html#13
| 動くことが保証される方法も移植性の高い方法もない。
| 興味があるの ならこのリストの編者に聞いてみること。
| 彼はヘンテコリンなアイデ アをいくつか持っている

だそうで。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


404 Re: 動的に引数の数を変更する関数呼び出し コメント数:  1件
  本多  | manybook@msc.biglobe.ne.jp 2002/06/04 (火) 23:37
> 可変引数をとる関数を呼び出すときに、その引数の数をfor文等で
> 動的に変更することは出来るのでしょうか?

 stdarg.hのマクロやva_list型を参照して、
 引数のデータの格納される仕組みを調べ、
 va_list型の配列を自作して、それに「適切に」
 データを書き込んで、vprintf()などに渡してやるとか?
 ...どちらにしよ、汎用的なものは作れないですね。

もし、呼び出される関数も自作するなら、
 引数にして渡したい値を格納している変数へのポインタを
 voidポインタの配列に突っ込んで、
 各配列の要素を適切な型に直す情報と一緒に
 呼び出される関数の側で、各ポインタから適切な値を取り出す...
と、いう方法が考えられますが、

【新規投稿】 【この投稿にリプライ】 【投稿者削除】


403 動的に引数の数を変更する関数呼び出し コメント数:  3件
  xiu 2002/06/04 (火) 22:24
tfさんが可変引数について書き込まれているので便乗質問。

可変引数をとる関数を呼び出すときに、その引数の数をfor文等で
動的に変更することは出来るのでしょうか?
理屈上は、引数をスタックに詰めてやればいいんでしょうけど、
関数にジャンプする前に引数をpushするのはinlineアセンブラ
でも厳しそうです(やりたくもないですし・・・)。

何か抜け道はないのでしょうか?
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


402 Re^9: ファイル操作 コメント数:  0件
  (ぱ)   | PXU00211@nifty.ne.jp 2002/06/04 (火) 21:52
 http://member.nifty.ne.jp/maebashi/
> > > 当然これはWindowsでも動作します。
> >
> > Win9x系限定ですよね? 確か。
>
> えっ? NTでも、通常の16ビットアプリは動作するのでは?
> intdos()やint86()程度ならエミュレートしてたはず。

…すみません、IN/OUTでI/Oポートを叩く話と混同してました(_o_)
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


401 Re^7: ファイル操作 コメント数:  1件
  レプラコーン 2002/06/04 (火) 19:55
> 共通してできるようなものが作りたかったのですが、難しいようですね。
同じ関数は使用できないことが判りましたが、
ソースを分ける必要はありません。

#ifディレクティブを使用して適切なルーチンを
コンパイルするようにすれば大丈夫です。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】

Copyright(C) 1999 NIFTY Corporation
All Rights Reserved.