投稿

5月, 2012の投稿を表示しています

C言語 バイナリファイル書込み fwrite

音声ファイルのwavファイルを用意して、それをバイナリで読み込んで、そのまま別ファイルに書き込むプログラム。 バイナリファイル読込みプログラム に書込みを追加した。 wavファイル読込み&書込みプログラム #include &ltstdio.h&gt #include &ltstdlib.h&gt int main(void){ FILE *fpr,*fpw; int i; unsigned char buf[1000]; int size; fpr = fopen("wav_sample.wav", "rb"); if (fpr == NULL) { printf("error"); exit(EXIT_FAILURE); } fpw = fopen("wav_sample_new.wav", "wb"); if (fpw == NULL) { printf("error"); exit(EXIT_FAILURE); } size = fread(buf, sizeof(unsigned char), 1000, fpr); fwrite(buf, sizeof(unsigned char), size, fpw); fclose(fpr); fclose(fpw); return 0; } 読み込み用と書込み用の処理をそれぞれして、fwrite()で書込みを行っている。このプログラムでは特に表示はせずに新規にファイルを作るだけ。 C言語 ANSI C89 Meadow & MinGW GCC 目次はこちら

C言語 バイナリファイル読込み fread

イメージ
音声ファイルのwavファイルを用意して、それを読み込んで、16進数で表示させてみる。wavファイルは波形編集ソフトのAudacityで作成した。実験なので5サンプルしかない短いもの。 これをStirlingというバイナリエディタで表示させると以下のようになる。ほとんどはヘッダ情報で、ファイルの各種情報が収められている。音の情報は20行の0Cから。16bitモノラルwavなので、ひとつの音は2バイトで構成されている。扱いはリトルエンディアン。 Cのプログラムで同じように表示させてみる。下の例では「wav_sample.wav」という名前のファイルをプログラムと同じ階層に置いている。 wavファイル読込プログラム #include &ltstdio.h&gt #include &ltstdlib.h&gt int main(void){ FILE *fp; int i; unsigned char buf[1000]; /* 符号なしchar宣言 */ int size; fp = fopen("wav_sample.wav", "rb"); /* rb バイナリ読込み */ if (fp == NULL) { /* ファイルがない場合のエラー処理 */ printf("error"); exit(EXIT_FAILURE); }else{ /* 読込み及びデータ数の取得 */ size = fread(buf, sizeof(unsigned char), 1000, fp); for(i=0; i&ltsize; i++){ /* 表示 */ if(i % 16 == 0) printf("\n"); /* 改行 */ printf("%02x ", buf[i]); /* 16進数で表示 */ } } fclose(fp); /* ファイルを閉じる */ return 0; } fread()でバイナリ

C言語 テキストファイル書込み fputs

ファイルの書込み。新規でテキストファイルを作って、そこに文字列を書込む。同じ名前のファイルがある場合は上書きされる。 ファイル書込みプログラム #include &ltstdio.h&gt #include &ltstdlib.h&gt int main(void){ char str[] = "Hello World"; FILE *fp; fp = fopen("sample1.txt", "w"); if (fp == NULL) { exit(EXIT_FAILURE); } fputs(str, fp); fclose(fp); return 0; } 実行すると以下の内容のテキストファイルがプログラムと同じ階層に作られる。 上から説明すると、ファイルを扱うためにまず、&ltstdlib.h&gtが必要なのでincludeする。 str[]は書き込み内容。内容は「Hello World」とした。 FILE *fpはファイルポインタの宣言。これはファイルの入出力で必要な情報を管理する。 fopenで指定したパスのファイルを開く。その際の「w」は、書込みモードの指定。 fputsでテキストを書込む。 最後にfcloseで開いたファイルを閉じて終了。 sample1.txt Hello World 次に作ったファイルに追加書込みしてみる。 既存ファイルに追加書込み #include &ltstdio.h&gt #include &ltstdlib.h&gt int main(void){ char str[] = "\n追加書込み"; FILE *fp; fp = fopen("sample1.txt", "a"); if (fp == NULL) { exit(EXIT_FAILURE); } fputs(str, fp); fclose(fp); return 0; } 実行すると、先に作ったファイル「sample1

C言語 テキストファイル読込み fopen

ファイルの読み込みを行ってみる。まずは、テキストファイルを用意する。下の例ではsample.txtという名前のファイルをプログラムと同じ階層に置いている。中身は以下のようにした。 sample.txt param0=1.000000 param1=0.513000 param2=0.120000 param3=0.110000 param4=0.000012 ファイルから1行読込プログラム #include &ltstdio.h&gt #include &ltstdlib.h&gt int main(void) { FILE *fp; char str[128]; fp = fopen("sample.txt", "r"); if (fp == NULL) { exit(EXIT_FAILURE); } else { printf("%s", fgets(str, 128, fp)); } fclose(fp); return 0; } このプログラムを実行すると、1行目の「param0=1.000000」だけがコマンドプロンプトに出力される。 上から説明すると、ファイルを扱うためにまず、&ltstdlib.h&gtが必要なのでincludeする。 FILE *fpはファイルポインタの宣言。これはファイルの入出力で必要な情報を管理する。 str[128]は、読み込んだテキストを格納するための配列を用意。サイズは1行がまるまる入るだろう大きさにしている。 fopenで指定したパスのファイルを開く。その際の「r」は、読込モードの指定。 if文。もしファイルがなければ、fpはNULLとなるので、その時点で終了させる。ファイルがあれば、elseの行を実行する。 fgetsでテキストを読み込んでいるのだが、fgetsは1行読み込む関数なので、改行があるところまで読み込んでいる。もしくはバイト数で指定することもできる。それをpintfでプロンプトに出力する。 最後にfcloseで開いたファイルを閉じて終了。 param0=1.000000 次にすべての行を読み込

C言語 入力関数 scanf, fgets

入門書で、まず紹介されているキーボードからの書式付入力 scanf。出力の printf の逆であり使い方も似ている。実際のプログラムでは、scanf は予期せぬ入力に対応しきれいないため、あまり使われないらしい。入力関数は scanf 以外にも fscanf や gets などがあるが、これらも推奨ではないようだ。getsに至っては最新のC11では廃止された模様。では推奨は何?という疑問だが、それぞれ問題があって対処しながら使うというのが現実のようだ。それでも fgets が使いやすいようだ。 fgets は本来ファイルから文字列を読み取るための関数だが、キーボードからの入力もファイルと同じように扱うことができる。とりあえず入力は fgets だけ使っていればよいみたい。このページでは、まず scanf を試してみる。そして fgets でも同じことをしてみようと思う。 scanfのシンプルな例 #include &ltstdio.h&gt int main(void){ char str[10]; printf("文字列入力\n"); scanf("%s", str); printf("%s\n", str); return 0; } 入力した文字列(char 10バイト)をそのままコマンドプロンプトに出力するプログラム。例えば「123abcあいうえお」と入力すると、「123abcあいうえお」と出力される。文字列の配列の10バイトを超えているが、ポインタで扱われているので、入力した文字列はすべて表示される。注意点はスペース、タブ、改行などが入ると、そこまでしか読み取らない。 文字列入力 123abcあいうえお 123abcあいうえお 続いてfgetsで同じ内容を書いてみる。 fgetsのシンプルな例 #include &ltstdio.h&gt int main(void){ char str[10]; printf("文字列入力\n"); fgets(str,10,stdin); printf("%s\n", str); return 0; }

HTML5 画像スムーズ スクロール

イメージ
smoothdivscrollを使わせてもらった。 http://www.smoothdivscroll.com/ 通常のサーバではうまく動くのだが、Bloggerに移植すると毎回苦労する。今回はうまく動かないまま。マウススクロールしか有効になっていない。カーソル位置でもスクロールが出来るはずなのだがうまく動かない。エラーも出ているけど、ソースを修正するのも面倒なのでそのまま。Bloggerで凝った事はやらないほうがいいなぁ。 IEで見るとたぶんひどいことになっていると思います。

表計算ソフト Gnumeric spreadsheet

イメージ
オフィススイートを捨てる 長年しぶしぶ使っていたMSオフィスを捨てた。代替品として使っていたLibreOfficeもアンインストールした。もうオフィススイートは使わない。どうもこれらのソフトを使うとイライラして楽しくない。というか、いつも不快な思いをしながら作業をする。そして馬鹿みたいなことで、時間を食ってしまう。LibreOfficeはその思想からして応援したいところだが、MSオフィスの代替を目指すところで、個人的に使いたいというソフトではないのだなぁ。。残念ながら。仕事でワードのファイルを渡されることもあるけど、変換で何とかなるだろう。官公庁のMSオフィス指定はさっさとやめてもらいたい。ワードで作った出来の悪いフォーマットを送ってきて、それに記入しろ、というのは勘弁して欲しい。 オフィススイートのよろしくないところ オフィススイートと呼ばれるソフトには、ワープロ、表計算、プレゼン用ソフトにデータベースなどが入っていて、これさえあれば一般事務がこなせるという代物。オフィススイートの欠点としては肥大化しまくって、起動が遅く、起動後ももっさり動き、ディスクスペースは500MB以上食う。対策としてPCを最新の超高速マシンにして一般事務をこなさなければならない。これはおかしいだろう・・・ 個人的にはワードが最悪。それにも関わらず、これで提出しろということがあまりにも多い。プレゼンもパワーポイント指定に何年も付き合わされた。誰もが似たような印象のプレゼン資料にはうんざりする。データベースはかわいそうなぐらい使わない。(個人的にデータベースって好きなのよ) ただ表計算だけはたまに使う。ということで、表計算単体があれば、個人的にはOKなのだ。あと、データベースはデータベースでいろいろと。 表計算(spreadsheet)だけでいい 単体表計算ソフトを探して見つけたのがGnumeric (グニューメリック)。オープンでフリーで強力! マルチプラットフォーム! http://projects.gnome.org/gnumeric/ image/svg+xml

音律について

イメージ
ドレミの誕生 現代のドレミの基盤を作ったのはピタゴラス(教団)。なんと紀元前500年以上前に、その基礎は出来上がっていた。では、どうやってドレミを作り出したのか? オクターブは基準 まず、ある音に対して最も調和する音を探してみる。これはピタゴラスに限らず、世界中の共通の認識でオクターブの音となる。低い「A(ラ)」に最も馴染む音は、高い「A」もしくは、さらに低い「A」ということになる。実際に波形を作って音にしてみた。純粋なサイン波の「A 440Hz」に対して途中でオクターブ上の「A 880Hz」をミックスしたサンプル。880Hzは耳に付くので、-6dB音量を下げている。 実際に聴いてみると、響きとしては単純な印象で、ハーモニーという感じはない。きわめて近い関係の音である。波形を見るとよく分かる。上段が440Hzで、中段が880Hz、下段がミックスしたもの。オクターブ上の音は周期がちょうど1/2になり、ミックスしてもうなりは生じず、安定した波形になっている。 現代の最も使われているドレミは、オクターブを均等に12分割している平均律という音律。でもピタゴラスの時代は、同じ12分割でも、微妙にいろいろ違う。ピタゴラスが、その12音を作り出す過程を追ってみる。 弦の倍音 はじめに弦の振動の分析から始まる。まずは実際のギターで音を出してみる。5弦開放のA(110Hz)の音。 弦を鳴らすと、いくつもの倍音が鳴っていることが分かる。Audacity(波形編集ソフト)を使って、周波数スペクトルで視覚的に確認してみる。 一番低い音が基音のA110Hzの音で最もピークが大きい。これでAの音が鳴っていると人は認識できる。明らかなピークとして存在する倍音を順に並べると以下のようになった。 基音 110Hz A 2倍音 220Hz A 3倍音 331Hz E 4倍音 440Hz A 5倍音 551Hz C# 6倍音 659Hz E 7倍音 770Hz G 8倍音 880Hz A ・ ・ ・ スペクトルを見ても、かなりたくさんの音で構成されているのが分かる。ピークの大きさが様々であり、時間軸で見ると、鳴り続けている音もあれば、すぐに減衰する音もある。弦が鳴っている音以外にアタック音もあるの

C言語 多次元配列

2次元以上の配列を多次元配列という。これは1次元配列の各要素に、さらに1次元配列をするようなもの。2次元配列の場合は升目をイメージになり、3次元配列の場合は、さらに奥行きが加わって立体になるようなイメージ。4次元では、さらに各要素に1次元配列がされていく。イメージとしては個人差が出るところだが、個人的には2次元&入れ子でイメージしている。こうすれば何次元だろうが容易いので。 まずは2次元配列。使うシーンとしては、縦横柔軟な計算が必要なとき。サンプルは、よくある成績の例で、いくつかの方法で計算してみた。 #include &ltstdio.h&gt /* マクロ定義 配列の要素のサイズを調べる */ #define SIZE(a) (sizeof(a)/sizeof(a[0])) /* 2次元配列 A,B,C,Dさんの国語、算数、理科の点数 */ int main(void) { float a[][3]={ /* 最初の配列の要素数は省略可 */ {50,50,50} /* 0=Aさん 国語、算数、理科の点数 */ ,{90,60,50} /* 1=Bさん 国語、算数、理科の点数 */ ,{30,90,40} /* 2=Cさん 国語、算数、理科の点数 */ ,{40,70,60} /* 3=Dさん 国語、算数、理科の点数 */ }; /* 各人の3教科平均点 */ int i; int j; float sum; for(i=0;i&ltSIZE(a);i++){ for(j=0;j&ltSIZE(a[0]);j++){ sum += a[i][j]; } printf("各人平均点 %d= %f\n",i,sum/SIZE(a[0])); sum = 0; } /* 各教科の平均点 国語=0、算数=1、理科=2 */ for(i=0;i&ltSIZE(a[0]);i++){ for(j=0;j&ltSIZE(a);j++){ sum += a[j][i]; } printf("教科平均点

C言語 構造体 struct

構造体とは、異なった型の変数をひとつの名前でまとめたようなもの。Javaから入った身としては、どう使うか疑問に感じるところ。構造体は関数を内部に入れられないので、クラス的に使うことは難しい。でもクラスを使うよりも負荷が少ないようだ。新しいGo言語でも構造体は健在なので、パフォーマンスを重視すると捨てがたいのだろう。まずは基本的な扱い方からスタート。 CDのリストを構造体で表現してみる #include &ltstdio.h&gt #include &ltstring.h&gt /* 構造体の宣言 メモリ割当ては行われない*/ struct cd{ int no; char title[20]; int price; }; int main(void){ /* クラシック リスト作成 メモリに展開 */ struct cd classic[] ={ {1,"Bach",2600}, {2,"Mozart",2500}, {0,"",0} }; /* ジャズ リスト作成 メモリに展開 */ struct cd jazz ={ 1,"Coltrane",1800 }; /* クラシック リスト表示 */ int i; for(i=0;i&lt2;i++){ printf("%-6s No.%d %-9s Price:%d\n", "Classc", classic[i].no, classic[i].title, classic[i].price); } /* ジャズ リスト表示 */ printf("%-6s No.%d %-9s Price:%d\n", "Jazz", jazz.no, jazz.title, jazz.price); return 0; } まずジャンルごとにClassicとJazzに分けて考える。使う構造体は同じで、ナンバー

C言語 static 変数

static ローカル変数 staticがついたローカル変数は、プログラム開始時にメモリ上に作られ、関数の処理が終わっても変数の値は残り続け、プログラム終了時まで存在する。また何もしなくても0で初期化される。 #include &ltstdio.h&gt int count(){ static int s_x; /* 値が残り続ける */ s_x++; return s_x; } int main(void){ int a; a = count(); printf("main1 a= %d\n",a); a = count(); printf("main2 a= %d\n",a); a = count(); printf("main3 a= %d\n",a); return 0; } mainからcount関数を3回呼び出している。staticがなければ、変数「s_x」は毎回初期化され、同じ結果「1」が出るのだが、staticをつけることで、変数の値が残り続け、「1」「2」「3」となる。 main1 a= 1 main2 a= 2 main3 a= 3 static グローバル変数 グローバル変数にstaticキーワードを使用すると、そのファイル内でしか利用できなくなる。同じstaticキーワードだが、ローカル変数の時と意味合いが違う気がする・・ こういう部分がC言語のちょっとおかしなところ。 main関数 a.c /* a.c */ #include &ltstdio.h&gt #include "a.h" /* グローバル変数を利用するために宣言をするが・・ */ extern int g_num; int main(void){ funcB1(); funcB1(); /* printf("main %d\n",++g_num); エラーになる */ return 0; } 実装ファイル b.c /* b.c */ #include &ltstdio.h&gt /* staticグローバ

C言語 配列 arrays

配列の宣言 配列は同じ型の集まり。データを一括して扱う場合に使用する。ひとつひとつを要素(element)という。要素数の添え字は0から始まる。例として10個のint型の配列を宣言。 int a[10]; 配列にアクセスするときの添え字は0から9となる。 a[0]~a[9] この配列の中にint型の数値を入れるには、いくつかの方法がある。 要素ひとつひとつに入れる場合は以下のようにする。 a[0]=255; a[1]=256; 配列を宣言するときに初期値として入れてしまうことも可能。 int a[10] = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55}; また、初期値をこのように入れている場合は、要素数は省くこともできる。 int a[] = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55}; int型の配列 #include <stdio.h> int main(void){ int a[] = {1,1,2,3,5,8,13,21,34,55,89,144}; int i; for(i=0;i<15;i++){ printf("%d array= %d アドレス=%x\n" ,i,a[i],&a[i]); } return 0; } 配列を用意して、初期値となる数列を入れる。それをfor文で出力。実行結果は以下の通り。注目点はアドレスがint型の4byteずつ増加しているところ。要素は4byteをひとつとして数えているのが分かる。また配列の要素以上に繰り返し表示させているが、最後の要素である144以降は無関係な数値が入っている。Javaではコンパイルエラーになるようなところも、C言語では容赦なく実行してしまうので注意が必要。 0 array= 1 アドレス=23ff0c 1 array= 1 アドレス=23ff10 2 array= 2 アドレス=23ff14 3 array= 3 アドレス=23ff18 4 array= 5 アドレス=23ff1c 5 array= 8 アドレス=23ff20 6 array= 13 アドレス=23ff24 7 arr