トップページ⇒tech
1001コメント281KB

C言語なら俺に聞け! Part 62

■ このスレッドは過去ログ倉庫に格納されています
0001v(^o^i)dNGNG
まず問題を冷静に吟味してCの話か否かをはっきりさせてから質問しましょう。
質問する前には最低限検索を。

GUIなどの標準Cではできない事の質問は使用している開発環境のスレへGo! (←ここ注目)
ソース丸投げ、宿題、書籍 は専門の別スレがあるのでそこへさようなら。

コンパイラを探しているなら >>2-13 を。
C machineはCに非ず
上記を逸した場合の結果は激しく未定義だYO!

C FAQ 日本語訳
http://www.catnet.ne.jp/kouno/c_faq/c_faq.html
Cプログラマ必読 ・プログラミング言語C(通称 K&R)
http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/

C言語なら俺に聞け! Part 61
http://pc2.2ch.net/test/read.cgi/tech/1057677056/
0153デフォルトの名無しさんNGNG
>>152
すげぇ、そんな考え及びもしなかったぜ・・・
0154デフォルトの名無しさんNGNG
>>152
NULLじゃないだろう
0155デフォルトの名無しさんNGNG
>>154
すまそ、Cから数年離れてるもので・・・
a[5]='\0';
なのかな
0156150NGNG
>>152
じゃあ、初期化してないとどうなるんですか?
0157デフォルトの名無しさんNGNG
むかし
char str[BUFSIZ]を初期化しないで表示してみるスレ
なんてのがあったな
0158デフォルトの名無しさんNGNG
>>156
static な変数なら 0 で初期化されるが、
自動変数の場合はどうなってるか分からない。
毎回違う値が入ってる可能性も大きい。
0159デフォルトの名無しさんNGNG
>>156
「変化しない」って言葉がわからない?
初期化してようがしてなかろうが今は関係ない。
0160_NGNG
http://homepage.mac.com/hiroyuki44/jaz08.html
0161デフォルトの名無しさんNGNG
>>148
>char* pData
>だと、char*型の pDataオブジェクトっぽく見えて良い感じだと思うのですが
確かにその通り。
でも、複数宣言する場合はそうはいかないよね。
char *pData, *pData2; の方が見栄えがいい。
まあ、typedef char* pchar; で型定義して
pchar pData, pData2; にすればいいんだけど。
これは個人の好みの問題だね。
0162デフォルトの名無しさんNGNG
>150はその程度のことをなぜ自分で試さないんだ?
数行で済む話だろ。
0163デフォルトの名無しさんNGNG
>>161
複数宣言なんて殆どしないなぁ。
どうしても複数宣言したくなった時のみするけど、
その場合は確かに * は変数にくっつけて書く。
0164デフォルトの名無しさんNGNG
こんばんわ。
ちょっとわからない事があったので、ご意見を聞かせてください。

data1.txt に例えば
x y z
1 1 10
1 2 12
1 3 17
:
:
のようなn行3列のテキストデータがあったとします。
ここでdata2.txtには
x y
1 3
1 5
3 9
6 41
:
:
と n行2列のデータがあったとします。ここで私は data1.txt から
data2.txt の x y と一致する行だけ抜き出したいのですが上手くいきません。
どこを直したらよいか教えていただけませんか?
0165164NGNG
ちなみにこれがためしに書いてみたソースですが
実行しても一行も出力されませんでした。


#include <stdio.h>
#include <string.h>

main(int argc,char *argv[])
{
FILE *file1;
FILE *file2;

char buf1[BUFSIZ];
char buf2[BUFSIZ];
char *p;

file1 = fopen(argv[1],"r");
file2 = fopen(argv[2],"r");

while(fgets(buf1,sizeof(buf1),file1)!=NULL){
while(fgets(buf2,sizeof(buf2),file2)!=NULL){
if( ( p = strstr(buf1,buf2)) !=NULL) {
puts(buf1);
}
}


}
0166デフォルトの名無しさんNGNG
>165
・fgetsで得た文字列がどうなってるか
・file2が終端に達した後どうなるか
0167デフォルトの名無しさんNGNG
同じxyの組合せが1組しかなくて、それぞれのファイルが同じようにソートされてる場合
while(fgets(buf2,sizeof(buf2),file2)!=NULL){
while(fgets(buf1,sizeof(buf1),file1)!=NULL){
if(strncmp(buf1,buf2,strlen(buf2)-1) == 0) {
fputs(buf1, stdout);
break;
}
}
}
0168デフォルトの名無しさんNGNG
#include <stdio.h>
#include <string.h>

main(int argc,char *argv[]){
  FILE *file1;
  FILE *file2;

  char buf1[BUFSIZ];
  char buf2[BUFSIZ];

  file1 = fopen(argv[1],"r");
  file2 = fopen(argv[2],"r");

  fgets(buf1,sizeof(buf1),file1);// 最初のx yの行を読み飛ばす

  while(fgets(buf1,sizeof(buf1),file1)!=NULL){
    int x1,y1,z1;
    sscanf(buf1,"%d %d %d",&x1,&y1,&z1);
    rewind (file2); // file2を最初から読み直す
    fgets(buf2,sizeof(buf2),file2); // 最初のx yの行を読み飛ばす
    while(fgets(buf2,sizeof(buf2),file2)!=NULL){
      int x2,y2;
      sscanf(buf2,"%d %d",&x2,&y2);
      if( (x1 == x2) && (y1 == y2) ){
        printf("%s",buf1);
      }
    }
  }
}
0169164NGNG
>>166
>・fgetsで得た文字列がどうなってるか
>・file2が終端に達した後どうなるか

え〜と、
fgetsで得た文字列には改行コードがある。
よって改行コードも文字列の判定に入ってきてしまうから、
改行コードをはずさないと意図した通りにならない、ってことでしょうか?

file2が終端に達すると...?
え〜と、file2のwhileが終わってfile1の次の行を読み込んだ後、
またfile2を読み始めると思うのですが。

うーん。まだよくわからないです。すみません。
0170デフォルトの名無しさんNGNG
while(FILE1が終端まで行ってるか?){
 FILE1から読み込み
 while(FILE2が終端まで行ってるか?){
   FILE2から読み込み
 }
}
FILE1から1つめのデータを読み込んで、FILE2上の全てのデータで含まれているかどうかチェックする
(この時点でFILE2上にはデータが残っていない)

FILE1から2つめのデータを読み込むと、FILE2には「もうデータが無い」と判断し誤動作する、というわけで。
0171デフォルトの名無しさんNGNG
rewindがポイント
0172170NGNG
厳密には、「誤動作」じゃないので。

>>171がいってるとおり、rewind manpageで検索して見てくれ。
0173164NGNG
>>170
なるほど。
2つ目の while は一回終端まで行ったので
次のループでは既にストリームが終わってしまっているわけですね。
と、なると>>167で教示していただいたループも上手くいかなそうに見えるのですが...
0174デフォルトの名無しさんNGNG
strstrでのチェックの場合、改行を取り去っても
buf1が"1 10 5"
buf2が"1 1"
や
buf1が"2 21 1"
buf2が"1 1"
等で、問題が発生する
従って>>168のように数値でチェックした方が良いだろう
0175デフォルトの名無しさんNGNG
数値とは一言も書いてない
0176164NGNG
なるほどよくわかりました。
レスしてくれたみなさん、どうもありがとうございます。
とても勉強になりました。
0177デフォルトの名無しさんNGNG
はいはい。お疲れさまでした >> 175
0178デフォルトの名無しさんNGNG
やり方自体がショボ杉
0179デフォルトの名無しさんNGNG
夏房的しつもんですが、
sprintf()で渡したエリア以上に文字列を出力させた場合、
エリアを壊しますよね??
0180デフォルトの名無しさんNGNG
>>179
さぁ。直後がmallocで正当に確保された領域だったりメモリマップドファイルだったりすることも考えられる。
0181デフォルトの名無しさんNGNG
double d;
for(d=0.0;d<pow(FLT_RADIX,DBL_MANT_DIG);d+=1.0){}
とあった時、pow(FLT_RADIX,DBL_MANT_DIG)回だけループするのでしょうか?
それとも、途中で、丸められてしまう事も、あるのでしょうか?
0182フラウボウNGNG
http://life.fam.cx/a008/



0183デフォルトの名無しさんNGNG
>>181
1. double をループカウンタにしないのが吉。
  数値誤差が溜まって、正確にループできないことが頻繁にある。

2. 関数の結果を一時変数に入れて、それをループのリミットとすること。
  何度も pow を呼ぶのは非効率。

pow の結果が整数なら、

int i;
int limit = (int)(pow(...) + 0.5);
for(i = 0; i < limit; i++) { ... }

とするべし。
0184デフォルトの名無しさんNGNG
>>161
関数の引き数で複数宣言出来たか?

# 関数の引き数の場合と書いてあるが?
0185デフォルトの名無しさんNGNG
掘り出してすまんが、>>150 は代入と初期化を混同していると思われ。
そもそも C だと文字列の代入なんて普通には出来ない。
初期化の指定なら a[9] は '\0' になる。
0186デフォルトの名無しさんNGNG
>>184
関数の引数と、そうで無い場合で使い分けるのはもっと気持ち悪いよ
0187デフォルトの名無しさんNGNG
文字列の初期化なんてどうせ動作環境決まっているから
memset(str,0,sizeof(str));
ですましてる。
0188デフォルトの名無しさんNGNG
文字列の初期化なんて、str[0] = '\0';で充分。

>>183
doubleの上限までループしようと言う無茶な181なんだから
精度云々以前にintが使えない罠。
で、doubleの有効桁数は10進で20桁もないので途中で1足しても値が増えなくなる。
0189デフォルトの名無しさんNGNG
>>187
どういう意味?
0190デフォルトの名無しさんNGNG
>>185の言う初期化は、宣言時に初期値を指定することだと思われ
0191デフォルトの名無しさんNGNG
>>188
あ、そこまでループするのか。
pow の中身見てなかった。
なるほど。そのうち精度が悪くなって足しても d の値が変わらなくなるな。
0192デフォルトの名無しさんNGNG
>>188,191
doubleの上限じゃない。
1足して値が変わる上限。
0193デフォルトの名無しさんNGNG
>181
その値の場合においては問題ない
0194181NGNG
>>183-193
返事が遅れて、ごめんなさい。
何か、とても書き方が悪かったようで…
>>193さんが、問題ないと言われてますが、念の為、もう1度、お願いします。
ようするに、知りたい事は、3つ程あるのですが、
「doubleの初期値を0.0にして、1.0ずつ足せば、仮数部も1ずつ増えるのか?」
と言う事と、
「仮数部を意図的に1ずつ増やした場合、
 仮数部の限界がくるまで指数部の値が、かわる事はないのか?」
と言う事と、
「指数部に余裕がある時に、
 仮数部の限界の値と、仮数部の限界に1を足した値を比較しても
 (FLT_ROUNDS等に関係なく)正しい結果が得られるのか?」
と言う事の3つです
知ってる方は宜しく、お願いします。
0195デフォルトの名無しさんNGNG
doubleの表現形式って仕様で決まってたっけ?
0196デフォルトの名無しさんNGNG
>>194
仮数部って整数じゃないよね?
0197デフォルトの名無しさんNGNG
IEEE754の浮動小数は仮数部が0.5<=x<1を満たすんじゃなかったかな?
指数部の値によっては上記の条件を満たさないかもしれないが
0198デフォルトの名無しさんNGNG
>>196
はい、仮の数です。
だから、単純に1.0を足しても仮数部の内部が1増えるとは限りません
が、>>194に書いた事は、1つ目と2つ目は、出来そうな気がするし、
計算精度的に、出来なければ、おかしい気もします。
また、3つ目は、出来ても、出来なくても、何となく納得出来るので、
仕様上、どのように決まってるのかなと思いまして…。
0199181NGNG
>>198は自分が書いたものです

>>197
と言う事は、どう言う事になるのでしょうか?
0200デフォルトの名無しさんNGNG
200ゲット
C言語なら俺に聞け!
0201デフォルトの名無しさんNGNG
>>199
What Every Computer Scientist Should Know About Floating-Point Arithmetic
http://docs.sun.com/source/806-3568/ncg_goldberg.html
0202デフォルトの名無しさんNGNG
構造体とクラス(C++)の違いを教えてください
0203デフォルトの名無しさんNGNG
>>202
なんでここで聞くの?
0204デフォルトの名無しさんNGNG
>>202
スレ違いです。
0205sageNGNG
すまん
0206181NGNG
>>201
分かりませんでした…。(T_T)
最初の方に、指数部が同じなら
仮数部の値は保証されるような事が書いてありましたが、
それが、途中のIEEE754や、最後の方に書いてあった、
C99の仕様と、どのような関係があるのか、全然分かりませんでした…。
誰か、英語の出来る人、教えて下さいませ。m(_ _)m
0207181NGNG
時間が時間なので寝ますが、
それでも宜しければ、レスお願いします。
0208デフォルトの名無しさんNGNG
>>179
壊れます
>180の答えは無視してもいいです
0209デフォルトの名無しさんNGNG
>>207>>181
なぜ自分で実験しないのかと小一(jr
0210デフォルトの名無しさんNGNG
 | ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
 |  次でボケて!!!   |
 |________|
    ∧∧ ||
    ( ゚д゚) ||
    / づΦ
0211デフォルトの名無しさんNGNG
よしこさんや。メシはまだかい?
0212デフォルトの名無しさんNGNG
あのー、CRC16/CRC32/MD5鍵のアルゴリズムを解説したページ
ご存じでしたら教えてください。

出来れば、概要だけではなく、アルゴリズムと実装の両方が記載されてる
ページをお願いいたします。
0213デフォルトの名無しさんNGNG
C言語のプログラムからシステム日付を設定する方法は
あるのでしょうか?
あるのなら教えていただきたい。
システム日付設定関数とかあるのかな???ネットで検索したが
見つからなかったので。
0214デフォルトの名無しさんNGNG

期間限定!もうお目にかかれない!

http://alink3.uic.to/user/angeler.html
0215デフォルトの名無しさんNGNG
>>213
これ全部見た?
http://www.google.com/search?hl=ja&ie=UTF-8&oe=UTF-8&q=C%E8%A8%80%E8%AA%9E%E3%80%80%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%80%80%E6%97%A5%E4%BB%98%E3%80%80%E9%96%A2%E6%95%B0&lr=lang_ja
0216215NGNG
ごめん、日付の取得じゃなくて設定か。
それは、システムによって違うな。
0217デフォルトの名無しさんNGNG
プラットフォーム依存する話題はヤメレ!!

まあ、どうしても設定したいのであれば、
system("date -s 2003-07-28");
という手もある(windows/linuxどっちでも動くかもね)
0218デフォルトの名無しさんNGNG
あ、ただしlinuxの場合、管理者権限が必要という罠が...
0219デフォルトの名無しさんNGNG
dateをrootにsui(ry
0220デフォルトの名無しさんNGNG
JPEGファイルをコピーする方法を教えてください。

ファイルをfopenでバイナリモードで開き
fgetcで元のファイルを読み込んで、fputcでコピーして閉じたのですが
テキストファイルはうまくコピーできたものの
JPEGファイルはファイルだけが出来て中身がありません。
具体的にはどうすればいいんでしょうか?
0221デフォルトの名無しさんNGNG
>>220
"rb"
0222221NGNG
書き込むんだから"wb"も必要か。
0223デフォルトの名無しさんNGNG
>int hoge ; fgets(buffer , sizeof(buffer) , stdin) ; sscanf(buffer , "%c" , &hoge) ;

char hoge ; scanf("%c" , &hoge) ;

scanf「だけは」使わないくせに
scanfより悪いことを平気でする低脳
0224デフォルトの名無しさんNGNG
>>220
具体的にはどうやったのでしょうか?
0225デフォルトの名無しさんNGNG
すいません、16bitの配列について質問させて下さい。
今、tiff画像の各ピクセルあたりの輝度を
取り出すプログラムを書いているのですがどうも値が間違ってるようなんです。
ちゃんと16bitの値を取り出して出力できているでしょうか?
コードは次のようになっています。

0226デフォルトの名無しさんNGNG
#include <stdio.h>
#include <tiffio.h>
main(int argc ,char *argv[])
{
TIFF *tiff;
uint32 width,height,row,x;
unsigned short int *buffer;
unsigned long int result;

tiff = TIFFOpen(argv[1],"r");

/*画像の幅と高さを取得*/
TIFFGetField(tiff,TIFFTAG_IMAGEWIDTH,&width);
TIFFGetField(tiff,TIFFTAG_IMAGELENGTH,&height);

buffer = (unsigned short int *)malloc(TIFFScanlineSize(tiff));

for (row = 0; row < height; row++) {

/*tiff から一行読み出して buffer に格納る。row で何行目かを指定。0は画像の番号。*/
/*読み出した配列は 16bit の整数データを要素に持つ */

TIFFReadScanline(tiff, buffer, row, 0); 

for(x=0;x<width;x++){
result = * ((unsigned short int *)(buffer + x));
printf("%d %d %u \n",row,x,result);
}
}
}
0227デフォルトの名無しさんNGNG
フローチャートを作るとき、四角の中身の処理はC言語で書くんですか?
それとも、日本語で説明するんですか?
0228デフォルトの名無しさんNGNG
JISで標準形式が決まっている
0229デフォルトの名無しさんNGNG
result = * ((unsigned short int *)(buffer + x));
これは
result = * ((unsigned short int *)(buffer) + x);
でないの?
0230デフォルトの名無しさんNGNG
そもそも buffer が unsigned short int * だろう。
malloc の cast も無駄。
0231225NGNG
>>229
間違ってますでしょうか?

>>230
malloc() に void で確保させても結果に変化はないと思うのですが。
0232デフォルトの名無しさんNGNG
>>231
実際に、printfではどう表示されているの?
それと本来ならどう表示されるはずなの?
0233デフォルトの名無しさんNGNG
>>229
言うだけ無駄な相手だったな
0234デフォルトの名無しさんNGNG
endianは大丈夫なのか。
0235デフォルトの名無しさんNGNG
つーか、ちゃんとタグの解析してるのかな?
0236225NGNG
>>232
実行結果は、
0 0 43
0 1 68
:
:
という感じで、一見すると正しい値が得られているようなんですが、
画像の輝度を全て得てからグラフツールでプロットすると
ただランダムな値が出力されているようにしか見えないんです。

>>234
endian がおかしいのでしょうか。
未熟で判断できません。すみません。
0237225NGNG
>>235
TIFFGetField(tiff,TIFFTAG_BITSPERSAMPLE,&cps);
TIFFGetField(tiff,TIFFTAG_SAMPLESPERPIXEL,&bpc);

別のプログラムで、この2行を加えて画像のbitは確認しています。
0238デフォルトの名無しさんNGNG
最初の文字をxに変えるプログラムなんですが、
何処がおかしいか教えて下さい。
//includeは省略
char *mutation(char *str){
char *str1;int l;int i;

l=strlen(str);
str1=(char *)malloc(l*sizeof(char));
*str1='x';
for(i=1;i<l;i++){
*(str1+i)=*(str+i);
}
return str1;
}

int main(){
char *str;char *str1;

puts("文字列を入力して下さい!");
gets(str);
str1=mutation(str);
puts(str1);
return 0;
}
0239デフォルトの名無しさんNGNG
mallocのサイズが\0の分だけ足りない
\0を移してない
0240デフォルトの名無しさんNGNG
>*(str1+i)=*(str+i);

str1[i] = str[i];

で済むものを、なんでそんなにひねくる?
0241デフォルトの名無しさんNGNG
>239
レス有難うございます
mallocの行をl+1に変えたけど上手くいきませんでした・・・
0242デフォルトの名無しさんNGNG
>>241
*(str1+strlen(str)+1) = '\0';
これ。
0243181NGNG
やはり、レスが無い…
>>194の質問に答えられる方、
もしくは、>>201の先が書いてある事が分かる方は、
分かるように説明して下さい。お願いします。m(_ _)m

>>209
知りたいのは、自分の環境での動作ではなくて、
規格上での動作だからです
0244238NGNG
解決しました、有難うございます!
main関数で文字列を入力する前に
str=(char *)malloc(BUFSIZ*sizeof(char));
とすると上手くいきいました。
あと、それに加えて>293さんの処理も必要だったみたいです。

>240
私はポインタと配列の違いが良く分かってないDQNなんです
0245240NGNG
>>244
漏れも高卒だから別にいいんだけどよ、
ポインタと配列は違うってとこはコンドーさんつけないほうが気持ちいいぞ。
忘れるな。
0246デフォルトの名無しさんNGNG
俺は逆に、ポインタが配列見たく使えるのがよく分かってない
0247デフォルトの名無しさんNGNG
>>246
こう言うのか?
(A+1)->B == A[1].B ;
0248デフォルトの名無しさんNGNG
>>246
p[i] は *(p + i) のシンタックスシュガー。
両方等価。
0249デフォルトの名無しさんNGNG
>>248
これか?
p[n][m] == m[n[p]] ;
0250デフォルトの名無しさんNGNG
>243
・仮数部は整数値ではない為、1を加算しても仮数部は1ずつ増えない
・仮数部は正規化された小数値なので、指数部は絶対値によって変化する
・overflow等が発生しない限り、指数に応じたEPSILONの加算では計算誤差は発生しない

と2chで回答されて、それを信じるのか(w
0251デフォルトの名無しさんNGNG
>>247
そーそー
>>248
ヘー
ポインタの理解は値を代入するところまでで止まってまつ
どうもありがとうです
0252181NGNG
>>250
レスありがとうございます。m(_ _)m

>仮数部は整数値ではない為、1を加算しても仮数部は1ずつ増えない
はい、最初は、自分も、そう思ったのですが、
良く考えると、基数が幾つであれ、整数を加算した場合は、指数部が0(基数^0)になり、
仮数部も、その整数と同じになるのではないかと思い質問しました
でも、規格上は、1ずつ増えるとは限らないと言う事なのですね。

>・仮数部は正規化された小数値なので、指数部は絶対値によって変化する
なるほど、絶対値で変わる事のですね

>・overflow等が発生しない限り、指数に応じたEPSILONの加算では計算誤差は発生しない
絶対値で指数部が変化すると言う事は、3つ目は大丈夫と言う事ですね

>と2chで回答されて、それを信じるのか(w
うむ…そう言われると…。
■ このスレッドは過去ログ倉庫に格納されています