【初歩】mac OSXでC言語マスターするスレ【基本】 401 :
390 :02/09/27 09:43 ID:SxbbXQMC
>>399 連休中はさすがにみんな遊びに行ってるんだろうと思ってましたが、それだ
けじゃなかったみたいですね。
みなさん自力でがんばってると思っておきましょう。
>>400 それを言っちゃあ...。
でも、Project Builderの話題もありますのであってもいいと思いますよ。
402 :
392 :02/09/27 12:20 ID:KXadaBpf
>396さん char ch;の間違いの件、分かりませんでした。ヒント下さい。 >399 人いますよ(少なくとも1人は)。 超初心者向けの問題だったらがんばって解いてみようと思います。
403 :
401 :02/09/27 13:37 ID:SxbbXQMC
>>402 396さんではありませんが、ヒントはman fgetcです。
ch = fgetc(fp)は...
404 :
392 :02/09/27 14:47 ID:KXadaBpf
fgetcの戻り値はint型であるべきなのに、char型のch=fgetc()としているところが 間違い...でよろしいのでしょうか? ちなみにProjectBuilderでchar ch;をint ch;にしても動きました。
おぃおぃ本当にそれで良いのか? 392がほすぃのはint型の値じゃなくてchar型の値だろ。 だったらchar chじゃ無いとまずいだろ。
406 :
396 :02/09/27 15:53 ID:nGAAdYd5
>>402 まぁ、
>>404 で正しいけど、以下のことを考えてみて。
fgetcはファイルから読み取った文字を返します。
ファイルを最後まで読み終わるとEOFを返します。
さて、ファイル中にもしEOFが存在したらどうなるでしょう?
fgetcは何を返せばいいでしょう?
407 :
403 :02/09/27 16:14 ID:SxbbXQMC
>>405 man putcharもしてみましょう。
408 :
392 :02/09/27 16:21 ID:KXadaBpf
>405 どっちでも動くんですよね、intでもcharでも。他になんか違うところがあるんでしょうか? >406 読み込みファイルに設定したname.txtの内容mynameの間にEOFと入れてmyEOFname としたら、EOFのところで読み込みが止まるのかな?ん〜chをintにしてもcharにしても 問題なくmyEOFnameと表示されました。お〜っと、EOFは負の整数だって独習Cに書いて あったなぁ(通常は-1だって)。じゃあmy-1nameとすると途中で読み込みが止まって myとしか表示されないのかなぁ〜ってやってみたのですが...my-1nameと表示 されました(chをintにしてもcharにしても)。僕は何か根本的な思い違いをしているので しょうか? ちなみに>406さんが指摘されている「ファイル中にEOFが存在したら云々」に関しては ちょっと本を読み進めたら同じような事が指摘されていて、feof(),ferror()でチェックする と書いてありました。この前読んだときは何のことかよく分からなかったのですが、すこし 理解できたような気がします(まだ分かってないかもしれませんが)。
409 :
406 :02/09/27 16:58 ID:nGAAdYd5
>>408 「-1」って書いたら'-'と'1'という二文字になっちゃうよ。
もっと簡単な方法がありそうだけどとりあえず、
#include <stdio.h>
int main() {
FILE *fd;
fd = fopen("testfile", "w");
fprintf(fd, "before%cafter\n", -1);
fclose(fd);
return 0;
}
とかって感じのプログラムを実行すると
-1が内部に入ったtestfileっていうファイルができるよ。
エラーチェックをつけたければ自分でやってくれ。
ターミナルを使うなら、こんなプログラム書かなくても
awk 'BEGIN {printf ("before%cafter\n", -1)}' > testfile
とかってコマンドを実行すればいい。
410 :
392 :02/09/27 17:30 ID:KXadaBpf
>409 確かに、教えていただいた方法でtestfileを作成してfgetc()の戻り値をchar型にすると beforeで読み込みが止まり、int型にするとbefore�afterと最後まで表示されました。なるほど。 fgetcの戻り値をchar型にすると真のEOFと偽物のEOF(こんな表現でいいのかなぁ?)が判別でき ないけどint型ならそれが可能、ということでしょうか? でもそれだと何でfeof()やferrorがあるのかなぁなんて疑問がまた生まれました。
411 :
407 :02/09/27 18:00 ID:SxbbXQMC
>>410 その疑問を解く(一つの)ヒントは、やっぱりman fgetcです。
fgetc()がEOFを返すのは...
412 :
392 :02/09/27 18:52 ID:KXadaBpf
>407 man fgetc()のreturn valuesのところを読むと fgetc()がEOFを返すのは、ファイルの最後に到達したときか、読み込みエラーが生じたとき。 この2つを識別するためにfeof()とferror()が使われる。って書いてありました。 (これはわかるんですが、、、でも同じ事がfgetc()の戻り値をchar型でなくint型にすれば できるんですよね。この理由がわからない...) で、エラーが起こるとグローバル変数のerrnoがエラーを識別するために設定される。 (なんじゃこのerrnoって?man errnoしても何にもでてこない) EOFの状態(本当はエラーかもしれない?errnoのこと?)はとりあえずターミナル上で覚えて おいて、さらに読み込み作業を本当のEOF(ファイルの終わり)に到達するまで続ける。 (ん〜英語に自信が無いなあ、誤訳してそう。) ..すみません結局分かりませんでした。manが使いこなせません。
413 :
411 :02/09/27 22:23 ID:9NMezIFm
>>412 戻り値をcharで受けてもintで受けても、ファイルの終わりなのか、エラーに
なったのかは判断できませんね。
414 :
392 :02/09/27 23:09 ID:KXadaBpf
>412 あっ、やっぱりそうなんですか。でもそうすると>409 >410のように 意図的に途中にEOF(-1)が入ったファイルを作るった場合に、fgetc() の戻り値をcharにした場合とintにした場合で結果が異なるのは何故なんでしょう? 意図的にEOF(-1)を作った場合以外にもエラーになることがあるということなのでしょうか?
415 :
413 :02/09/28 00:21 ID:dsHEaITP
>>414 fgetc()は、unsigned charで読み取った値をintに変換して返すからです。
-1をunsigned charにすると...
>>414 >>392 のプログラムの
putchar(ch);
の部分を
printf("%c:%d:%d ", ch, ch, (char)ch);
とかって書いて実行してみたら?
実行する前に、どういう結果になるのか想像してからね。
>>414 int のサイズが2バイトとすると(最近は4バイトが多いが)
EOF -> 0xFFFF、データ中の -1 -> 0x00FF の違い。
418 :
名称未設定 :02/09/29 20:25 ID:/mjKyy7o
419 :
412 :02/09/29 20:42 ID:NLsBSK/K
>418 ありがとうございます。実は、1週間ぐらい前にjmanインストールしたのですが、 環境変数の設定の仕方もろもろが分からずに使えませんでした。 で、いまはC、Cocoa、Unix(B shell)の勉強を行ったり来たりしています。
420 :
418 :02/09/29 21:26 ID:/mjKyy7o
>>419 PATHのこと?
tcsh使ってるなら、 ~/.cshrc ってファイルを作って、
set path=($path /usr/local/bin)
と書いとくと、幸せになれるかも。
shell の勉強もしているということなので、解説は割愛。
ちなみに、環境変数を設定していなくても
% /usr/local/bin/jman
で使えると思う。
421 :
名称未設定 :02/10/03 11:13 ID:C+ZpC/fs
スレ参加者募集あげ。
数日これない間にさびれぎみ、、(-_-) ム板にいってしまったのかな、、
>>422 みんなある程度すると自分で考え、調べ、学ぶ事が
出来て行くのではないでしょうか?
なんというかある程度はプログラミング(C)についての
道理や筋道が見えてくるというか。。。
とりあえず、新規参加募集age
>>423 そうやね。
ってか自分でできるようにならんとヤバイでしょうし。
しかし新規参加者不足ですな。
ム板にいきなりいってるのかもしれず。
425 :
238 :02/10/09 12:19 ID:8CXNpsst
GUIを絡めた、Cプログラミングってどんな感じなの? PowerPlant + CodeWorrior (C)とか。
ProjectBuilder + InterfaceBuilder じゃないかな。
427 :
238 :02/10/09 14:23 ID:8CXNpsst
>>426 Cプログラミングだと、CW+PPの組み合わせの方が多そうだな、と思ったから。
もう、CプログラミングでもPB+IBの方が多いのかな。
428 :
426 :02/10/10 00:13 ID:ggYyHlG5
>>427 あぁなるほど。仕事でバリバリ組む人はそっちのが多いのかなぁ。
勉強し始めた俺は mi + Terminal だったりします。
RSAの簡単な実験のつもりで以下をterminalでccすると ld: Undefined symbols: _decript _encript とエラーが出ます。どうか間違いやまずい点をご指摘下さい。 #include<stdio.h> #include<math.h> int decryptkey, n,ln; int getPublicKey(void){ n = 11*13; ln = 10*12; decryptkey = 17; return decryptkey; } void encrypt(char* pt, int e){ int buffer,t; t = 0; while(pt[t] == -1){ buffer = (int)pt[t]; pt[t] = (char)(fmod(pow(buffer,e), n)); t++; } }
void decrypt(char* pt){ int buffer,t; t = 0; while(pt[t] == -1){ buffer = (int)pt[t]; pt[t] = (char)(fmod(pow(buffer,decryptkey), n)); t++; } } int main(void){ int encryptkey; char* text="this is plain text."; encryptkey = getPublicKey(); printf("public key is:%d",encryptkey); encript(text, encryptkey); printf("encrypted text is:%s",text); decript(text); printf("decrypted text is:%s",text); return 0; }
cryptとcript
432 :
429 :02/10/10 12:33 ID:Sv5RKon6
>>431 ありがとうございます。タイプミスだったすね。
なんだか恥ずかしいです、とても。
で、直すと無事コンパイルが通りまして
実行するとencryptや、decryptの中の
whileが実行されないようです。
このように文字列を扱うのは間違いなのでしょうか?
while()ってのは 括弧の中が真である時に繰り返される。 -1ってのは文字列の最後に出てくるんだよね? つまりpt[t] == -1が真になるのは・・・。
434 :
415 :02/10/10 14:18 ID:E9qOCXvY
>>432 whileループに入る条件が成立してませんね。
あと、文字列リテラルはナル文字で終わります。
それと、文字列リテラルは書き換えないようにしましょう。
435 :
429 :02/10/10 23:50 ID:Sv5RKon6
>>433 ,434
ご指摘ありがとうございます。
なるほどです。本をよく読めって感じですね。。。
とりあえずwhileのところは
while(pt[t] != '\0'){
とやってみるとうまくいきました。
ただ根本的な部分で間違いをしていまして
それについて考えています。
ユーグリッドの互除法(改)のやりかた。。
436 :
429 :02/10/11 03:44 ID:cGX7Km9y
改変に改変を重ね以下のようになりました。 一応動きますがバグあり、突っ込みどころ満載だと思いますので、ぜひ突っ込んで下さい。 また、ご指摘を頂いた皆様に改めて感謝いたします。ありがとうございます。 #include<stdio.h> #include<math.h> int decryptkey, n,ln; int getPublicKey(void){ n = 11*13;//p*q for p,q is prime ln = 2*2*3*5;//LCM((p-1)*(q-1)) decryptkey = 23;//relatively prime to ln (equals to GCD(dkey,ln)=1) //calculate 1/d mod ln int x, y, z, q, u, v, w; u = 0; v = 1; x = ln; y = decryptkey; do{ z = x % y; q = (x - z) / y; w = u - q * v; x = y; y = z; u = v; v = w; }while(z != 0); if(u < 0) u += ln;//in order to avoid negative index return u; }
void rsacrypt(char* it, int key, char* ot){ int buffer, b, j; int i = 0; while(it[i] != '\0'){ b = (int)it[i]; buffer = b; for( j = 1; j < key; j++){//calculate (it)^key mod n buffer *= b; buffer %= n; } *(ot + i) = (char)buffer; i++; } *(ot + i) = '\0'; } void encrypt(char* in, int e, char* out){ rsacrypt(in, e, out); } void decrypt(char* in, char* out){ rsacrypt(in, decryptkey, out); } int main(void){ int encryptkey; char* ptext="this is plain text."; printf("plain text is: %s\n",ptext); char *etext, *dtext; dtext = (char*)malloc(sizeof(ptext));//without this , BUS ERROR returned... encryptkey = getPublicKey();//maybe etext needs malloc too... printf("public key is:%d\n",encryptkey); encrypt(ptext, encryptkey, etext); printf("encrypted text is: %s\n",etext); decrypt(etext, dtext); printf("decrypted text is: %s\n",dtext); return 0; }
438 :
名称未設定 :02/10/11 10:47 ID:vOgTkuMQ
Perlでもやってたほうがいいのでは。
>>436 うーん、少なくともポインタについては勉強したほうがいいと思う。
もし本を読んでるとしたら、理解が中途半端かor分かってない。
ポインタについてはこのスレの前の方で説明している人がいたはずです。
まず、これらをヒントに間違い探しをしてみましょう。
それと、できれば字下げしてください。
あなたも読みにくいでしょう?
>>438 Cを勉強したい、といっているのだし
Cを学んでからでもいいと思うが。Perlなんて将来どうなるか分からんし。
>>436 ソースが激しくきちゃない、、、
スレに書き込むためなのかもしれないですが、もうすこしなんとかした方がよいです。
個人的意見ですがどんなソースがきれいか判断できるという事は、意味がある程度
わかっているという事に近似だと思います。
ソースきちゃないのはよくわかっていないからだと思われます。
精進してください。
>>438 Perlは、、今から学ぶならPythonの方がいいです。
どこが汚くて、どう書き換えたらいいか、例を出してあげないと たぶん分からないと思われ。それをしないで言いっぱなしだと、 ただの自慢したがりに見えなくもない。 漏れはプログラミング、まったく分からない人なので、 「そういうならお前やれ」はなしね。
>>441 >>440 氏が汚いって言ってるのは確かに、
ポインタに関する作法(それ自体はよく分からんけど)も含まれているだろうけど、
本当に基本的な作法を守っていないからだと思われます。
これは、どんな言語のコードを書く上で、守らなければならないモノで。
まぁ、多分
>>440 氏の言うように、スレに書き込むためかもしれませんが。
漏れ自身も初心者ですが、自分で調べたりなんなりしないと、身に付かないと思ってます。
もし、
>>436 自身が分からなければ、そう言えばいいだけの話だと思うし。
生意気で申し訳ないが。
古いProjectBuilderでコンパイルしてみたんですが、素のままだと通りませんね。 mainだけ字下げしてみました。コメントは冗長ですけど。 最初のprintfは適当なところに動かしてます。 <--?のところがネックですね。まだ問題があるかもしれませんが 時間もありませんのでこのあたりで。 int main(void){ int encryptkey; char* ptext="this is plain text."; char *etext, *dtext; //<--? // initialize dtext = (char*)malloc(sizeof(ptext));//without this , BUS ERROR returned... encryptkey = getPublicKey();//maybe etext needs malloc too... printf("public key is:%d\n",encryptkey); printf("plain text is: %s\n",ptext); // make an encryption for given tokens encrypt(ptext, encryptkey, etext); printf("encrypted text is: %s\n",etext); // make decoded tokens for given encrypted tokens decrypt(etext, dtext); printf("decrypted text is: %s\n",dtext); return 0; }
>>443 cryptの仕組みは分りませんが、ある文字列に対応する文字列を返すものだと思います。
で、問題は
char *etext,*dtext;
は文字列を保存できません。保存してある場所を指し示せるだけです。
さらに
dtext = (char*)malloc(sizeof(ptext));
は無意味です。まだ、
dtext = (char*)malloc(strlen(ptext)+1);
のほうがましでしょう。
この場合でも問題は残ります。rsacrypt(in, decryptkey, out);
で、*outにどれだけの長さの文字列が格納されるかです。
*ptextの文字列長を超える文字列が格納された場合、メモリを破壊します。
また、
>>429 さんの実装もよくありません。一見上手くいっているようですが、
char* ptext="this is plain text."
の直後に
char* hoge="abcdefghijklmnopqrstuvwxyz";
とかやって、rsacrypt実行後
printf(hoge);
でとんでもない文字列が表示される可能性があります。
Cには文字列と言う型は無くて、
プログラマが場所を用意してあげなければならないことを覚えておいてください。
445 :
434 :02/10/12 19:01 ID:QRhvrJFa
>>436-437 1. malloc()のために、stdlib.hをインクルードしましょう。
2. sizeof(ptext)は、4(MacOS Xの場合)になりますので、(
>>444 さんの言
われるように)strlen()を使うか、
char ptext[] = "this is plain text."にしましょう。
あと、一応動くとありますが、ちゃんとdecryptされてます?
446 :
445 :02/10/13 16:44 ID:VvHAy8Li
あ、etextをmalloc()してませんね。 あと、malloc()したらfree()と憶えておきましょう(この場合いらないと言う 人もいるでしょうが)
447 :
443 :02/10/14 19:01 ID:Y8/UodjN
>>445 どうもありがとうです。
元のコードはインデントと変数の宣言部分しかみてません(w
ちゃんと直してあげればよかったですね。
>>446 うーん、いきなりmalloc使わずに
普通に配列で宣言してもいいんじゃないですかね。
あと気になったのは、引数のチェックをどこでしてるのか、ってところですか
この辺りは最初のうちに頭に入れといたほうがいいと思います。
>>441 例ですか。修正してしまった方がはやいのですが、それだと勉強にならない気
がしますし。
なぜきたないかは勉強するうちにわかるかという期待だと思ってほしいです。
>>443 おおきれいや。
ただchar* ptextとchar *etextがまざるのはいかがな物かと。
>>445 氏適切やな、、わし頭さびてきてる(w
>>447 境界チェックとかいわゆる安全なプログラムの作り方の話しされてます?
Cではいろいろそのあたり気をつける事多すぎるやもしれず。
450 :
445 :
02/10/14 22:29 ID:iRkbH5Mi