【初歩】mac OSXでC言語マスターするスレ【基本】

このエントリーをはてなブックマークに追加
401390:02/09/27 09:43 ID:SxbbXQMC
>>399
連休中はさすがにみんな遊びに行ってるんだろうと思ってましたが、それだ
けじゃなかったみたいですね。
みなさん自力でがんばってると思っておきましょう。

>>400
それを言っちゃあ...。
でも、Project Builderの話題もありますのであってもいいと思いますよ。
402392:02/09/27 12:20 ID:KXadaBpf
>396さん
char ch;の間違いの件、分かりませんでした。ヒント下さい。

>399
人いますよ(少なくとも1人は)。
超初心者向けの問題だったらがんばって解いてみようと思います。


403401:02/09/27 13:37 ID:SxbbXQMC
>>402
396さんではありませんが、ヒントはman fgetcです。
ch = fgetc(fp)は...
404392:02/09/27 14:47 ID:KXadaBpf
fgetcの戻り値はint型であるべきなのに、char型のch=fgetc()としているところが
間違い...でよろしいのでしょうか?
ちなみにProjectBuilderでchar ch;をint ch;にしても動きました。
405名称未設定:02/09/27 14:57 ID:IOoGYOVP
おぃおぃ本当にそれで良いのか?
392がほすぃのはint型の値じゃなくてchar型の値だろ。
だったらchar chじゃ無いとまずいだろ。
406396:02/09/27 15:53 ID:nGAAdYd5
>>402
まぁ、>>404で正しいけど、以下のことを考えてみて。
fgetcはファイルから読み取った文字を返します。
ファイルを最後まで読み終わるとEOFを返します。
さて、ファイル中にもしEOFが存在したらどうなるでしょう?
fgetcは何を返せばいいでしょう?
407403:02/09/27 16:14 ID:SxbbXQMC
>>405
man putcharもしてみましょう。
408392: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()でチェックする
と書いてありました。この前読んだときは何のことかよく分からなかったのですが、すこし
理解できたような気がします(まだ分かってないかもしれませんが)。
409406: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
とかってコマンドを実行すればいい。
410392:02/09/27 17:30 ID:KXadaBpf
>409
確かに、教えていただいた方法でtestfileを作成してfgetc()の戻り値をchar型にすると
beforeで読み込みが止まり、int型にするとbefore�afterと最後まで表示されました。なるほど。
fgetcの戻り値をchar型にすると真のEOFと偽物のEOF(こんな表現でいいのかなぁ?)が判別でき
ないけどint型ならそれが可能、ということでしょうか?
でもそれだと何でfeof()やferrorがあるのかなぁなんて疑問がまた生まれました。
411407:02/09/27 18:00 ID:SxbbXQMC
>>410
その疑問を解く(一つの)ヒントは、やっぱりman fgetcです。
fgetc()がEOFを返すのは...
412392: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が使いこなせません。
413411:02/09/27 22:23 ID:9NMezIFm
>>412
戻り値をcharで受けてもintで受けても、ファイルの終わりなのか、エラーに
なったのかは判断できませんね。
414392:02/09/27 23:09 ID:KXadaBpf
>412
あっ、やっぱりそうなんですか。でもそうすると>409 >410のように
意図的に途中にEOF(-1)が入ったファイルを作るった場合に、fgetc()
の戻り値をcharにした場合とintにした場合で結果が異なるのは何故なんでしょう?
意図的にEOF(-1)を作った場合以外にもエラーになることがあるということなのでしょうか?
415413:02/09/28 00:21 ID:dsHEaITP
>>414
fgetc()は、unsigned charで読み取った値をintに変換して返すからです。
-1をunsigned charにすると...
416名称未設定:02/09/28 23:36 ID:SP4EnSXl
>>414
>>392のプログラムの
putchar(ch);
の部分を
printf("%c:%d:%d ", ch, ch, (char)ch);
とかって書いて実行してみたら?
実行する前に、どういう結果になるのか想像してからね。
417名称未設定:02/09/29 18:58 ID:GQdLvuN8
>>414
int のサイズが2バイトとすると(最近は4バイトが多いが)
EOF -> 0xFFFF、データ中の -1 -> 0x00FF の違い。
418名称未設定:02/09/29 20:25 ID:/mjKyy7o
>>412
ttp://www.fan.gr.jp/~sakai/jman.html

% jman getc
% jman ferror
% jman errno
419412:02/09/29 20:42 ID:NLsBSK/K
>418
ありがとうございます。実は、1週間ぐらい前にjmanインストールしたのですが、
環境変数の設定の仕方もろもろが分からずに使えませんでした。
で、いまはC、Cocoa、Unix(B shell)の勉強を行ったり来たりしています。
420418: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
スレ参加者募集あげ。
422Emacsうまうま:02/10/08 23:50 ID:anwF+JbT
数日これない間にさびれぎみ、、(-_-)

ム板にいってしまったのかな、、
423名称未設定:02/10/09 00:53 ID:8ouTcHb2
>>422
みんなある程度すると自分で考え、調べ、学ぶ事が
出来て行くのではないでしょうか?
なんというかある程度はプログラミング(C)についての
道理や筋道が見えてくるというか。。。

とりあえず、新規参加募集age
424Emacsうまうま:02/10/09 06:55 ID:mJ2sQ+oY
>>423
そうやね。
ってか自分でできるようにならんとヤバイでしょうし。

しかし新規参加者不足ですな。
ム板にいきなりいってるのかもしれず。
425238:02/10/09 12:19 ID:8CXNpsst
GUIを絡めた、Cプログラミングってどんな感じなの?
PowerPlant + CodeWorrior (C)とか。
426名称未設定:02/10/09 12:57 ID:9HFJZVR5
ProjectBuilder + InterfaceBuilder じゃないかな。
427238:02/10/09 14:23 ID:8CXNpsst
>>426
Cプログラミングだと、CW+PPの組み合わせの方が多そうだな、と思ったから。
もう、CプログラミングでもPB+IBの方が多いのかな。
428426:02/10/10 00:13 ID:ggYyHlG5
>>427
あぁなるほど。仕事でバリバリ組む人はそっちのが多いのかなぁ。
勉強し始めた俺は mi + Terminal だったりします。
429質問です。:02/10/10 03:03 ID:Sv5RKon6
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++;
}
}
430429続き:02/10/10 03:04 ID:Sv5RKon6
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;
}
431名称未設定:02/10/10 03:58 ID:y8tmBRM6
cryptとcript
432429:02/10/10 12:33 ID:Sv5RKon6
>>431
ありがとうございます。タイプミスだったすね。
なんだか恥ずかしいです、とても。

で、直すと無事コンパイルが通りまして
実行するとencryptや、decryptの中の
whileが実行されないようです。
このように文字列を扱うのは間違いなのでしょうか?
433名称未設定:02/10/10 13:09 ID:TJ2o8Ii8
while()ってのは
括弧の中が真である時に繰り返される。

-1ってのは文字列の最後に出てくるんだよね?
つまりpt[t] == -1が真になるのは・・・。
434415:02/10/10 14:18 ID:E9qOCXvY
>>432
whileループに入る条件が成立してませんね。

あと、文字列リテラルはナル文字で終わります。
それと、文字列リテラルは書き換えないようにしましょう。
435429:02/10/10 23:50 ID:Sv5RKon6
>>433,434
ご指摘ありがとうございます。
なるほどです。本をよく読めって感じですね。。。

とりあえずwhileのところは
while(pt[t] != '\0'){
とやってみるとうまくいきました。
ただ根本的な部分で間違いをしていまして
それについて考えています。
ユーグリッドの互除法(改)のやりかた。。
436429: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;
}
437429続き:02/10/11 03:47 ID:cGX7Km9y
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でもやってたほうがいいのでは。
439名称未設定:02/10/11 18:30 ID:dxlld3+G
>>436
うーん、少なくともポインタについては勉強したほうがいいと思う。
もし本を読んでるとしたら、理解が中途半端かor分かってない。
ポインタについてはこのスレの前の方で説明している人がいたはずです。
まず、これらをヒントに間違い探しをしてみましょう。
それと、できれば字下げしてください。
あなたも読みにくいでしょう?

>>438
Cを勉強したい、といっているのだし
Cを学んでからでもいいと思うが。Perlなんて将来どうなるか分からんし。
440Emacsうまうま:02/10/11 23:35 ID:D3K4wBGA
>>436
ソースが激しくきちゃない、、、
スレに書き込むためなのかもしれないですが、もうすこしなんとかした方がよいです。

個人的意見ですがどんなソースがきれいか判断できるという事は、意味がある程度
わかっているという事に近似だと思います。

ソースきちゃないのはよくわかっていないからだと思われます。
精進してください。

>>438
Perlは、、今から学ぶならPythonの方がいいです。
441名称未設定:02/10/11 23:56 ID:7ILM8oEP
どこが汚くて、どう書き換えたらいいか、例を出してあげないと
たぶん分からないと思われ。それをしないで言いっぱなしだと、
ただの自慢したがりに見えなくもない。
漏れはプログラミング、まったく分からない人なので、
「そういうならお前やれ」はなしね。
442名称未設定:02/10/12 00:47 ID:cug6SGxj
>>441
>>440氏が汚いって言ってるのは確かに、
ポインタに関する作法(それ自体はよく分からんけど)も含まれているだろうけど、
本当に基本的な作法を守っていないからだと思われます。
これは、どんな言語のコードを書く上で、守らなければならないモノで。
まぁ、多分>>440氏の言うように、スレに書き込むためかもしれませんが。

漏れ自身も初心者ですが、自分で調べたりなんなりしないと、身に付かないと思ってます。
もし、>>436自身が分からなければ、そう言えばいいだけの話だと思うし。
生意気で申し訳ないが。
443名称未設定:02/10/12 01:20 ID:mPnxXiHx
古い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;
}
444名称無設定:02/10/12 08:50 ID:KLGSCDT/
>>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には文字列と言う型は無くて、
プログラマが場所を用意してあげなければならないことを覚えておいてください。
445434: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されてます?
446445:02/10/13 16:44 ID:VvHAy8Li
あ、etextをmalloc()してませんね。
あと、malloc()したらfree()と憶えておきましょう(この場合いらないと言う
人もいるでしょうが)
447443:02/10/14 19:01 ID:Y8/UodjN
>>445
どうもありがとうです。
元のコードはインデントと変数の宣言部分しかみてません(w
ちゃんと直してあげればよかったですね。
>>446
うーん、いきなりmalloc使わずに
普通に配列で宣言してもいいんじゃないですかね。
あと気になったのは、引数のチェックをどこでしてるのか、ってところですか
この辺りは最初のうちに頭に入れといたほうがいいと思います。
448Emacsうまうま:02/10/14 21:10 ID:aCYxR+PI
>>441
例ですか。修正してしまった方がはやいのですが、それだと勉強にならない気
がしますし。

なぜきたないかは勉強するうちにわかるかという期待だと思ってほしいです。

>>443
おおきれいや。
ただchar* ptextとchar *etextがまざるのはいかがな物かと。

>>445氏適切やな、、わし頭さびてきてる(w

>>447
境界チェックとかいわゆる安全なプログラムの作り方の話しされてます?
Cではいろいろそのあたり気をつける事多すぎるやもしれず。

449Emacsうまうま:02/10/14 21:53 ID:UbbmMpwQ
今回の場合RSAそのものはしらないでもいいですが、参考までに。
http://www.faireal.net/articles/5/24/#d20524
http://www.maitou.gr.jp/rsa/
などを読むとためになるかもしれません。

450445
ソースの書き方については、この辺のページを読むといいと思います。
http://www.st.rim.or.jp/~phinloda/cprog.html

>>447
まあ、最初(というか練習プログラムのうち)はそこそこでいいんじゃ
ないでしょうか。