C言語なら、俺に聞け! <10>
■ このスレッドは過去ログ倉庫に格納されています
0001Cハッカー日下部陽一
NGNGいろいろな言語を極めたが、一番手になじむのはCだった。
Cのことならぜんてわかるから、疑問な点があったらオレに聞け。
だが、いちいちFAQに載った質問に応えるほど暇じゃない。
課題丸投げなら別スレにいけ。
・comp.lang.c Frequently Asked Questions
http://www.eskimo.com/~scs/C-faq/top.html
・C FAQ 日本語訳
http://www.catnet.ne.jp/kouno/c_faq/c_faq.html
・前スレ C言語なら、オレに聞け! <9>
http://pc.2ch.net/test/read.cgi/tech/1007272267/l50
Cプログラマならこれを買っとけ。
・プログラミング言語C(K&Rと呼べば通のようだぞ)
http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/yfcbookshelf-22/250-3950205-1475419
K&Rで挫折するようなヤツはこれでも買え。
これでわからない、救いがたいヤツはあきらめろ。
・作ってわかるCプログラミング(アヒル本と呼べば通のようだぞ)
http://dennou.gihyo.co.jp/books/void_c/
http://www.amazon.co.jp/exec/obidos/ASIN/477411328X/qid%3D1005618315/250-3950205-1475419
0002デフォルトの名無しさん
NGNG0003デフォルトの名無しさん
NGNG0004デフォルトの名無しさん
NGNG0005デフォルトの名無しさん
NGNG早速ですが、ファイルポインタを引数として関数に渡そうとしてコーディング
してみたのですが、どうも上手くいきません。
方法は下記の通りです。
main(){
FILE *FP;
Init_Proc(&FP);
}
Init_Proc(FILE **FP){
*FP = fopen(・・・);
X_Proc(FP);
}
X_Proc(FILE **FP){
fprintf(*FP, "%s\n", "ABC");
}
現状ではX_Procでファイル書込を行った際にファイルポインタが破壊されて
いるようです。
ファイルポインタを引数として渡すことはあまりなくて、どのようにすれば
よいのかわかりません。
みなさん、ご教授を宜しくお願いします。
0006Kusakabe Youichi
NGNGデフォルトの名無しさん wote:
>いつもお世話になっております。
そういうことにしたいのですね。
0007デフォルトの名無しさん
NGNGつかれてきましたね?
0008Kusakabe Youichi
NGNG> main(){FILE *FP;Init_Proc(&FP);}
> Init_Proc(FILE **FP){ *FP = fopen(・・・); X_Proc(FP);}
> X_Proc(FILE **FP){fprintf(*FP, "%s\n", "ABC");}
>
> 現状ではX_Procでファイル書込を行った際にファイルポインタが破壊されて
> いるようです。
そういう問題ではないですね。
> ファイルポインタを引数として渡すことはあまりなくて、
っていうか、こんな渡し方をしなきゃいけない場合は考えられないので、
そもそも設計がまちがっているのでしょう。
まず、fopenで帰ってくる値(ポインター)が指す実体はどこにあるのか
想像してみましょう。
# いったいどんな本を読んで勉強したのだろうか。
0009Kusakabe Youichi
NGNG> >>5
> デフォルトの名無しさん wote:
> >いつもお世話になっております。
>
> そういうことにしたいのですね。
引用の仕方がちがいますね。
0010デフォルトの名無しさん
NGNGアヒル本とK&Rをよんで勉強してきました。
0011デフォルトの名無しさん
NGNG> 早速ですが、ファイルポインタを引数として関数に渡そうとしてコーディング
> してみたのですが、どうも上手くいきません。
「どうも」じゃなくて「どう」上手くいかねぇのよ。
> 現状ではX_Procでファイル書込を行った際にファイルポインタが破壊されて
> いるようです。
んなこたぁない。
fopen()の引数だけ直して#include <stdio.h>つけたらちゃんと動いたぞ。
省略したところに別のバグがあるんだろ。
> ファイルポインタを引数として渡すことはあまりなくて、どのようにすれば
> よいのかわかりません。
変すぎ。
00125
NGNG以前、UNIXの環境でファイルポインタを引数にしようとした時、
『ダブルポインタにしないと渡せない』と言われてから、そういうものだと
思っていましたが、VC++では違うようですね・・・
みなさんの意見を参考に試してみます。
有り難うございました。
0013Kusakabe Youichi
NGNG> みなさん、有り難うございます。
> 以前、UNIXの環境でファイルポインタを引数にしようとした時、
> 『ダブルポインタにしないと渡せない』と言われてから
「だれに」いわれたのですか?
0014デフォルトの名無しさん
NGNG> 以前、UNIXの環境でファイルポインタを引数にしようとした時、
> 『ダブルポインタにしないと渡せない』と言われてから、そういうものだと
> 思っていましたが、VC++では違うようですね・・・
>>5が完全に誤解してるか、思いっきりだまされてるか、そう言った奴も完璧な厨房か。
>>5の誤解に1000ポインタ。
0015もふ
NGNGプログラムをつくってます。ひとつのデータが下のような構造体です。
typedef struct {
int x;
long y;
} mydata;
なにかアライメントやエンディアンとかの問題があるらしいので
mydata buf;
fread( &buf, sizeof(mydata), 1, fp );
fwrite( &buf, sizeof(mydata), 1, fp );
みたいなのは駄目らしいのですが、具体的にどう回避すれば
よいのでしょうか?
アライメントの問題のほうは
fwrite( &(buf.x), sizeof(int), 1, fp );
fwrite( &(buf.y), sizeof(long), 1, fp );
とか分ければいいのかな? と思うのですが
エンディアン云々のほうは回避策がわかりません。。。
そもそも、longとかのビット数が違ったら駄目な気もするし。。。
なにかこういうときの定番の方法とかあったら教えてくださるとうれしいです。
0016デフォルトの名無しさん
NGNG0018デフォルトの名無しさん
NGNGアライメントの問題は、そのように構造体のメンバを
ひとつずつ処理しればOKですよ。
エンディアンの問題は、たとえば、こういうように一バイトずつ
読み書きするしかないでしょうね。
void write_long(FILE* fp, long n)
{
int i;
for (i = 0; i < 4; i++ ) {
fputc(n & 0xff, fp);
n >>= CHAR_BIT;
}
}
0019デフォルトの名無しさん
NGNG書く、という手もあるよ。
0020デフォルトの名無しさん
NGNGlongのサイズの問題は、保証されてる32ビットしか使わない
ようにすればよいと思う。
0021Kusakabe Youichi
NGNG> なにかこういうときの定番の方法とかあったら教えてくださるとうれしいです。
対象環境が1つか2つだったら#ifで対処、
無数の環境を意識するんだったら、
freadでcharの配列に読んで1バイトずつ処理するか、
ascii化して書くかどちらか。
0022tai
NGNGひとつの関数で使ったローカル変数に入った値をプログラム全体での変数に代入したいのですが、どのようにしたら良いのでしょうか?
よろしくおねがいします。
0023デフォルトの名無しさん
NGNG0024Kusakabe Youichi
NGNG> ひとつの関数で使ったローカル変数に入った値をプログラム全体での変数に
> 代入したいのですが、どのようにしたら良いのでしょうか?
ふつうに代入する。
0025もふ
NGNGなるほど、0xffと & を取ればエンディアンに関係なくいちばん「桁」の
小さいところのバイトを取れるんですねー。
いちおう、こんなのでやってみます。。。
int read_mydata( FILE *fp, mydata *dp ){
if( read_int( fp, &(dp->x) ) == 0 ) return 0;
if( read_long( fp, &(dp->y) ) == 0 ) return 0;
return 1;
}
int read_long( FILE *fp, long *l ){
int i, c;
*l = 0;
/* 32bitまで */
for( i=0; i<4; i++ ){
if( ( c = fgetc( fp ) ) == EOF ){
return 0;
}
*l |= c;
*l <<= 8;
}
return 1;
}
0026Kusakabe Youichi
NGNG> いちおう、こんなのでやってみます。。。
> int read_mydata( FILE *fp, mydata *dp ){
> if( read_int( fp, &(dp->x) ) == 0 ) return 0;
> if( read_long( fp, &(dp->y) ) == 0 ) return 0;
> return 1;
> }
エンディアンの問題はなんとかなっても、構造体のメンバーの間に
隙間があったらどうするつもりなの?
0027デフォルトの名無しさん
NGNG>エンディアンの問題はなんとかなっても、構造体のメンバーの間に
>隙間があったらどうするつもりなの?
メンバをひとつずつ処理してるから、問題ないのでは?
0028Kusakabe Youichi
NGNG> >エンディアンの問題はなんとかなっても、構造体のメンバーの間に
> >隙間があったらどうするつもりなの?
>
> メンバをひとつずつ処理してるから、問題ないのでは?
「処理」とは?
0029デフォルトの名無しさん
NGNG>「処理」とは?
if( read_int( fp, &(dp->x) ) == 0 ) return 0;
if( read_long( fp, &(dp->y) ) == 0 ) return 0;
read_int(),read_long()こういう関数をコールして、
ファイルから、int,longの単位で読み出してることです。
0030デフォルトの名無しさん
NGNG| |
| ここでボケて |
|____ ____|
∧,,∧ ||
⊂ミ.,,゚Д゚彡つ
0031Kusakabe Youichi
NGNG> >「処理」とは?
>
> if( read_int( fp, &(dp->x) ) == 0 ) return 0;
> if( read_long( fp, &(dp->y) ) == 0 ) return 0;
>
> read_int(),read_long()こういう関数をコールして、
> ファイルから、int,longの単位で読み出してることです。
ってことは、書くときにもそうするってことですよね?(そこが重要)。
0032デフォルトの名無しさん
NGNG>ってことは、書くときにもそうするってことですよね?(そこが重要)。
ああ。
読むときに、int,long単位でやってるから、書き込みも
同じに処理するって、思い込んでましたよ。
初心者相手には、そういう配慮をしたほうがいいですかね。
0033もふ
NGNGもちろん、書くときにも同じ順番でひとつずつ write_int , write_long などとやりますが、
それなら大丈夫ですよね?
0034Kusakabe Youichi
NGNG> ああ。
> 読むときに、int,long単位でやってるから、書き込みも
> 同じに処理するって、思い込んでましたよ。
まあ、自分でやるときはそうするから...は甘いですね:)
> 初心者相手には、そういう配慮をしたほうがいいですかね。
配慮というか「警戒」というか。
0035Kusakabe Youichi
NGNG> もちろん、書くときにも同じ順番でひとつずつ write_int , write_long などとやりますが、
> それなら大丈夫ですよね?
その読む関数と書く関数がつねにセットになっていて不整合がなく、
片方だけ修正しわすれることがなければね。
そのためにはなるべく近くに置くのがコツ。
(#defineマクロなどで共通化もはかる)
0036デフォルトの名無しさん
NGNGたいていのアーキテクチャでは整数を表現するのに2の補数を使ってるけど、稀に1の
補数を使ってるアーキテクチャもある。その場合には >>25 だと NG だね。
(ま、そんなアーキテクチャを使う予定がなければ、気にしないのが正解だけどさ)
あと、構造体ごとに read_xxx 関数を作ると面倒になるから、一つ抽象化したほうがいい
と思われ。printf() みたく
(1) ダンプするデータを指定する文字列 (c で char, i で int, l で long とか)
(2) 実際のデータ
を列挙して処理できる関数を、一つ用意するとかね。
inline int read_mydata(FILE *fp, mydate *dp)
{
unpack(fp, "il", &dp->x, &dp->y);
}
たとえば、こんな感じで。これだけだと有り難味が実感できないかもしれんが、ユーザ定義の
コールバック関数を取れるように (1) を拡張したりすると、データが複雑になったときの保守
性に差が出てくる。
0037デフォルトの名無しさん
NGNG>稀に1の補数を使ってるアーキテクチャもある。その場合には >>25 だと NG だね。
1の補数でもOKのように見えますけど、どこがいけないんでしょうか?
0038デフォルトの名無しさん
NGNG2の補数の機械で、-50を保存
そのデータを1の補数の機械へもっていき、読みこむ
とどうなるか、というお話ではないだろうか?
0039デフォルトの名無しさん
NGNGなるほど。
いろいろあるなぁ。
互換性を考えると、テキストデータが一番いいかな。
(って、文字コードもいろいろあるのか)
0040デフォルトの名無しさん
NGNGクリップボードに移すにはどのようにやればよいのでしょうか?
0041デフォルトの名無しさん
NGNGGeneric な C では「クリップボード」は定義されてないから、何とも。VC の話なら VC スレで聞いたほうが
いいと思うぞ。
0042デフォルトの名無しさん
NGNGなんか下記のようなサンプルがあるんだけどこれを独立したcソースの関数とすると、
コンパイル後に「HGLOBALは定義されていない識別子です」とでてエラーがでます。
定義はどこですればいいのでしょうか?
あとCではクリップボードはつかわないほうがいいのですか?
void SetClipText(void)
{
HGLOBAL hText;
char *pText;
hText = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, 4);
pText = GlobalLock(hText);
lstrcpy(pText, "abc");
GlobalUnlock(hText);
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_TEXT, hText);
CloseClipboard();
}
0043デフォルトの名無しさん
NGNGヘッダをインクルードしなさい。
てか、C言語の質問とちゃうでしょ。
0044ネタ?
NGNGゲラゲラ
0045デフォルトの名無しさん
NGNG0046デフォルトの名無しさん
NGNG>>8
> っていうか、こんな渡し方をしなきゃいけない場合は考えられないので、
Init_Proc()で開いたファイルストリームを、main()で触りたい場合は?
戻り値で返せってか、まぁその通りなんだが。
> まず、fopenで帰ってくる値(ポインター)が指す実体はどこにあるのか
> 想像してみましょう。
これはマジか?ネタか?
5をひっかけて喜んでるのか?
想像の入る余地があんのかよ。
> # いったいどんな本を読んで勉強したのだろうか。
あんたがな。
0047デフォルトの名無しさん
NGNG>これはマジか?ネタか?
>5をひっかけて喜んでるのか?
なんのことだろ。
日下部氏が間違ってるようには見えないけど?
0048デフォルトの名無しさん
NGNG・fopenで帰ってくる値(ポインター)が指す実体
> fopenが返す値(FILE*型)の実体は、標準関数が内部管理する領域(FILE型)
・fopenが返した値を格納した領域
> Init_Proc(FILE** FP)へ引数としてアドレス(FILE**型)が渡された、
main()内のFILE*型変数FP。
で、何が問題?
fclose()してない事?
0049デフォルトの名無しさん
NGNG普通、構造体で包んで渡したりするとおもうよ。
FILE**が出てくるソースは、俺はあんまし見たことない。
>47
じゃ、とりあえず、5のどこが間違っているのか、説明してみてよ。
0050デフォルトの名無しさん
NGNG>>49
まぁ、その通りだし、私もそうするけど、5の
> っていうか、こんな渡し方をしなきゃいけない場合は考えられないので、
“考えられない”ってのが言い過ぎだという反例です。
0051デフォルトの名無しさん
NGNGポインタのポインタなんてしないで、
普通に FILE*fpで受け渡しすればいいのでは?
5が動くといっても、無駄に処理を複雑にしてるだけに見えるよ。
0052デフォルトの名無しさん
NGNGとりあえず、その「普通にFILE*fpで受け渡し」してみたコードを載せてみ。
0053デフォルトの名無しさん
NGNG0054デフォルトの名無しさん
NGNG検証の余地なんてないと思うけど、なんで?
なんか勘違いしてない?
005546
NGNGそれに必然性があるか否かはともかく、
5のソースではFILE*型変数FPの実体はmain()内にあるのさ。
で、Init_Proc()でfopen()してる。
さて、Init_Proc()からmain()に戻ったとき、
FPの値は何やろね?
という事を、52は言いたいのだと思われ。
あんまこんな事をつついていると、元凶から
“そもそも設計がまちがっているのでしょう。”
とか返されそうでやだな。
0056デフォルトの名無しさん
NGNGp = malloc(sizeof(char)*256);
これをコンパイルするとエラーになります。
エラー E2034 testf.cpp 8: 'void *' 型は 'char *' 型に変換できない(関数 main() )
コンパイラのせい?
0057デフォルトの名無しさん
NGNGコンパイラのおかげです。
0058デフォルトの名無しさん
NGNGなんで、p=(char *)malloc(256);
にしないの?
0059デフォルトの名無しさん
NGNG知らなかったから。
ありがと。無事コンパイルできたよ
0060デフォルトの名無しさん
NGNG0061デフォルトの名無しさん
NGNGc++コンパイラでコンパイルしたんじゃない?
0062デフォルトの名無しさん
NGNGそう、コンパイラはBorland C++ です。
006361
NGNGc++はある型をtypeとすると
type*からvoid* へは普通にキャストできるけど
void*からtype* へのキャストは明示的に(type*)とキャストしないと
コンパイラに叱られる。
0064デフォルトの名無しさん
NGNGと知ったかぶってみる板違い。
0065デフォルトの名無しさん
NGNGWinで\nてやるとWin用の改行コードを吐きますよね?
それを、無理矢理UNIX系OSの改行コードを吐かせる方法ってありますか?
0066デフォルトの名無しさん
NGNG0067デフォルトの名無しさん
NGNGそれ以前に new 使うと思うが。(これならキャスト不要だよ)
0068デフォルトの名無しさん
NGNG良く分かってないのに“吐く”だなんて言葉使うな。
“\nてやると”ってなんだよ!
“テキストモード”と“バイナリモード”で調べろ。
阿呆
0069デフォルトの名無しさん
NGNG0070デフォルトの名無しさん
NGNGあ
ほ
。
0071デフォルトの名無しさん
NGNG0072名無しさん@お腹いっぱい。
NGNGUNIXでもDOSでも吐きますが何か?
>それを、無理矢理UNIX系OSの改行コードを吐かせる方法ってありますか?
何を無理するんでしょうか、すいませんが私も「吐く」の意味が把握出来ません
0073自作自演
NGNG0074デフォルトの名無しさん
NGNGバイナリモードでオープン
0075デフォルトの名無しさん
NGNG> “テキストモード”と“バイナリモード”
しかも工房呼ばわり。
ところで無理矢理ってイイね。
無理矢理履かせる、黒ニーソクスを
無理矢理穿かせる、タイトミニを
0076デフォルトの名無しさん
NGNG0077デフォルトの名無しさん
NGNG> しかも工房呼ばわり。
そりゃあ 65=69 で、質問したら馬鹿にされて悔しかったんだろ(w
0079デフォルトの名無しさん
NGNG自分で「吐きます」とつかっているじゃないか。
0080opopi
NGNGこういうエラーがでるんですけど、なぜかわかりませんか?
ちなみにproject−設定でplotc2fをいれたんですができません
0081Kusakabe Youichi
NGNG> 厨房見るとハイエナの如くハンターが集まってくるね(^^;)こわっ
っていうか「正しい教え方」どころか、
自己満足のために相手しているみたいだし。
私みたいに正しく対処すればいいのにね。
0082デフォルトの名無しさん
NGNG'plot10.h': No such file or directory
って自分で書いてるじゃねぇか。
> ちなみにproject−設定でplotc2fをいれたんですができません
意味不明
正しい対処とやらは誰かさんがしてくれるじゃろ。
俺は毒づくだけ。
阿呆
0083デフォルトの名無しさん
NGNG0084Kusakabe Youichi
NGNG>'plot10.h': No such file or directory
> こういうエラーがでるんですけど、なぜかわかりません
考えなさい。
0085デフォルトの名無しさん
NGNGと言うかwarez臭いな(w
0086デフォルトの名無しさん
NGNGバグ?
while(...) {
...
} while(...);
0087デフォルトの名無しさん
NGNGなにが言いたいのかよくわからないな。
Whileが2つあるだけではないのか?
while(1) i++;
while(1) ;
を、君はエラーにしてほしい、とでも言うのか?
0088デフォルトの名無しさん
NGNGどこかで見たな、その質問。
ネタか?ツマラソ
0089デフォルトの名無しさん
NGNGネタかも知れんが、一応解説しといてやる。
structとかと違って複文ブロックのあとに;は不要。
0090デフォルトの名無しさん
NGNGdog
cow
hors
dog
bird
cat
こういう感じで、一行に単語がひとつ書いてある
テキストファイルを読み込んで、重複してある
単語を取り除いて、ユニークな単語数を数えると
いうプログラムを作りました。
いったんは完成したのですが、いろいろいじっている
うちに、うまく動かなくなって、元にもどせなくなって
しまいました。
どうすれいいですか?
009190の続き
NGNG#include <stdlib.h>
#include <time.h>
#include <string.h>
char *table[1000];
int table_tail = 0;
void table_add(char *s)
{
char *p;
p = malloc(strlen(s)+1);
if (p == NULL ) {
exit(1);
}
strcpy(p, s);
table[table_tail] = p;
table_tail++;
}
void word_count()
{
int i, j;
int kazu;
int flag;
kazu = 0;
j = 0;
start:
flag = 0;
for (i = j; i < table_tail; i++) {
if (strcmp(table[j], table[i]) == 0) {
flag = 1;
}
}
if (flag == 1 ) {
table[j] = NULL;
}
j++;
if( j >= table_tail-1 ) {
goto end;
}
goto start;
end:
for (i = 0; i < table_tail; i++) {
if (table[i] != NULL) {
kazu++;
}
}
printf("%d\n", kazu);
}
009291の続き
NGNGint main()
{
char s[256];
char *p;
FILE *fp;
fp = fopen("word.txt","r");
if (fp == NULL) {
exit(1);
}
for (;;) {
p = fgets(s,256,fp);
if (p == NULL) {
goto end;
};
table_add(s);
}
end:
word_count();
return 0;
}
0093デフォルトの名無しさん
NGNGソース読むのウザイ、後でみてやるかもしれない。
> いったんは完成したのですが、いろいろいじっている
> うちに、うまく動かなくなって、元にもどせなくなって
> しまいました。
ソースは履歴を取っとけ。
“いったんは完成した”というのなら、
そういった時点でな。
0094デフォルトの名無しさん
NGNG>うちに、うまく動かなくなって、元にもどせなくなって
>しまいました。
>どうすれいいですか?
CVSを導入しましょう。
0095デフォルトの名無しさん
NGNG0096デフォルトの名無しさん
NGNGでも、お前がgoto使ってる個所は総て、forかwhileループ、
およびbreak文で書ける、というか俺ならそうする。
>うまく動かなくなって
何が問題が書け!
コピペしてmakeして実行してみろと?
しかもバグ付きソースを!?
アクセス違反が起きる、というなら、
strcmp(table[j], table[i])にNULLを突っ込んでいるのが原因やろ。
阿呆
0097デフォルトの名無しさん
NGNGブレイク!
0098デフォルトの名無しさん
NGNGwhile forとbreakで十分。
0099デフォルトの名無しさん
NGNGなんの目的でやってるの?
プログラミングのお勉強?
それなら、とりあえず goto なくせ。
必要ない flag も使うな。
問題があるのは strcmp(table[j], table[i]) のところで
NULL を渡すことがあるのがいけんのだと思う。
0100デフォルトの名無しさん
NGNG010199
NGNG■ このスレッドは過去ログ倉庫に格納されています