• ベストアンサー

O_CREAT、O_TRUNC、O_WRONLYはどうして512、1024、1になる?何進数表示?

Win2k+cygwinの環境です。 #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> int main(void){ int c,i,t,w; c=O_CREAT,t=O_TRUNC,w=O_WRONLY; i=(O_WRONLY | O_CREAT | O_TRUNC); printf("c=%d,t=%d,w=%d,i=%d\n",c,t,w,i); return 0; } を実行すると $ ./test c=512,t=1024,w=1,i=1537 となりました。 /cygwin/usr/include/bits/fcntl.hには #define O_ACCMODE 0003 #define O_RDONLY 00 #define O_WRONLY 01 #define O_RDWR 02 #define O_CREAT 0100 /* not fcntl */ #define O_EXCL 0200 /* not fcntl */ #define O_NOCTTY 0400 /* not fcntl */ #define O_TRUNC 01000 /* not fcntl */ #define O_APPEND 02000 #define O_NONBLOCK 04000 #define O_NDELAY O_NONBLOCK #define O_SYNC 010000 #define O_FSYNC O_SYNC #define O_ASYNC 020000 #ifdef __USE_GNU # define O_DIRECT 040000 /* Direct disk access. */ # define O_DIRECTORY 0200000 /* Must be a directory. */ # define O_NOFOLLOW 0400000 /* Do not follow links. */ となっていまして、どうして c=512,t=1024,w=1,i=1537 になるのか分かりません。8進数表になっているのかと推測して #define O_CREAT 0100 よりこれは Ox0100 (8進数表示での0100)の意味なので10進数表示に変換してみましたら 64 となって辻褄が合いません。 #define O_TRUNC 01000 に於いても Ox01000→512 #define O_WRONLY 01 に於いては Ox01→1 でこれだけは実行結果と一致しています。 どうして c=512,t=1024,w=1,i=1537 となるのでしょうか?

  • KaoriM
  • お礼率86% (153/177)

質問者が選んだベストアンサー

  • ベストアンサー
  • terra5
  • ベストアンサー率34% (574/1662)
回答No.1

>/cygwin/usr/include/bits/fcntl.hには 手元のcygwinにはinclude/bitsは存在しませんが、何か特殊なものインストールされているんでしょうか。 おそらくそのファイルは実際には使用されていないと思われます。 こちらでは /Cygwin/usr/include/fcntl.h、およびそこからincludeしている/Cygwin/usr/include/sys/fcntl.hが使われていて、 例えば、 #define O_CREAT _FCREAT #define _FCREAT 0x0200 /* open with file create */ となっていますので、実行結果と一致します。 ちなみに、 find /usr/include -name fcntl.h としてみると、 /usr/include/mingw/fcntl.h というのがあって、これまた違うdefineになっています。 いずれにしろ標準で使われるのは /usr/includeです。 もし、bitsの定義を使用したいなら コンパイル時にincludeパスを指定する必要がありますし、もしかすると標準のincludeを使わない指定が必要かも知れません。 クロスコンパイルでもしないと使わないような気がしますが。

KaoriM
質問者

お礼

$ cd /usr/include $ ctags -R --exclude=mingw としてtagsを作り直してタグジャンプしたら上手くいきました。

KaoriM
質問者

補足

こんにちは。有難うございます。 > >/cygwin/usr/include/bits/fcntl.hには > 手元のcygwinにはinclude/bitsは存在しませんが、何か特殊なものインストールされ > ているんでしょうか。 もう2年くらい経つので知らないうちにいじってしまったのかもしれません。 /usr/include/sys/fcntl.h を直接 $ vim.exe c:/cygwin/usr/include/sys/fcntl.h として開いて、O_CREATを探してタグジャンプしてみましたら0x0200に辿り着きました。 このヘッダより O_WRONLYは1、O_CREATは0x0200、O_TRUNCは0x0400 ですね。 10進数表示に変換すると 1は10進数でも1 0x0200→512、 0x0400→1024 で $ ./test c=512,t=1024,w=1,i=1537 に辻褄がありますね。 一応念のため、先月にOS自体を再クリーンインストールしてCygwinも最新のものをインストールしたWin2kのマシンでも試してみました(下記)。 > ちなみに、 > find /usr/include -name fcntl.h > としてみると、 > /usr/include/mingw/fcntl.h > というのがあって、これまた違うdefineになっています。 -mno-cygwinオプションとか非使用なのに 何故か他のヘッダにタグジャンプしてしまいます。 #include <fcntl.h> ↓ #include </usr/include/fcntl.h> としてもO_CREATからタグジャンプしたら /usr/include/mingw/fcntl.hに飛びまして、 #define _O_CREAT 0x0100 に行き着きました。 findコマンドでその他のfcntl.hを探してみましたら /usr/include/fcntl.h /usr/include/mingw/fcntl.h /usr/include/mingw/sys/fcntl.h /usr/include/sys/fcntl.h がヒットしました。 terra5さんの環境では /Cygwin/usr/include/fcntl.h にタグジャンプされるんですよね。 するとctagsの問題みたいです。。。

その他の回答 (1)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

#1の方のとおりだと思いますが、 それとは、別のところでツッコミ 0で始まる定数は8進数として解釈されます。 0xで始まる定数は16進数として解釈されます。

KaoriM
質問者

お礼

> #1の方のとおりだと思いますが、 > それとは、別のところでツッコミ > 0で始まる定数は8進数として解釈されます。 > 0xで始まる定数は16進数として解釈されます。 有難うございます。 憶えて置きます。

関連するQ&A

  • O_CREAT が効かない

    my$file='test.dat'; sysopen(FH, $file, O_WRONLY|O_TRUNC|O_CREAT) || die $!; test.datが無い場合は作成されるはずですが作成されません。 サーバーの設定が原因でしょうか。 ご存知の方がいらっしゃいましたらご指摘をお願いいたします。

    • ベストアンサー
    • Perl
  • cの標準関数openでNo such a file or directoryが起こっている状況について

    以下のプログラムでエラーとなる要因はどこにあるのでしょうか? #include <fcntl.h> #include <sys\stat.h> #include <sys\types.h> #include <string.h> #include <errno.h> char fname01[64]; //グローバル変数 ここからが、エラーになるプログラム ↓ fh_out = open( &fname01[0], O_CREAT|O_WRONLY|O_BINARY , S_IREAD|S_IWRITE );   if (fh_out == -1){ Application->MessageBox( strerror(errno) , " エラー", MB_OK | MB_ICONEXCLAMATION); ブレイクして、fname01を見た値。c:\\TEST\\d050_g10s187mv174av96bv16.bmp\0

  • exp()が計算されなくて困ってます。

    #include <stdio.h> #include <math.h> #define C_B 13.5e-12 #define C_D 5.5e-12 #define R 100 #define Vb 3e3 /* Breakdown voltage [V]*/ #define Vpp 8e3 #define f 50e3 void main(void){ double C,t=0.0; double dt,tmax,i=0,v=0,bv=0,vc1=0,vc2=0,q1=0,q2=0,w=0,CR; FILE *fp; fp=fopen("test4.txt","w"); C=(C_B*C_D)/(C_B+C_D); tmax=(1/f)*2; dt=tmax/1000; w=2*3.14*f; CR=-1/(R*C_B); while(1){  if(fabs(v-vc2)>=Vb/2){   while(1){    v=(Vpp/2)*sin(w*t);    if(fabs(v-vc2)>=0.1*(Vb/2)){     i=(Vpp/2)*(C_B*w/(pow(R,2)*pow(C_B,2)*pow(w,2)-1))*(R*C_B*w*sin(w*t)-exp(CR*t)+cos(w*t)); この式で使われているexpです。↑ q1=q1+i*dt; q2=q2+i*dt; vc1=i/R; vc2=q2/C_B; } else{break;} fprintf(fp,"%1.10f %1.10f %1.10f %1.10f % 1.10f\n",t,v,i,vc2,q2); t=t+dt; if(t>=tmax)break; } } else{ while(1){ v=(Vpp/2)*sin(w*t); i=C*(v-bv)/dt; q2=q2+i*dt; q1=q1+i*dt; vc1=q1/C_D; vc2=q2/C_B; fprintf(fp,"%1.10f %1.10f %1.10f %1.10f\n",t,v,i,vc2,q2); bv=v; t=t+dt; if(fabs(v-vc2)>=Vb/2)break; if(t>=tmax)break; } } if(t>=tmax)break; } fclose( fp ); } この問題を解決できる人がいたら教えてください。

  • 低水準ファイル入出力

    openを用いてファイル:"test.dat"を開き、そのファイルにbuffに示すような適当なデータを書き込みたいのですが、 下記の様に記述してコンパイル、実行した結果"test.dat"内には何も記述されていませんでした。 自分でも調べてみたのですがどうしても上手くいかず、この場で質問させて頂きます。 ご指摘の程宜しくお願いします<(_ _)> #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> int main(void) {  char buff[]={"test123456789"};  int fd;  fd=open("test.dat",O_CREAT,S_IREAD|S_IWRITE);  if(fd==-1)   {    close(fd);    fd=open("test.dat",O_WRONLY);    if(fd == -1)    {      printf("open error <file>");      return 1;    }   }  write(fd,buff,sizeof(buff));  close(fd);  return 1; } ---- 私の環境 ---- Vine Linux 2.6r4

  • 数十万番目の素数を表示させるプログラム

    以下のようなプログラムを作ってみたのですが、計算結果を出すのに大体10分くらいかかってしまいます。自分の知識の範囲でできる限りの工夫はしてみたのですが、10分はちょっと長すぎなのでもう少し短縮できる方法をどなたか教えてください。よろしくお願いします。 #include <stdio.h> #include <math.h> #include <time.h> int main(void) { int gakuseki,n,no,i,prime,j; time_t t1,t2; printf("学籍番号を入力して下さい。\n"); scanf("%d",&gakuseki); time(&t1); n=gakuseki%100000+900000; printf("%d番目の素数を計算中...\n",n); no=1; if(n==1){ i=2; }else{ i=1; while(no<n){ prime=1; i+=2; for(j=3;j<=sqrt(i);j+=2){ if(i%j==0){ prime=0; break; } } if(prime==1) no+=1; } } time(&t2); printf("%d番目の素数は%dです。\n",no,i); printf("計算時間は%ld秒でした。\n",t2-t1); return 0; }

  • C アルファベットのカウント

    #include<stdio.h> #define N 97 #define M 122 int main(void) { char str[ ]="national university"; int i,h,count; char check; for(h=N-1;h<=M;h++){ h++; char check = (char)h; for(i=0;str[i] != '\0';i++){ if(str[i] = check){ count++; } } printf("%c:%d\n",check,count); } } というコードで、アルファベットをそれぞれ何文字使用しているか調べるつもりだったのですが、結果は次のようになってしまいました。解説お願いします。 a:28 c:56 e:84 g:112 i:140 k:168 m:196 o:224 q:252 s:280 u:308 w:336 y:364 {:392

  • 2進数でのシリアル通信

    シリアルを用いてデータを伝送するプログラムを作りたいのですが、よく分かりません。 10進数では出来たのですが2進数に変換する際に上手く行きません。 シリアル通信のプログラムとして以下を使用しています。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <termios.h> #include <fcntl.h> #include <errno.h> #define BAUDRATE B9600 //hentyou-kaisu per second #define BSIZE 64 //byte size #define CR 0x0D // carriage return int fd; //file descriptor 0:H-nyuryoku,1:H-syuturyoku,2;error struct termios otio; int open_serial_port(char *modem_dev) //modem_dev = serial_dev { struct termios ntio; if ((fd = open(modem_dev, O_RDWR | O_NOCTTY)) < 0) { // O_RDWR=read&write O_NOCTTY= perror(modem_dev); exit (1); } tcgetattr(fd, &otio); //tanmatsu-no-now-settei-syutoku memset(&ntio, 0, sizeof(ntio)); ntio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD; ntio.c_cc[VTIME] = 0; //burst-de-datadenso-wo-timeout-surutameno-timer ntio.c_cc[VMIN] = 1; //jyusin-moji-no-min tcflush(fd, TCIFLUSH); // not read data-wo flash tcsetattr(fd, TCSANOW, &ntio); //new-tanmatsu-settei-watasu return (0); } void close_serial_port(void) { tcsetattr(fd, TCSANOW, &otio); //motono-settei-ni-modosu close(fd); } int main(int argc, char **argv) { char *serial_dev; // char buf[BSIZE]; //data-wo-kakikomu-buffa-no-top-address char *buf = (char *)malloc(sizeof(char)*64); char msg[BSIZE]; int i,j; j=0; if (argc != 2) { fprintf(stderr, "usage : %s serial_dev\n", argv[0]); exit (1); } serial_dev = argv[1]; //device to write e.g. /dev/ttyUSB0 memset(buf, '\0', BSIZE); //m byte memory block no set \0=char-gatano-0 memset(msg, '\0', BSIZE); //syokika open_serial_port(serial_dev); i = 0; while (1) { //infinite loop sprintf(buf, "%d,", i); //printf-wo-buf-ni j = strlen(buf); write(fd, buf, j); //write to modem-device printf("%s\n", buf); sleep (2); //read(fd, msg, BSIZE); //printf("%s\n", msg); i++; if (i >= 10) i = 0; } close_serial_port(); free(buf); exit (0); } 2進数変換プログラムは、 #include <stdio.h> #include <stdlib.h> int main(void) { int i, n; int bits[1024]; int digit, amari; printf("10進数: "); scanf("%d", &digit); n=0; while(digit>=1){ amari = digit % 2; /* 配列変数に順番に代入して */ bits[n++] = amari; digit = digit / 2; } /* 逆順に表示している */ for(i=n-1; i>=0; i--){ printf("%d", bits[i]); } printf("\n"); return 0; } この両者をつなぎ合わせたいのですが、どうすればよろしいでしょうか。

  • 0と1のファイルへの書き込み、出力

    c言語で0と1の乱数を生成し、ファイルに出力したいのですが、出力がおかしくなってしまいます。 正しく0と1をファイルに書き込み、出力するにはどうしたらいいでしょうか。 わかる方いらっしゃいましたら教えてください。 お願い致します。 #include<stdio.h> #include <stdlib.h> #include <time.h> #define max 3000000 #define nrand(n) (int)((double)n*rand()/RAND_MAX) /* 0以上n未満の整数を返す */ int main() {   FILE *Wf;   char W_filename[20];   int *W=(int *)malloc(sizeof(int) * max);   printf("入力ファイル名 : "); scanf("%s",W_filename);   if( ( Wf=fopen(W_filename,"w") ) == NULL ) printf("ファイルを開けません\n");   else   {     for(i=0;i<max;i++)     {     W[i]=nrand(2);     fprintf(Wf,"%d ",W[i]);    }   }   fclose(Wf);   free(W); } 出力が ‰‱‱‰‱‱‰‱‱‰‰‰‰‱‰‱‰‱‰‰ のようになってしまいます。 Wにはちゃんと0か1が入っているみたいなのですが・・・

  • 大学でTurbo C++ 4.0の講義を受けています。その課題で困って

    大学でTurbo C++ 4.0の講義を受けています。その課題で困っています。 問1 画面上に描かれた長方形がキー入力によって原点を中心に回転するアニメーションを実現するプログラムを作成せよ。キーの「1」と「3」で回転角度が増減するようにせよ。 問2 前問のプログラムの図形を画面の中心に平行移動をしてから表示するように改造せよ。結果として画面の中央(320, 240)を中心とした回転移動の角度をキー入力によって増減するようにせよ。 #include <graphics.h> #include <stdio.h> #include <conio.h> #include <math.h> // SIN, COSを使うので必要 #define VN 4 // 頂点数 #define OX 10.0 // 長方形の左上頂点のX #define OY 20.0 // 長方形の左上頂点のY #define WIDTH 50.0 // 長方形の幅 #define HEIGHT 100.0 // 長方形の高さ static double rect_data[VN][2] = { // 長方形頂点配列 { OX, OY }, { OX+WIDTH, OY }, { OX+WIDTH, OY +HEIGHT}, { OX, OY +HEIGHT} }; int main() { int GraphDriver = DETECT, GraphMode; int i, j, k,c,d=0; double new_data[VN][2]; // 変換の結果を入れる配列 double matrix[2][2]; // 回転変換の行列 double theta = M_PI / 6.0; // 回転角度θ=π / 6 registerbgidriver(DOSVGA_driver); // 設定を読み込む initgraph( &GraphDriver, &GraphMode, "") ;  // 画面切替 while(1){ c=getch(); d=d+c; if(c == '1'){ theta = M_PI / d; matrix[0][0] = cos(theta); matrix[0][1] = sin(theta); matrix[1][0] = -sin(theta); matrix[1][1] = cos(theta); for (i = 0; i < VN; i++) { // すべての頂点について for (j = 0; j < 2; j++) { // ここから行列のかけ算 new_data[i][j] = 0.0; for (k = 0; k < 2; k++) { new_data[i][j] += rect_data[i][k] * matrix[k][j]; } } } // これ以後は変換した長方形の表示 moveto((int)(new_data[VN-1][0]), (int)(new_data[VN-1][1])); for (i = 0; i < VN; i++) { lineto((int)(new_data[i][0]), (int)(new_data[i][1])); } cleardevice(); } else if (c == '3') { theta = M_PI / (-d);

  • 基本的なC言語のプログラム

    C言語を勉強中です・・・ 0秒から1.0秒まで0.01秒刻みでデータ(s[i])を配列から表示させていく簡単なプログラムです。 0から0.2までは"30" 0.2から0.4までは"29" 0.4から1.0までは"30"と表示させたいのですが、 全て"30"と表示されてしまいます。 配列の仕方が悪いのでしょうか?? すごく基本的な質問かもしれませんが、どなたか分かる方、よろしくお願いします。 #include <stdio.h> #include <math.h> #define number0 (100) #define h (0.01) #define f1 (30.0) #define f2 (29.0) void main(void){ double s[number0]={0}; int i; double t; for(i=0; i<number0; i++){ t=h*i; if(0<=i<20){ s[i]=f1; } else { if (20<=i<40){ s[i]=f2; } else { s[i]=f1; } } printf("%g %g\n",t,s[i]); } }

専門家に質問してみよう