|
Name: 管理人 [URL] ..ハッカー(120,613ポイント)
Date: 2006/12/08(金) 17:18
No:2505
|
|
Title: 掲示板の仕様と変更報告
|
|
いつも掲示板をご利用くださいましてありがとうございます。皆様お世話になっていますm(_ _)m
掲示板の仕様を変更しましたので、変更点と、この際掲示板の仕様をお伝えします。
変更点
・投稿者は記事を消せないように変更(編集は可)
(前回トピがまるまる消されてしまった事への対策です)
・Newアイコンの表示時間を投稿から30時間→24時間へ変更
・入力フォームの装飾変更(見たままです)
仕様
・投稿は添付ファイルを含めて一度に120KBが限度
・最大投稿文字数は3000文字
・画像サムネイルサイズは175*175
・「マーク」で選択する「解決! 質問 雑談」はトピの内容として掲示板トップにトピの横へ表示される物。
・「マーク」はトピ主が入力する物(トピ主は最後に「解決!」を選択)
(つまりトピ主は最初質問か雑談のどちらかを選択する。返信者は選択の必要無し)
・「アイコン」は全員が選択する物で、記事の左にその記事の内容を表すものとして表示される。
・ポイントは投稿文字数に応じて多少ランダムに決まる。文字数が多いとポイントも多い。
・ポイントは一定量たまるとランクが上がる。(掲示板メニュー「昇進状態」から確認出来る)((ランクが上がっても別に何かあるわけではありません(汗)))
・トップの「検索」で検索する対象は過去ログ落ちしていない記事のみ(詳しくはメニュー「検索/過去ログ」から)。
・ソースコードの投稿は<pre></pre>のタグで囲むとインデントが綺麗に表示される。ソースの場合以外でも、文字の間隔をそろえたい時には使える。
・掲示板は携帯電話から閲覧可能。携帯用のURLはこちらから
http://www.play21.jp/phonemail.cgi?id=dixq
・(仕様ではないですが)記事の最後を</pre>で終えると、ポイントゲットログが右に表示されない。
以上です。他何かご要望・ご質問あれば、お聞かせください。
一点、よろしければ、お答えください。
普段トップのトピ表示数は10件ですが、1日に10以上のトピに投稿があった時は、2へのリンクへ落ちてしまい、24時間以内でも、New!アイコンは消えてしまいます。
しかし表示する画面サイズとして10件だと一般的だと思われる17インチモニタサイズにちょうど収まります。
トップのトピ表示数は10件がいいでしょうか、20件がいいでしょうか?
530ポイント を手に入れた。
|
|
|
|
Name: Justy ..プログラマー(34,103ポイント)
Date: 2006/12/08(金) 17:42
No:2508
|
|
Title: Re:掲示板の仕様と変更報告
|
|
投稿時のコメントの背景 "hai.jpg"の黒部分をもっと薄くしてもらえるとたすかります。
文字と被ると見にくくなりますので。
49ポイント を手に入れた。
|
|
|
|
Name: 管理人 [URL] ..ハッカー(121,050ポイント)
Date: 2006/12/08(金) 21:50
No:2519
|
|
Title: 雑談板
|
|
最近急に寒くなってきましたねぇ(>_<)
バイクに乗ってると特に完全防寒しないとめっちゃキツイです。
ところで12月になってあちこちクリスマスモードですね(*゜ー゜)
クリスマスが好きなわけじゃないですけど、あの綺麗なイルミネーションが好きで、あちこちイルミネーション見に行ったりします☆
特に京都駅のツリーは定番ですけど、毎年見に行きます♪
普段立ち食いうどんとかしか縁の無い私ですが、
前からチェックしていたフランス料理店が、クリスマスシーズンということで、弦楽四重奏の生演奏を聞きながら食事が出来るらしく、予約して行って見ました。
雰囲気もとても良く、木目のテーブルがあったかみのあって、とても良いところでした♪
何の演奏をしてほしいか希望を聞きに来てくれて、希望の曲を演奏してくれます“(。◕‿◕ฺ)
生演奏を聞きながら‥なんて普段まったく機会の無い事で、とても新鮮でした^^
・・・・し、しかし・・メニューに値段が載ってないヤツがある(汗)
まぁ大丈夫かと食事をし、・・・勘定すると・・・。
_
_
_
_
_
_
_
_
▄█▀█●ガーン
皆さんも普段と変わったとこで食事してはいかがでしょうか〜♪
252ポイント を手に入れた。
|
|
|
Name: まいこ ..ぴよぴよ(579ポイント)
Date: 2006/12/08(金) 04:04
No:2476
|
|
Title: 迷路
|
|
迷路の説き方について考えているのですが、お力お貸しください。
{
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0},
{0,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0},
{0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0},
{0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0},
{0,1,0,0,1,1,1,0,0,1,1,1,1,1,1,0},
{0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,1,1,1,1,1,1,0},
{0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
};
いまこのように配列に数字がはいっているんです。
0が壁で1が通れるとこだと思ってください。
プログラムで出口までいけるようにするにはどうしたらいいでしょうか?
579ポイント を手に入れた。
|
|
|
|
Name: 管理人 [URL] ..ハッカー(118,987ポイント)
Date: 2006/12/08(金) 04:13
No:2477
|
|
Title: Re:迷路
|
|
こういう迷路ですね。
■@■■■■■■■■■■■■■■
■ ■■■■■■■■■
■ ■■■■ ■■
■ ■■■■ ■■■■■■ ■■
■ ■■■■ ■■■■■■ ■■
■ ■■ ■■ ■
■ ■■ ■■■■ ■■■■■■
■■■■ ■■■■ ■
■■■■ ■■■■■■■■■ ■
■■■■■■■■■■■■■■A■
まず、図のように番号をつけましたが、どちらがゴールですか?
とりあえず@がスタートだとしますね。
こういうの再起関数うまくつかえば解ける気がしますね。
でも、再起で解く方法ぱっと思いつきません・・。
私が考え付く範囲でしたら、
自分のいる地点から過去に通った方向を除く進行方向に対して3方向を左から順に調べ、いけるほうにすすみます。
自分が現在むいている方向を変数に保存します。
いつも左から調べれば無限ループになることもないでしょう。
しかし、どうも再起関数の方がいいきがします。
ちょっと考えさせてください。
すみません。
2倍のポイントを手に入れた! 1,840ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(119,499ポイント)
Date: 2006/12/08(金) 05:44
No:2479
|
|
Title: Re:迷路
|
|
すみません、間違いが多かったので、先ほどの投稿消しました。
プログラム修正しました。
しかし、、すごく無駄な処理をしています・・。
必ずもっとスマートにかけると思います。。。
angleという向きを設定して、今の進行方向に対して
・左 進行方向 右
の順番にいけるかどうか調査し、いけなかったら戻ります。
いけるかどうかはその配列要素が0か1かで判断します。
常に進行方向に対して左から調査しているので、
同じいきどまりでうろうろすることはありません。
とうとう再起関数では書きませんでした。
一応できたので、これでいいか見てください。
ans関数の中はどうにもなりません・・。
これ以上スマートに書く方法自分では思いつきません。
ごめんなさい。
とりあえず修正版アップします。
迷路はもっと複雑にしました。
始点はi,jの宣言に代入してください。
終点の設定はいりません。一番下に来れば自動的に終了します。
これでやりたいことがあってるか確認してください。
汚いソースですみません・・・。
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#define R1 16
#define R2 16
int ans(int *angle,int **road,int *i,int *j){//angel 1=上 2=右 3=下 4=左
if(*angle==1){//上向きだったら
if(road[(*i)][(*j)-1]==1)//左にいけたら
(*j)-- , *angle=4;//左に進む
else if(road[(*i)-1][(*j)]==1)//上にいけたら
(*i)--;//上に進む
else if(road[(*i)][(*j)+1]==1)//右にいけたら
(*j)++ , *angle=2;//右に進む
else{//行き止まりなら
(*i)++;//来た方向へ戻る
*angle=3;//方向を変える。
}
}
else if(*angle==2){//右向きだったら
if(road[(*i)-1][(*j)]==1)//上にいけたら
(*i)-- , *angle=1;//上に進む
else if(road[(*i)][(*j)+1]==1)//右にいけたら
(*j)++;//右に進む
else if(road[(*i)+1][(*j)]==1)//下にいけたら
(*i)++ , *angle=3;//下に進む
else{//行き止まりなら
(*j)--;
*angle=4;
}
}
else if(*angle==3){//下向きだったら
if(road[(*i)][(*j)+1]==1)//右にいけたら
(*j)++ , *angle=2;//右に進む
else if(road[(*i)+1][(*j)]==1)//下にいけたら
(*i)++;//下に進む
else if(road[(*i)][(*j)-1]==1)//左にいけたら
(*j)-- , *angle=4;//左に進む
else{//行き止まりなら
(*i)--;
*angle=1;
}
}
else{//左向きだったら
if(road[(*i)+1][(*j)]==1)//下にいけたら
(*i)++ , *angle = 3;//下に進む
else if(road[(*i)][(*j)-1]==1)//左にいけたら
(*j)--;//左に進む
else if(road[(*i)-1][(*j)]==1)//上にいけたら
(*i)-- , *angle = 1;//上に進む
else{//行き止まりなら
(*j)++;
*angle=2;
}
}
if((*i)==R2-1)//一番下まで来たら
return 0;
else
return 1;
}
void disp(int **road,int i,int j){//表示関数
for(int s=0;s<R1;s++){
for(int t=0;t<R2;t++){
if(s==i && t==j)//今いる位置なら
printf("●");
else if(road[s][t]==0)
printf("■");
else
printf(" ");
}
printf("\n");
}
printf("\n\n\n");
return ;
}
int main(){
int road[R1][R2]={
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,0,0,1,0,1,0,1,1,0},
{0,1,0,1,0,0,1,1,1,1,1,1,1,1,0,0},
{0,1,0,1,1,0,1,0,0,1,0,1,0,1,0,0},
{0,1,0,1,0,0,1,0,1,0,0,0,0,1,0,0},
{0,1,0,0,1,1,1,0,1,1,1,1,1,1,1,0},
{0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0},
{0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,0},
{0,1,0,1,1,1,0,1,0,0,0,0,0,0,1,0},
{0,1,1,0,0,0,0,1,0,0,0,0,0,0,1,0},
{0,0,1,0,1,0,1,1,1,1,1,1,1,1,1,0},
{0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0},
{0,1,0,0,1,0,1,0,1,1,1,1,1,1,1,0},
{0,1,1,0,1,1,1,1,1,0,0,0,0,0,1,0},
{0,0,1,1,1,0,1,0,0,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0}
};
int *ptr[R2];
for(int s = 0; s < R2; s++)//別にこんな事しなくてもいいですが、一応2次元配列が**で受け取れるように
ptr[s] = road[s];
int **pp = &ptr[0];
{
int i=0,j=1,angle=3;
while(1){
system("cls");//画面クリア
if(ans(&angle,pp,&i,&j)==0)
break;
disp(pp,i,j);
Sleep(17*12);//17というのは60fpsの1fあたりの時間
}
disp(pp,i,j);
}
return 0;
}
1,516ポイント を手に入れた。
|
|
|
|
|
Name: 通りすがり ..かけだし(2,291ポイント)
Date: 2006/12/08(金) 08:51
No:2480
|
|
Title: Re:迷路
|
|
#include <stdio.h>
#include <string.h>
void Print(int maze[][16])
{
char *mark[] = {"■", " ", "x", };
int i, j;
for(i = 0; i < 10; i ++){
for(j = 0; j < 16; j ++){
printf("%s", mark[maze[i][j]]);
}
putchar('\n');
}
return;
}
int Search(int maze[][16])
{
int env, flag = 0, i, j;
for(i = 1; i < 9; i ++){
for(j = 1; j < 15; j ++){
if(maze[i][j] == 1){
env = maze[i-1][j] + maze[i + 1][j] + maze[i][j - 1] + maze[i][j + 1];
maze[i][j] = (env > 1);
flag += (env < 2);
}
}
}
return flag;
}
void Result(int maze[][16])
{
int temp[10][16];
int i, j;
memcpy(temp, maze, sizeof(int) * 10 * 16);
while(Search(temp)) ;
for(i = 0; i < 10; i ++){
for(j = 0; j < 16; j ++){
maze[i][j] += temp[i][j];
}
}
return;
}
int main(void)
{
int maze[][16] = {{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
{0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,},
{0,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,},
{0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,},
{0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,},
{0,1,0,0,1,1,1,0,0,1,1,1,1,1,1,0,},
{0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,},
{0,0,0,0,1,0,0,0,0,1,1,1,1,1,1,0,},
{0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,},};
Print(maze);
putchar('\n');
Result(maze);
Print(maze);
return 0;
}
2倍のポイントを手に入れた! 1,416ポイント を手に入れた。
|
|
|
|
|
Name: mas ..入門者(2,904ポイント)
Date: 2006/12/08(金) 10:36
No:2482
|
|
Title: Re:迷路
|
|
お久しぶりです。
通りすがりさんのやり方は面白いですね。
行き止まりから0が伝播して、最終的に道筋だけが残るんですね。
ただ行き止まりがループしていると、その部分も出力されてしまいますね。
例えば下のようなのです。
int maze[][16] = {{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
{0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,},
{0,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,},
{0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,},
{0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,},
{0,1,0,0,1,1,1,0,0,1,1,1,1,1,1,0,},
{0,1,0,0,1,0,1,0,0,1,0,0,0,0,0,0,},
{0,0,0,0,1,0,1,0,0,1,1,1,1,1,1,0,},
{0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,0,},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,},};
管理人さんはans関数あたりが苦労されたようなので、簡潔にしてみました。
int ans(int *angle,int **road,int *i,int *j){//angel 0=上 1=右 2=下 3=左
int dx[] = {0, 1, 0, -1};
int dy[] = {-1, 0, 1, 0};
for(int k=0;k<4;k++) {
if(road[*i+dy[(*angle+3+k)%4]][*j+dx[(*angle+3+k)%4]] == 1) {
*i += dy[(*angle+3+k)%4], *j += dx[(*angle+3+k)%4], *angle = (*angle+3+k)%4;
break;
}
}
if((*i)==R2-1)//一番下まで来たら
return 0;
else
return 1;
}
angleを0から始めるようにしたのでmain関数での初期化はangle=2にしてください。
793ポイント を手に入れた。
|
|
|
|
|
Name: box ..中級者(14,643ポイント)
Date: 2006/12/08(金) 11:22
No:2483
|
|
Title: Re:迷路
|
|
お目汚しのコードです。
再帰関数を作ってみました。
先へ進めなくなったら前の分岐まで戻って別の道を探す、
という手順を出力しています。
#include <stdio.h>
#include <stdlib.h>
#define X (16+2) /* +2は周囲の壁 */
#define Y (10+2) /* +2は周囲の壁 */
#define START_X (2)
#define START_Y (1)
#define GOAL_X (15)
#define GOAL_Y (10)
void visit(int maze[][X], int x, int y);
int main(void)
{
int maze[Y][X] = { /* X:水平方向、Y:垂直方向 */
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
};
visit(maze, START_X, START_Y);
return 0;
}
void visit(int maze[][X], int x, int y)
{
if (maze[y+1][x] == 1 ||
maze[y-1][x] == 1 ||
maze[y][x+1] == 1 ||
maze[y][x-1] == 1)
printf("(%d,%d)\n", x, y);
if (x == GOAL_X && y == GOAL_Y) {
printf("(%d,%d)\n", x, y);
printf("GOOOOOAL!!\n");
exit(EXIT_SUCCESS);
}
if (maze[y+1][x] == 1)
maze[y+1][x] = 0, visit(maze, x, y+1), maze[y+1][x] = 1;
if (maze[y-1][x] == 1)
maze[y-1][x] = 0, visit(maze, x, y-1), maze[y-1][x] = 1;
if (maze[y][x+1] == 1)
maze[y][x+1] = 0, visit(maze, x+1, y), maze[y][x+1] = 1;
if (maze[y][x-1] == 1)
maze[y][x-1] = 0, visit(maze, x-1, y), maze[y][x-1] = 1;
}
1,400ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(119,558ポイント)
Date: 2006/12/08(金) 14:16
No:2485
|
|
Title: Re:迷路
|
|
通りすがりさん、
面白い書き方があるもんですね。参考になります(>_<)
maze[i][j] = (env > 1);
flag += (env < 2);
このような書き方ができるんですね‥思いつきませんでした(_ _||)
masさん、
なるほど〜!そのようにすればよかったんですね。
どうしてもあれ以上先に進めませんでした; 所詮実力もその程度・・・。
なんか実力テストみたいですね^^;
boxさん、
なるほど、再起関数はそう書くんですね。
こういう場合は再起関数を使った方がいいんでしょうか?何が一番最適なんでしょう。
59ポイント を手に入れた。
|
|
|
|
|
Name: GPGA ..中級者(13,722ポイント)
Date: 2006/12/08(金) 15:03
No:2493
|
|
Title: Re:迷路
|
|
プログラム豆知識として一つだけ。
C言語の比較演算の結果は、それが真ならば非0、偽ならば0が返るのが仕様となっています。
ほとんどの処理系では、真の場合1が返りますが、ある特定の処理系に置いては真の時に-1が返ります。
> maze[i][j] = (env > 1);
したがって、特定の処理系では、この時にmaze[i][j]に-1が入る可能性も否定できません。
ただ私は、いままで真に1が入らないコンパイラに出会ったことは一回もありません。
94ポイント を手に入れた。
|
|
|
|
|
Name: GPGA ..中級者(13,846ポイント)
Date: 2006/12/08(金) 15:41
No:2495
|
|
Title: Re:迷路
|
|
>そんな処理系があるとは・・・。
以前デジタルトキワ荘のプログラム掲示板でその話が書かれていました。
その時、処理系も書かれていたのですけど、昔トキワ荘の管理人が借りていたサーバ側のミスかなにかで
プログラム板のすべてデータが飛んだことがあり、それと一緒に消えてしまいましたため
残念ながらその記事は現在は存在しません。
124ポイント を手に入れた。
|
|
|
|
|
Name: keichan ..初心者(7,220ポイント)
Date: 2006/12/08(金) 15:51
No:2497
|
|
Title: Re:迷路
|
|
>>したがって、特定の処理系では、この時にmaze[i][j]に-1が入る可能性も否定できません。
確かにそうですね。
FALSEは「0」、TRUEは「非0」と仕様で決められていますからTRUEが1である必要はありません。
#コンパイラベンダが勝手に決めていい
>maze[i][j] = (env > 1);
>flag += (env < 2);
では処理系依存にならない書き方をすると
maze[i][j] = (env > 1) ? 1 : 0;
flag += (env < 2) ? 1 : 0;
とかけば問題ないですね。
2倍のポイントを手に入れた! 298ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..プログラマー(34,054ポイント)
Date: 2006/12/08(金) 16:07
No:2500
|
|
Title: Re:迷路
|
|
今ちょっと調べてみましたが、JIS X3010の規格書によると < > >= <= の各演算子の結果は int型で真の場合は 1を返す(6.5.8)ことが保証されているようです。
そのコンパイラはC言語に準拠していなかったか、昔の古い規格では -1を返してもよかったのか・・・。
> 以前デジタルトキワ荘のプログラム掲示板でその話が書かれていました。
懐かしい名前です(w
136ポイント を手に入れた。
|
|
|
|
|
Name: GPGA ..中級者(13,893ポイント)
Date: 2006/12/08(金) 16:15
No:2501
|
|
Title: Re:迷路
|
|
私も規格を確認しようと思い、JISの無料閲覧ページのpdfを選択して30分。
「。。。ただ今、ファイルを開いております。しばらくお待ちください。」が
まだ出ています。orz
47ポイント を手に入れた。
|
|
|
|
|
Name: keichan ..初心者(7,333ポイント)
Date: 2006/12/08(金) 16:38
No:2503
|
|
Title: Re:迷路
|
|
あぁ・・・確かにありますね。
|6.5.8 関係演算子
|<(小さい), >(大きい), <=(以下) 及び>=(以上) の各演算子は,指定された関係が真の場合は 1
|を,偽の場合は0を返す。その結果は,型intをもつ。
失礼しました。
12ポイント を手に入れた。
|
|
|
|
|
Name: GPGA ..中級者(13,806ポイント)
Date: 2006/12/08(金) 17:05
No:2504
|
|
Title: Re:迷路
|
|
いまだ、pdfは開けずorz
やはり、規格書は持っていたほうがいいですね。
結構な値段が張りますし、特に見ることもないと思っていたので
購入を見合わせていましたが、何かあったとき、正しい事実を確認するために
購入しようと思います。
87ポイント を落としてしまった。
|
|
|
|
Name: こまってます ..ぴよぴよ(219ポイント)
Date: 2006/12/08(金) 14:14
No:2484
|
|
Title: 乱数
|
|
1から1000の乱数を1000個発生させ、文字にすることができる数字はいくつあるか、また、もじにできるものは文字に変換しファイルに保存する というもんだいで
int main (void)
{
int i,n;
srand ((unsigned)time(NULL));
printf("1〜1000:\n");
for(i=1; i<=1000;i++)
1から1000の乱数を1000個発生させるという部分はこのような感じになるのではないかと予想してみたのですが、後の部分が教科書を見てもまったくわからずこまっています どなたかおねがいします
219ポイント を手に入れた。
|
|
|
|
Name: 管理人 [URL] ..ハッカー(119,634ポイント)
Date: 2006/12/08(金) 14:19
No:2486
|
|
Title: Re:乱数
|
|
こまってますさん、こんにちは。管理人です。
今回文字にすることが出来る数字はいくつかということですが、
数字はみな、文字に出来ると思います。
そこのとこ、「文字に出来る数字は」という意味がよくわからないのですが、
文字に出来ない数字とはたとえば何ですか?
76ポイント を手に入れた。
|
|
|
|
|
Name: box ..中級者(14,930ポイント)
Date: 2006/12/08(金) 14:32
No:2488
|
|
Title: Re:乱数
|
|
たぶん、こんなことがしたいのではないかという例です。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
int main(void)
{
FILE *fp;
int i, n;
/* 結果出力用ファイルのオープン */
fp = fopen("output.txt", "w");
if (fp == NULL)
fprintf(stderr, "file open error\n"), exit(1);
/* 乱数の初期化 */
srand((unsigned int) time(NULL));
for (i = 0; i < 1000; i++) /* 指定回数分だけ繰り返す */
if (isprint(n = rand() % 1000 + 1)) /* 1〜1000の乱数が表示可能なら */
fprintf(fp, "%4d %c\n", n, n); /* ファイルに出力する */
/* ファイルを閉じて終了 */
fclose(fp);
return 0;
}
287ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..プログラマー(33,864ポイント)
Date: 2006/12/08(金) 14:50
No:2491
|
|
Title: Re:乱数
|
|
MSVC7.1のその関数は引数は int型でも値が 255以下でないとそのアサートが出てしまいます。
もともと文字にできるかどうかの判定は、各環境に依存してしまうので、結構この問題は難しいです。
文字コードも SJIS/JIS/EUC/Unicodeとそれぞれによっても判定が異なりますし。
65ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(119,713ポイント)
Date: 2006/12/08(金) 14:55
No:2492
|
|
Title: Re:乱数
|
|
なるほど。
とりあえず私の環境では、ASCIIを使って
こんな感じで表示は出来ます・・。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main () {
int i,n,count=0;
srand ((unsigned)time(NULL));
for(i=0;i<1000;i++){//1000回ループ
n=rand()%1000+1;//1〜1000の乱数生成
if(n>=33 && n<=126){//ASCIIの文字範囲なら
printf("文字コード[%3d] 変換文字[%c]\n",n,(char)n);
count++;//文字数カウント
}
}
printf("\n%d個\n",count);
return 0;
}
7ポイント を手に入れた。
|
|
|
|
Name: オルムント ..ぴよぴよ(56ポイント)
Date: 2006/12/08(金) 01:21
No:2454
|
|
Title: 特定の文字数を数えるには
|
|
質問させていただきます。
問題
"(",")"が何個含まれているか数えなさい。
表示例
(((()()(()
"(" = 7
")" = 3
どうやって作るのでしょうか。
まったく見当もつかないのでお願いします。
56ポイント を手に入れた。
|
|
|
|
Name: 管理人 [URL] ..ハッカー(115,802ポイント)
Date: 2006/12/08(金) 01:46
No:2455
|
|
Title: Re:特定の文字数を数えるには
|
|
こんにちは、管理人です。
配列にその文字列を格納し、
配列の最初から順番に中身を比較し、カウントしていけばいいですよ。
st[]に文字列を格納したのなら
if(st[i]=='(')
count1++;
if(st[i]==')')
count2++;
こんな感じです。
文字列は入力されたものですか?
それとも最初から固定の文字列ですか?
10ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(116,263ポイント)
Date: 2006/12/08(金) 01:55
No:2456
|
|
Title: Re:特定の文字数を数えるには
|
|
まず、
(を数えるcount1という変数を用意し、
)を数えるcount2という変数を用意します。
また、文字列の長さを格納するlenという変数も用意します。
int count1=0,count2=0,len;
stに文字列を格納します。
char st[]="(((()()(()";
文字列の長さを取得するstrlen関数を使ってlenに文字列の長さを格納します。
この関数を使うためにstring.hをインクルードする必要があります。
len = strlen(st);
for文で配列の要素数だけループさせます。
先ほど測定したlenの値だけループさせます。
for(int i=0;i<len;i++){
もし今調べている配列要素が(ならcount1++し
if(st[i]=='(')
count1++;
今調べている配列要素が)ならcount2++します。
else if(st[i]==')')
count2++;
}
後は表示するだけ。
printf("%s\n\n",st);
printf("\"(\"=%d\n",count1);
printf("\")\"=%d\n",count2);
return;
}
こちらがそれをまとめたものです。
これ実際に実行してみて自分がやりたいこととあってるか確認してください。
#include <stdio.h>
#include <string.h>
void main(){
int count1=0,count2=0,len;
char st[]="(((()()(()";
len = strlen(st);
for(int i=0;i<len;i++){
if(st[i]=='(')
count1++;
else if(st[i]==')')
count2++;
}
printf("%s\n\n",st);
printf("\"(\"=%d\n",count1);
printf("\")\"=%d\n",count2);
return;
}
461ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(116,526ポイント)
Date: 2006/12/08(金) 02:03
No:2458
|
|
Title: Re:特定の文字数を数えるには
|
|
あ、後表示にはエスケープシーケンスを使っています。
"
↑ダブルコーテーション は普通表示できません。
普通に表示させようとすると
printf(""");
こんな感じになってしまいます。
しかしこれはダブルコーテーションで囲んだことになりません。
printf("1" "2");
こんな書き方もあるので、ダブルコーテーションが3つっていうのは変です。
" を表示させるにはどうしたらいいか?
それは「"」の前に「\」をつけることです。
そうすることで、「"」が表示できるようになります。
191ポイント を手に入れた。
|
|
|
|
|
Name: オルムント ..ぴよぴよ(0ポイント)
Date: 2006/12/08(金) 02:19
No:2459
|
|
Title: Re:特定の文字数を数えるには
|
|
すごくわかりやすい解説ありがとうございます。
文字列は自分で入力のものです。
色々と試してみたのですが、教えてもらったものだとエラーが出てしまいます。
iが宣言されてなかったので宣言しました。
他にエラーの要因になるところが見当たらないのですが何故エラーになるのでしょうか?
お願いします。
136ポイント を落としてしまった。
|
|
|
|
|
Name: Justy ..プログラマー(33,397ポイント)
Date: 2006/12/08(金) 02:38
No:2463
|
|
Title: Re:特定の文字数を数えるには
|
|
>エラーの要因になるところが見当たらないのですが何故エラーになるのでしょうか?
エラーですか。
あぁ、C++形式で書かれていますね。
変数 iの宣言位置を直したのであれば、後は strlenの戻り値は intではないので、そのあたりで警告が出ているのではないでしょうか。
ちょっと強引なのであまり多用して欲しくはないですが、下のようにすれば手っ取り早く解決できるかと思います。
len = (int)strlen(st);
267ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(116,676ポイント)
Date: 2006/12/08(金) 02:39
No:2464
|
|
Title: Re:特定の文字数を数えるには
|
|
iはfor文の中で宣言してあります。
Cだと宣言は最初に宣言しないとエラーになるので、環境があわなかったのですね。
すみません。
(C++のコンパイラだとどこで宣言してもいいので)
エラーになったときのメッセージになんと書いてありますか?
コピペしてもらったらわかりやすいです。
150ポイント を手に入れた。
|
|
|
|
|
Name: オルムント ..ぴよぴよ(110ポイント)
Date: 2006/12/08(金) 02:52
No:2467
|
|
Title: Re:特定の文字数を数えるには
|
|
迅速な対応感謝します。
試してみた変更点は
1.for文の中でのiの宣言を最初にしました。
2.len = (int)strlen(st);に変更しました。
です。
エラーは
「配列または、ポインタでない変数に添字が使われました。」というエラーです。
if(st[i]=='(')
else if(st[i]==')')
上記の2行がエラーの原因のようなのですがどうでしょうか?
110ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(116,948ポイント)
Date: 2006/12/08(金) 03:05
No:2468
|
|
Title: Re:特定の文字数を数えるには
|
|
Justyさん、
そういう小さい(?)警告がぜんぜん出ないんですよ私の使ってるVS2003。
なんでなんでしょう??
前も返り値の型間違ってたのに全然警告でなくて気づきませんでした。
後、返り値はsize_tですよね。size_tってunsigned intと同じでしたっけ?
intに変換して何か悪い事起きます?あれば教えてください。
私の考える範囲ではintの領域を超えてしまわない限りおきないと思ってました。
オルムンとさん、
stの宣言の部分ちゃんとサンプルと同じように宣言されてますか?
116ポイント を手に入れた。
|
|
|
|
|
Name: オルムント ..ぴよぴよ(59ポイント)
Date: 2006/12/08(金) 03:23
No:2469
| 解決!
|
Title: Re:特定の文字数を数えるには
|
|
すみません
宣言を
char st;
と配列にしてなかったのが原因です。
書き直し、実行できました。
#include <stdio.h>
#include <string.h>
int main(){
int count1=0,count2=0,len,i;
char st[256];
scanf("%s",st);
len = strlen(st);
for(i=0;i<len;i++){
if(st[i]=='(')
count1++;
else if(st[i]==')')
count2++;
}
printf("\"(\"=%d\n",count1);
printf("\")\"=%d\n",count2);
return 0;
}
夜分遅くに迅速な対応本当に感謝します。
ありがとうございました。
51ポイント を落としてしまった。
|
|
|
|
|
Name: Justy ..プログラマー(33,799ポイント)
Date: 2006/12/08(金) 03:30
No:2470
|
|
Title: Re:特定の文字数を数えるには
|
|
>そういう小さい(?)警告がぜんぜん出ないんですよ私の使ってるVS2003
2003だと・・・64bit移植への対応が有効になっていて、警告レベルが3以上で出ます。
>size_tってunsigned intと同じでしたっけ?
大抵はそうみたいです。
環境によっては違うかもしれません。
規定では符号なしの整数としか決まっていませんから・・・。
>intに変換して何か悪い事起きます?あれば教えてください。
sizeof(size_t)==sizeof(int)が確実に保証できれば、実害はほぼないはずです。
文字列のサイズが intで扱える範囲を超えてなければ・・・。
2倍のポイントを手に入れた! 402ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(117,105ポイント)
Date: 2006/12/08(金) 03:42
No:2473
|
|
Title: Re:特定の文字数を数えるには
|
|
Justyさん、なるほど、ありがとうございます。
逆にここで質問してしまいましたm(_ _)m
文字列のサイズがintの扱える範囲を超えることは無いかと思ったのですが
lenに格納するのに正しくはどう書けばいいのでしょう?
lenをsize_tで宣言して、
for( i = 0 ; i < (int)len ; i++)
でしょうか?でも、これだと結局同じ事か・・。
84ポイント を手に入れた。
|
|
|
|
Name: darue ..ぴよぴよ(242ポイント)
Date: 2006/12/08(金) 02:24
No:2461
|
|
Title: コンパイルが出来ません・・・
|
|
初めまして。お忙しいとは思いますが、エラーメッセージの意味だけでもご教授意していただければと思い質問させていただきました。宜しくお願いいたします。。
自宅でC言語のプログラムをコンパイルしたところ
「:61:8: warning: unknown escape sequence: '\211'
:62:8: warning: unknown escape sequence: '\211' 」
というエラーメッセージが出てしまいました。
問題の箇所は
「printf("五十円硬貨が%d枚です\n",x[5]);
printf("十円硬貨が%d枚です\n",x[6]);」
という文です。
このエラーはどういったことが原因なのでしょうか?
242ポイント を手に入れた。
|
|
|
|
Name: darue ..ぴよぴよ(77ポイント)
Date: 2006/12/08(金) 03:44
No:2474
| 解決!
|
Title: Re:コンパイルが出来ません・・・
|
|
「GNUの gcc/g++ は、日本語シフトJISコードに完全に対応していません。そのために、
Windows 95/98 などのシフトJISコード・ベースの環境では、特定の文字で問題を起こし
ます。」
ということでした。
→小生の文中の「十」が対応していなかったことから生じた問題でした。
管理人さんのすばやい返信のお蔭で迅速に解決できました。
有難う御座いました。。
今回は「品物の代金」と「支払った金額」を入力して、御釣の紙幣と硬貨の枚数を出力するプログラミングを作成しました。
これからもこのサイトを見ながら、様々な勉強をしていきたいと思います。
度々質問させていただくこともあるやもしれませんが、その時は是非とも宜しくお願いいたします。
165ポイント を落としてしまった。
|
|
|
|
Name: 高校生 ..ぴよぴよ(53ポイント)
Date: 2006/12/07(木) 13:44
No:2426
|
|
Title: 約数を求める問題について
|
|
はじめまして、高校2年生です 授業でだされた 「1から1000までの間の3の約数を求めるプログラムを作成せよ」t歩い問題で 1と3 が答えとして出てくればいいというのはわかったのですが、処理をどうやって書いていいかわかりません 教えていただけませんでしょうか
53ポイント を手に入れた。
|
|
|
|
Name: box ..中級者(12,973ポイント)
Date: 2006/12/07(木) 13:53
No:2427
|
|
Title: Re:学校の課題について
|
|
3の「倍数」ではないのですか?
3の約数ならば、別に1000までという範囲を決めなくても
最初から1と3だけに決まってますよね。
54ポイント を手に入れた。
|
|
|
|
|
Name: バグ ..上級者(15,211ポイント)
Date: 2006/12/07(木) 14:12
No:2428
|
|
Title: Re:学校の課題について
|
|
3÷nの計算を行い、余りが0の数値を表示すればいいというところまでは分かりますね?
ここまで分かれば、nが1〜1000の間だけ処理を繰り返せばいい訳ですが、このやり方が分からないという事でしょうか?
まず、nが1〜1000の間だけ繰り返す処理ですが、ループのやり方は習ってますか?while文や、for文と呼ばれているやつを使用するのが一般的だと思うのですが、こういう課題が出ているくらいですから、習っているものとして話をすすめますので、分からなければ質問してください。
今回は1〜1000の間だけ繰り返すという処理ですから、for文の方が理解しやすいかと思いますので、こちらを利用します。
int n;
for( n = 1 ; n <= 1000 ; n++ )
{
}
こんな風に使います。始めに変数nに1を代入して、nが1000以下の間だけループを続けて、ループを1周する毎にnの数値に1を足しなさいという意味です。つまり、nが1から始まって、1001になった時点でループが終了する訳です。
次に肝心の計算部分ですが、3÷nの計算をした余りを求める式というのは…
int val;
val = 3 % n;
こんな感じに表記します。今回の課題の場合は、約数を求めるという事ですから、余りが0の時だけ画面に表示すればいいので、valが0の時だけnを表示するという条件分岐を行う必要があります。これを実現させるにはif文を利用します。
if( val == 0 )
{
printf( "%d" , n );
}
こんな感じですね。
あとは前記のループと計算部分を組み合わせるだけです。ほぼ回答のようになってしまいましたが、ここから先は自分で何とかしてみてください。その方が理解度が高くなるはずですしね。
もし、どうしても分からなければ、何が分からなかったかを書き込みしていただければ、できる限りお答えしますので、頑張ってみてください(^-^)
490ポイント を手に入れた。
|
|
|
|
|
Name: バグ ..上級者(15,254ポイント)
Date: 2006/12/07(木) 15:46
No:2430
|
|
Title: Re:学校の課題について
|
|
>>バグさん、アイコンが管理人になってたので、「回答」にしておきました^^;
うわっ、失礼しました〜(^_^;)
43ポイント を手に入れた。
|
|
|
|
|
Name: 高校生 ..ぴよぴよ(0ポイント)
Date: 2006/12/07(木) 17:50
No:2431
|
|
Title: Re:学校の課題について
|
|
早速のアドバイスありがとうございます 何度確かめても「約数」を求めるとなっています。課題を作成した先生もはっきり約数だと言っていました
65ポイント を落としてしまった。
|
|
|
|
|
Name: box ..中級者(13,059ポイント)
Date: 2006/12/07(木) 18:31
No:2434
|
|
Title: Re:学校の課題について
|
|
約数で合っているのですか…。
そうすると、「1000までの数」は、
実は3以上なら何でもよくなります。
1000でなければならない理由がないですね。
倍数ならば、上限の数によって出力結果が変わりますので、
「〜まで」には十分に意味がありますが…。
86ポイント を手に入れた。
|
|
|
|
|
Name: 高校生 ..ぴよぴよ(142ポイント)
Date: 2006/12/07(木) 18:41
No:2437
|
|
Title: Re:学校の課題について
|
|
boxさんへ
同じように先生に「出てくるのは 1と3なので1000まで繰り返す必要ないんじゃないんですか」とお聞きしたところ、「ちょつとした引っ掛け問題だよ、とにかくめんどくさくても1000の値までの処理を繰り返し、その間の約数として 1と3がでてくればいいだけだよ」 といわれたのですが、 現在よくわからず混乱しています
142ポイント を手に入れた。
|
|
|
|
|
Name: 高校生 ..ぴよぴよ(27ポイント)
Date: 2006/12/07(木) 20:02
No:2443
|
|
Title: Re:学校の課題について
|
|
#include <stdio.h>
int n, val;
val = 3 % n;
for( n = 1 ; n <= 1000 ; n++ )
if( val == 0 )
printf( "%d" , n );
}
return 0
}
アドバイスを参考に自分で作ってみたのですが、こんな感じになったのですが大丈夫でしょうか 違っているところなど ご指摘よろしくおねがいします
115ポイント を落としてしまった。
|
|
|
|
|
Name: バグ ..上級者(15,388ポイント)
Date: 2006/12/07(木) 20:26
No:2446
|
|
Title: Re:学校の課題について
|
|
1:main関数が無い
2:値が割り当てられてないnを使っている
3:}の数がおかしい
4:return 0の後ろに;がない
5:valを計算している場所がおかしい
以上の不具合を考慮したサンプルです。
#include <stdio.h>
int main()
{
int n, val;
for( n = 1 ; n <= 1000 ; n++ )
{
val = 3 % n;
if( val == 0 )
printf( "%dn" , n );
}
return 0;
}
134ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(115,488ポイント)
Date: 2006/12/07(木) 23:54
No:2449
|
|
Title: Re:学校の課題について
|
|
高校生さん、
解決されましたか?
先生の回答からして、keichanさんの推測どおりとしか考えられません・・。
無駄な計算をかなりするようですが、
バグさんの回答が最適だと思います。
お書きになったプログラムですが、
#include <stdio.h>
ここ、int main(){
とかかないとダメです。どんなプログラムでも、必ずmain関数が必要です。
途中でプログラムかいてて消してしまっただけなんでしょうか?
int n, val;
val = 3 % n;
これでは、ループの中で計算ができません。
1000まで計算したいのならループの中で計算しましょう。
for( n = 1 ; n <= 1000 ; n++ )
ここには括弧のはじまりがひつようです。
if( val == 0 )
printf( "%d" , n );
printfは改行コードをかかないと次表示する値と連続してしまい、わからなくなってしまいます。
}
return 0
}
54ポイント を手に入れた。
|
|
|
|
|
Name: 高校生 ..ぴよぴよ(46ポイント)
Date: 2006/12/08(金) 02:21
No:2460
| 解決!
|
Title: Re:学校の課題について
|
|
ありがとうございました。一歩ずつですががんばっていけそうです
19ポイント を手に入れた。
|
|
|
|
Name: ★ ..かけだし(1,230ポイント)
Date: 2006/12/05(火) 22:51
No:2404
|
|
Title: 構造体
|
|
gstudent構造体を定義し,ユーザからの入力を3人分(fusayoshi,taro, hanako)受付けて,入力後に全員のデータを表示するプログラムを作成せよ.また構造体への値の代入は,struct gstudent set_gstudent();という関数の内部で行い,返り値として値の入った構造体を受け取るようにすること.
#include<stdio.h>
#include<string.h>
struct gstudent{
char name[20];
int height;
float weight;
int math;
long schols;
};
void show_profile(struct gstudent user_prof) {
printf("名前:%s, 身長:%d, 体重:%f, 数学の成績:%d,奨学金:%ld\n", user_prof.name, user_prof.height, user_prof.weight, user_prof.math,user_prof.schols);
}
struct gstudent set_gstudent(char username[],int userheight,float userweight,int usermath,long userschols){
struct gstudent temp;
strcpy(temp.name,username);
temp.height=userheight;
temp.weight=userweight;
temp.math=usermath;
temp.schols=userschols;
return temp;
}
int main(void) {
struct gstudent fusayoshi,taro,hanako,user_prof;
printf("fusayoshiのデータを入力してください\n");
printf("Fusayoshi\n");
scanf("%s,%d,%f,%d,%ld",user_prof.name,user_prof.height,user_prof.weight,user_prof.math,user_prof.schols);
printf("taroのデータを入力してください\n");
printf("Taro\n");
scanf("%s,%d,%f,%d,%ld",user_prof.name,user_prof.height,user_prof.weight,user_prof.math,user_prof.schols);
printf("hanakoのデータを入力してください\n");
printf("Hanako\n");
scanf("%s,%d,%f,%d,%ld",user_prof.name,user_prof.height,user_prof.weight,user_prof.math,user_prof.schols);
show_profile(fusayoshi);
show_profile(taro);
show_profile(hanako);
return 0;
}
こんなプログラムを作ったのですが、
実行結果が、
fusayoshiのデータを入力してください
Fusayoshi
172,47.2,56,10000
taroのデータを入力してください
Taro
176,60.0,81,50000
hanakoのデータを入力してください
Hanako
165,48.1,75,30000
名前:n@h 奎須 hi@, 身長:-1073743908, 体重:-1.999742, 数学の成績:134514126,奨学金:1075145064
名前:, 身長:0, 体重:2.139266, 数学の成績:1073826116,奨学金:1073826712
名前:wK@, 身長:1073918700, 体重:2.020582, 数学の成績:0,奨学金:0
こんな事になってしまうんですが、どこが可笑しいか教えてもらえませんでしょうか?お願いします。
1,230ポイント を手に入れた。
|
|
|
|
Name: 通りすがり ..ぴよぴよ(875ポイント)
Date: 2006/12/06(水) 00:13
No:2406
|
|
Title: Re:構造体
|
|
#include <stdio.h>
struct gstudent{
char name[20];
int height;
float weight;
int math;
int schols;
};
struct gstudent set_gstudent(char *name)
{
struct gstudent student;
char buff[64];
printf("%s のデータを入力してください。\n%s\n", name, name);
sscanf(name, "%s", student.name);
fgets(buff, 64, stdin);
sscanf(buff, "%d,%f,%d,%d", &student.height,&student.weight,
&student.math, &student.schols);
return student;
}
void print_gstudent(struct gstudent student)
{
printf("名前:%s, ", student.name);
printf("身長:%d, ", student.height);
printf("体重:%.2f, ", student.weight);
printf("数学の成績:%d, ", student.math);
printf("奨学金:%d\n", student.schols);
return;
}
int main(void)
{
char *name[] = {"Fusayoshi", "Taro", "Hanako"};
struct gstudent student[3];
int i;
for(i = 0; i < 3; i ++) student[i] = set_gstudent(name[i]);
for(i = 0; i < 3; i ++) print_gstudent(student[i]);
return 0;
}
489ポイント を手に入れた。
|
|
|
|
|
Name: ★ ..かけだし(1,310ポイント)
Date: 2006/12/06(水) 18:58
No:2424
| 解決!
|
Title: Re:構造体
|
|
あっ!!!できました★
でも書いてあるのと私が作ったのは全然違ったです。
新しい勉強ができました。
ありがとうございます。
55ポイント を手に入れた。
|
|
|
|
Name: 困ったさん ..ぴよぴよ(936ポイント)
Date: 2006/12/06(水) 15:35
No:2414
|
|
Title: 家でコンパイル出来る環境作り
|
|
学校だけじゃプログラミングができる時間に限りがあるので、
自宅でもプログラミングをしたいんですけど…。
WindowsXPの環境で、できれば無料でできるものってありますか?
61ポイント を手に入れた。
|
|
|
|
Name: 困ったさん ..ぴよぴよ(981ポイント)
Date: 2006/12/06(水) 15:59
No:2416
|
|
Title: プログラミングソフト
|
|
BCC Developer と Borland C++ Compiler をダウンロードすれば
使えますか?
あと、CとC++では何か違いがありますか?
45ポイント を手に入れた。
|
|
|
|
|
Name: box ..中級者(12,919ポイント)
Date: 2006/12/06(水) 16:24
No:2417
|
|
Title: Re:プログラミングソフト
|
|
> BCC Developer と Borland C++ Compiler をダウンロードすれば
> 使えますか?
使えます。
ただし、Borland C++ Compilerのための環境設定が必要です。
エディタなどを使って設定用ファイルを手で書き換えてもいいですが、
http://www.cmagazine.jp/setbcc.html
などのサイトで紹介している「環境設定ファイル作成ソフト」を
使うと楽でしょう。
「setbcc」でGoogleなどを引くと、多くのサイトがヒットします。
> あと、CとC++では何か違いがありますか?
C++は、Cをベースとして誕生した、オブジェクト指向の考え方を
採り入れているプログラミング言語です。
Cでできることは、C++でもできるはずです。
C++は、Cに比べて文法や機能の面で大きく拡張されています。
その分、マスターするには時間と努力を必要とするでしょう。
128ポイント を手に入れた。
|
|
|
|
|
Name: 困ったさん ..かけだし(1,082ポイント)
Date: 2006/12/07(木) 13:04
No:2425
| 解決!
|
Title: Re:プログラミングソフト
|
|
昨日みなさんが紹介してくれたサイトを参考にして自宅でも
プログラミングができるようにパソコンを設定しました。これでいつでも暇なときに
プログラミングができます。これからいろいろ試して、間違えながらCの知識を
深めていこうと思います。みなさんありがとうございました。
101ポイント を手に入れた。
|
|
|
|
Name: mika ..ぴよぴよ(45ポイント)
Date: 2006/12/07(木) 18:05
No:2433
|
|
Title: ポインタの値
|
|
ポインタを習い始めましたが、よく分からないので質問させてもらいます。
いろいろやってみたのですが独学なので本当に困っています。
どうかお願い致します・・・
問題は↓のようなものです
以下のプログラムを実行した場合に、各変数の値は@〜Cの時点で順次どの
ような値になっているか。
ただし、32bit処理系で実行しているものとし、n[0]、n[1]、・・・は夫々
0x1000番地、0x1004番地、・・・に存在するものとする。
/********************************************************************/
int n[7] = {0,1,2,3,4,5,6}; /* int型の配列を宣言し初期値を設定 */
int *p; /* ポインタ変数を宣言 */
p = &n[0]; /* ポインタ変数を初期化 */
*p = 5; /* ポインタを利用して値を変更 */
/* @この時点で、pの値とn[0]〜n[6]の各値は何か? */
p++; /* ポインタ変数をインクリメント */
*p = 6; /* ポインタを利用して値を変更 */
/* Aこの時点で、pの値とn[0]〜n[6]の各値は何か? */
p = &n[5]; /* ポインタ変数の値を変更 */
*p = 7; /* ポインタを利用して値を変更 */
/* Bこの時点で、pの値とn[0]〜n[6]の各値は何か? */
p -= 2; /** ポインタ変数を2減算 /
*p = 8; /* ポインタを利用して値を変更 */
*(p+3) = 9; /* ポインタを利用して値を変更 */
/* Cこの時点で、pの値とn[0]〜n[6]の各値は何か? */
/********************************************************************/
45ポイント を手に入れた。
|
|
|
|
Name: keichan ..初心者(6,652ポイント)
Date: 2006/12/07(木) 18:40
No:2436
|
|
Title: Re:ポインタの値
|
|
@〜Cの時にprintfでそれぞれ表示されてみてはいかがですか?
ヒント:
ポインタを表示するには printf("%p", p);
値を表示するには printf("%d", n[0〜6]);
59ポイント を手に入れた。
|
|
|
|
|
Name: mika ..ぴよぴよ(85ポイント)
Date: 2006/12/07(木) 19:10
No:2441
| 解決!
|
Title: Re:ポインタの値
|
|
今までポインタを表示するのに%dを使っていました>_<”
%pということが分かったので解決しました!
アリガトウございます。
40ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(115,722ポイント)
Date: 2006/12/08(金) 00:01
No:2451
|
|
Title: Re:ポインタの値
|
|
解決されたようでよかったです。
プログラムを書いていると優先度に悩まされたりするのでちょっとご紹介。
まちがい
#include <stdio.h>
int main()
{
int a=3,*b;
b=&a;
*b++;
printf("%d\n",*b);
return 0;
}
こちらと
正解
#include <stdio.h>
int main()
{
int a=3,*b;
b=&a;
(*b)++;
printf("%d\n",*b);
return 0;
}
これでは表示されるものが全然違うはずです。
がんばってくださいね。
152ポイント を手に入れた。
|
|
|
|
Name: mai ..かけだし(1,034ポイント)
Date: 2006/12/07(木) 18:04
No:2432
|
|
Title: ループを使った課題
|
|
以前は課題のアドバイスと回答をいただきありがとうございました。 {無限ループを使って、変数の数に1.5ずつ加算して50をこえたらそこで終了、ただし3の倍数だけを表示する。} という課題で教科書を調べてみたのですが、forをもちいて作成すればいいのでしょうか まったくわからずこまっています どうかおねがいします
120ポイント を手に入れた。
|
|
|
|
Name: keichan ..初心者(6,593ポイント)
Date: 2006/12/07(木) 18:37
No:2435
|
|
Title: Re:課題
|
|
>forをもちいて作成すればいいのでしょうか
forを用いるとこんな感じですね。
#include <stdio.h>
int main()
{
double sum = 0.0; /* 初期値が指定されていないのでとりあえず 0 で初期化 */
for( ; sum < 50.0; ) {
if( (int)sum % 3 == 0 ) {
printf("%lf\n", sum); /* 最初の加算に入る前に出力をしてもいいのか指定がないのでとりあえず出力 */
}
sum += 1.5;
}
return 0;
}
これを参考に while を用いて作ってみてください^^
211ポイント を手に入れた。
|
|
|
|
|
Name: mai ..かけだし(1,083ポイント)
Date: 2006/12/07(木) 18:48
No:2438
|
|
Title: Re:課題
|
|
keichanさんアドバイスありがとうございます。教科書をさがしてみたところ for while 2つのやりかたがのっていたのですが、使い分けとかはあるのでしょうか
49ポイント を手に入れた。
|
|
|
|
|
Name: keichan ..初心者(6,886ポイント)
Date: 2006/12/07(木) 19:04
No:2440
|
|
Title: Re:課題
|
|
言語仕様的に明確な使い分けが規定されているわけではありません。
ただ、一般的とはわかりませんが私がしている使い分け方を載せます。
・for
既定回数の反復処理を行う場合に使用。
例)1〜10までprintfで出力を行う
for( int i=1; i<=10; i++ ) {
printf("%d\n", i);
}
・while
反復処理を何回行えばよいか状況によって異なる場合に使用。
例)ある数を2で割り続け、割った後の結果が0になるまで反復
int a = 100;
while( a != 0 ) {
a /= 2;
printf("%d\n", a);
}
173ポイント を手に入れた。
|
|
|
|
|
Name: box ..中級者(13,243ポイント)
Date: 2006/12/07(木) 19:41
No:2442
|
|
Title: Re:課題
|
|
> for while 2つのやりかた
for (A; B; C) {
何かの処理;
}
と
A;
while (B) {
何かの処理;
C;
}
は、「何かの処理」に continue; を含まない場合、全く等価です。
「この場合にはこちらでなければならない」というような
決まり事はありません。
お好きな方をお使いください。
2倍のポイントを手に入れた! 184ポイント を手に入れた。
|
|
|
|
|
Name: mai ..かけだし(1,089ポイント)
Date: 2006/12/07(木) 20:06
No:2444
| 解決!
|
Title: Re:課題
|
|
みなさんありがとうございました。これからwhile文に挑戦してみたいとおもいます。
2倍のポイントを手に入れた! 6ポイント を手に入れた。
|
|
|
|
Name: 雛苺 ..ぴよぴよ(656ポイント)
Date: 2006/12/05(火) 13:07
No:2339
|
|
Title: C言語の入門課題について
|
|
初めまして。
C言語を学んで2ヶ月ほどの学生です。
前回の授業でテストがあり、そのテスト直しが課題という事なのですが、友人に聞いても友人もわからなく、今回アドバイスを頂けたらと思い投稿させていただきました。
まず問題の方を記載させて頂きますね。
問題1
文字型、整数型、単精度浮動小数点型、倍精度浮動小数点型の変数をそれぞれ宣言して使用できる最大の値を代入して書き出してください。変数名は型名の最初のアルファベットを使用してください。
ヒント
文字型:1バイトデータ(8ビット):-128〜127
整数型:4バイトデータ(32ビット):-2147483648〜2147483647
単精度浮動小数点型:4バイトデータ(32ビット):3.4E-38〜3.4E+38
倍精度浮動小数点型:8バイトデータ(64ビット):1.7E-308〜1.7E+308
アスキーコード表:http://www.cppll.jp/cppreference/ascii.html を調べること。
問題2 文字型の変数を宣言して文字Aを代入してください。
問題3 整数型の任意の変数を宣言して初期化してください。
問題4 定数 \n を宣言するコードを記述して表示してください。
ヒント:エスケープシーケンス一覧
\\ バックスラッシュそのもの
\a 「警告」文字。通常は ASCII BEL 文字である。
\b バックスペース
\f 改ページ
\n 改行
\r 復帰(キャリッジリターン)
\t 水平タブ
\v 垂直タブ
\x[0-9a-f]+ \xに続く16進数で表現された文字。"\x41"は大文字のAである。
\ddd 1桁か2桁か3桁の8進数で表現された文字。"\101"は大文字のAである。
\c 文字 c そのもの。
問題5 問題4のヒントをヒントにタブを入力してから文字をひとつ表示しましょう。文字は何でもよいです。
問題6 データ用整数型変数a,bを宣言して、aをbで割り算した値をcに、余りをdに代入して表示しなさい。必要な変数は適宜、宣言すること。
問題7 int型どうしの割り算の結果をdouble型に代入して表示しなさい。
とういうものです。
自分で分かった範囲というのは・・・恥ずかしながら問題1の途中までしかわかりませんでした。。
合っているか分かりませんが、
#include <stdio.h>
main()
{
char c;
int i;
float f;
double d;
c=127;
i=2147483647;
f=3.4E+38;
d=1.7E+308;
printf("%c");
printf("%i");
printf("%f");
printf("%d");
return 0;
}
です。
それぞれのプログラム文と実行結果を知りたいのですが、勉強不足で問題1から後ろは教科書を読み直したり、何時間も考えましたがどうしても分かりませんでした。どうかアドバイスを頂けたらと思います。
実行結果ですが、コマンドプロンプトに、どういった文を入力したら結果が表示できるのかも、どうか教えていただけたらと思います。
よろしくお願いいたします。
*物分りが悪いため、文書のところどころでおかしい箇所がありましたらすみません。
656ポイント を手に入れた。
|
|
|
|
Name: keichan ..初心者(5,406ポイント)
Date: 2006/12/05(火) 13:37
No:2345
|
|
Title: Re:C言語の課題について
|
|
疑問点があれば、何でもどうぞ。
/**
問題1:回答例
*/
#include <stdio.h>
int main()
{
char c = 127;
long l = 2147483647;
float f = 3.4e+38f;
double d = 1.7e+308;
printf("c = %d\n", c);
printf("l = %d\n", l);
printf("f = %f\n", f);
printf("d = %f\n", d);
return 0;
}
/**
問題2:回答例
*/
int main()
{
/// 文字の代入は''(シングルクォーテーション)で囲む
char c = 'A';
return 0;
}
/**
問題3:回答例
*/
int main()
{
/// 宣言と同時に代入。これが初期化。
int i = 0;
return 0;
}
/**
問題4:回答例
*/
int main()
{
const char n = '\x0A';
return 0;
}
/**
問題5:回答例
*/
#include <stdio.h>
int main()
{
printf("\tprint");
return 0;
}
/**
問題6:回答例
*/
#include <stdio.h>
int main()
{
int a = 10, b = 3;
double c = a/b;
int d = a%b;
printf("c = %f\n", c);
printf("d = %d\n", d);
return 0;
}
/**
問題7:回答例
*/
#include <stdio.h>
int main()
{
int a = 10, b = 3;
double div = a/b;
printf("div = %f\n", div);
return 0;
}
531ポイント を手に入れた。
|
|
|
|
|
Name: 雛苺 ..ぴよぴよ(658ポイント)
Date: 2006/12/05(火) 13:44
No:2346
|
|
Title: Re:C言語の課題について
|
|
丁寧にサイト等も教えていただきありがとうございます。
教科書というのは教えて下さっている先生がオリジナルで作成したものだったので、他にも読んで見ますね、
サイトの方もこれから伺い勉強してきます。
サイトを見終わった後、教えて下さったプログラムを考え、もしも疑問が生じてしましたら、申し訳ないですがまたこちらから質問させて頂きますね。
理解出来た場合も書き込みさせて頂きます。
正直授業に一度ついていけなくなってからすべてがこんがらがってしまい悩んでいたので、回答だけでなくこのようなHPまで教えて頂けてうれしいです。
本当にありがとうございます。
それでは勉強して参りますね。
2ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(108,712ポイント)
Date: 2006/12/05(火) 13:46
No:2347
|
|
Title: Re:C言語の課題について
|
|
表現指示文字について、わかりましたか?
printf文でデータを表示する時は、その変数にあった表現指示文字を使用する必要があります。
以下の表を見てください。
型 データ範囲 表現指示文字
char -127〜128(文字) %cまたは%d
int -32768〜32767 %d
float 有効桁数6桁の実数 %f
double 有効桁数15桁の実数 %f
例えば、今int型変数の中身を表示させたい時は%dを使えと書いてありますね。
int i=10;
と宣言したとします。int型変数であるiには10が入っています。
これを表示してみましょう。
printf("%d",i);
このように書きます。
ダブルコーテーションの中に表現指示文字を書き、それに対応した変数を「,」の後に書きます。
今
int i=10, j=20;
とi,jの2つの変数を用意したならば、
printf("%d %d",i,j);
このように書くことで連続して書くことが出来ます。
%dの数と、後ろに書く変数の数は一緒でなければなりません。
左から書いた順番どおりに表示されます。
最初の%dがiの中身を表示させ、次の%dがjの中身を表示させているわけです。
型 データ範囲 表現指示文字
char -127〜128(文字) %cまたは%d
int -32768〜32767 %d
float 有効桁数6桁の実数 %f
double 有効桁数15桁の実数 %f
ですから、今回この表をもとに、どのように表示させようか考えて見ます。
そのまま書けばいいですね。
1番の答え考えてみてください。
747ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(109,152ポイント)
Date: 2006/12/05(火) 13:59
No:2350
|
|
Title: Re:C言語の課題について
|
|
1番の回答を考える前に、
とりあえず、文字型と、浮動小数点型で宣言された変数の表示について考えます。
文字型であるchar型で宣言したcは%cで表示するんだったですね。
つまり
printf("%c",c);
こういうことになります。
しかし、このままではよろしくありません。
int i=11;
printf("%d",i);
printf("%d",i);
このように書いた時、実行結果はこうなります。
1111
どこまでが前の表示で、どこからが次の表示かわからなくなりますね。
ですからこんな時は、行の終わりに\n改行コードを入れましょう。
printf("%d\n",i);
printf("%d\n",i);
こうすることで、実行結果は
11
11
となり、きちんと区切って見えてわかりやすくなりますね。
プログラムソースコードないでいくら改行しようが、printfで出力される文字にはなんら影響しませんので
ちゃんと改行コードを書いてやることが必要です。
ですから、文字型の表示はこうします。
printf("%c\n",c);
これで、文字を表示し、改行が出来ます。
先ほどの表では
文字型は%cでも%dでもいいかのように、書いてありましたね。
しかし両者では、表示されるものが違います。
文字というものは、全て文字コードで管理されています。
「文字」といういみの「1」と「数字」という意味の「1」では意味が異なります。
コンピュータの中でデータは全て0と1の信号で計算されています。
それにもかかわらず「文字」というあいまいなデータがあっては困りますね。
ですから「141」という信号がきたら「a」という文字にあたる
「142」という信号がきたら「b」という文字にあたる
と決めているんですね。
それが先ほどのアスキーコードです。
%cでは、その対応する「文字」を表示します。
%dでは、その対応する「文字コード」を表示します。
自分で両方表示してみて、どう違うか実際にみてみてください。
これらをふまえれば、回答はもうわかりますね。
回答のサンプルを書いておきます。
#include <stdio.h>
int main(){
char c = 127;
int i = 2147483647;
float f = 3.4e+38f;
double d = 1.7e+308;
printf("c = %d\n", c);
printf("i = %d\n", i);
printf("f = %f\n", f);
printf("d = %f\n", d);
return 0;
}
440ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(110,176ポイント)
Date: 2006/12/05(火) 14:14
No:2351
|
|
Title: Re:C言語の課題について
|
|
では、続いて回答2にはいります。
char c;
と宣言すると、どのような意味をもつでしょうか。
変数を宣言すると「領域が確保」されます。
データは全て0と1の信号で管理されています。
ビットとバイトの事は知っていますか?
0か1をあらわす物が一つあるとしましょう。
これは1つで何種類の信号が識別できますか?
0か1 つまり2種類ですね。
これが2つ集まると何種類の信号が識別できますか?
00
01
10
11
数学の順列組合わせのように、2*2=4種類ですね。
これが3つ集まると何種類の信号が識別できますか?
000
001
010
011
100
101
110
111
2*2*2=8種類ですね。
このように、8個並べると
2*2*2*2*2*2*2*2=256種類の信号が識別出来ます。
この8個というのを8ビットといいます。
1と0の識別できる1つのものを1ビットといいます。
ビットが8個あつまったもの、
これが1バイトです。パソコンのHDDとかによくギガバイトなんてかいてある単位はこれです。
つまり1バイトでは256種類の信号が識別出来るんですね。
これが俗に言う「半角文字」です。半角文字では漢字や平かなはかけませんね?
何故でしょうか。
そうです。漢字は256種類の識別では表現し切れません。
漢字は何千とあり、もっともっと沢山の識別が必要です。
では先ほど8ビットで計算しましたが、1バイトを2つ並べて2バイトにすると
16ビットで計算できます。
つまり
2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2=65536
ですから、6万通り以上の識別が出来ます。
こなれば、漢字も平かなもカタカナも色んな記号もなんでも表現できますね。
これらを全角文字といいます。
よく携帯でメールをうっていると
右端のあたりに「残り9872」とかって出ていますよね。
あれは「残り9872バイト」という意味です。
あれって全角文字をうつと2ずつへり、半角文字をうつと1ずつへりますよね。
あれは半角文字が1バイト、全角文字が2バイトだからです。
・・・とかなり脱線しましたけど、
char c;
と宣言すると、半角文字分である1バイトが確保されます。
そして、シングルコーテーション「'」で文字を囲むとそれは文字コードをあらわします。
cにAの文字コードを代入したければ
c = 'A';
と書けばよいのです。
半角1文字がはいる1バイトにA 1文字がはいって丁度いいですね。
ですから、答えはこうなります。
#include <stdio.h>
void main(){
char c;
c = 'A';
}
簡単ですね。
これは、printf文がないので、実行しても何も見えません。
#include <stdio.h>
void main(){
char c;
c = 'A';
printf("%c",c);
}
このように書くと、実行時に代入された文字が表示されます。
1,024ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(110,691ポイント)
Date: 2006/12/05(火) 14:21
No:2353
|
|
Title: Re:C言語の課題について
|
|
続いて問題3です。
変数は
int i;
このようにすると整数型であるint型のiという名前の変数が用意されますね。
実は先ほども断り無くやってしまいましたが、
宣言と同時に初期化できるんです。
初期化というのは、聴きなれない言葉かもしれませんが、
一般的には最初に0を代入することを言います。
変数は宣言しただけでは、その中身に何が入っているかわからないのです。
ですから、何の値も代入せずに表示したりすると変な値が出たり、
エラーになったりすることがあります。
そんなことを防ぐために、あらかじめ何かの値をいれておくことを
初期化といいます。別に0でなくてもいいですが、0が一般的です。
変数は宣言と同時に初期化出来、このように書きます。
int i=0;
こうすると、宣言と同時にiに0がはいります。
ですから解答はこうなります。
#include <stdio.h>
void main(){
int i=0;
}
しかし、例によってこのプログラムにはprintf文がないので実行しても何も表示されませんから
本当にできたのか確認できません。
#include <stdio.h>
void main(){
int i=0;
printf("%d",i);
}
このようにprintf文を書くことで確認が出来るようになります。
515ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(110,989ポイント)
Date: 2006/12/05(火) 14:31
No:2356
|
|
Title: Re:C言語の課題について
|
|
文字コードは先ほどのアスキーコード表を見てください。
文字と文字コードについては上でお話しましたね。
あの表から見てみると改行コードは「10」だとわかります。
16進数で10を書けば「0A」ですね。
C言語で16進数を書く時は0xを最初に書きます。
char c;
で宣言したcに10を代入したらいいだけです。
#include <stdio.h>
void main(){
char c = 10;
}
こうですね。
例によってprintfを付けると
#include <stdio.h>
void main(){
char n = 10;
printf("%c",n);
}
こうなります。
16進数で代入するなら
#include <stdio.h>
void main(){
char n = 0x0A;
printf("%c",n);
}
こうなります。
298ポイント を手に入れた。
|
|
|
|
|
Name: 雛苺 ..ぴよぴよ(5ポイント)
Date: 2006/12/06(水) 11:14
No:2408
|
|
Title: Re:C言語の課題について
|
|
こんにちは。
問題に対する丁寧な解説もありがとうございました。
教えて頂いたHPも見ています。
プログラムの最初から分からなくなっているようなので、はじめから勉強することにしました。
今日も教えていただきたい問題があるのですがよろしいでしょうか;;
授業にはまだついていけないので、こちらもどういったプログラムの文になるのかアドバイスを頂けたら嬉しいです。
プログラムの実行の仕方は昨日教えて頂いたHPを見て理解出来ました。
その問題は昨日の問題の続きになるのですが、まだ昨日の問題3までしか理解できていないので、プログラム文を作るのに苦戦しております;;
問題8
先の問題1から7について、再度確認のために正解例を入力し、main関数内のすべての行にコメントをつけなさい。コメント行は/*と/*ではさむこと。
『この問題は、昨日回答して頂いたものを見させて頂き、調べながらなんとかできました。』
問題9
整数型変数a,b,cを宣言して、aとbを比較してaを代入して表示する文を記述して下さい。
問題10
年齢を整数でキーボードから入力し、12歳以下の場合には「小人料金」、それ以外の場合は「大人料金」と表示しなさい。
問題11
年齢を整数でキーボードから入力し、12歳以下の場合には「小人料金」、18歳以下の場合には「学生料金」それ以外の場合は「大人料金」と表示しなさい。
というものです。
問題8はなんとかとけたのですが、問題9からはどのようなプログラム文を作ればよいのか分かりません・・・。
よかったらアドバイスを下さい。
また、検索したのですがPC版の方のURLが分からなくなってしまったので、そちらも教えていただけないでしょうか?
よろしくお願いいたします。
653ポイント を落としてしまった。
|
|
|
|
|
Name: 雛苺 ..ぴよぴよ(0ポイント)
Date: 2006/12/06(水) 11:23
No:2410
|
|
Title: Re:C言語の課題について
|
|
申し訳ございません。
問題9の文章を写し間違えてしまいました。
訂正させて頂きます。
↓
問題9
整数型変数a,b,cを宣言して、aとbを比較してaが大きい場合にはcにaを代入して表示する文を記述して下さい。
です。失礼致しました。
77ポイント を落としてしまった。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(114,894ポイント)
Date: 2006/12/06(水) 16:58
No:2422
|
|
Title: Re:C言語の課題について
|
|
>雛苺さん、
家に、コンパイルできる環境はありますか?
もしまだでしたら、まず、環境をそろえて、家で勉強できるようにする方がよいと思います。
>検索したのですがPC版の方のURLが分からなくなってしまったので
これはここの掲示板のURLの事ですか?
うわ、確かに携帯で投稿なさってますね。
書くの大変だったんじゃないですか?;
URLはアドレスバーに
「dixq.net」
とだけうてばここにたどり着けます。
実際のURLは
http://dixq.net/board/
こちらです。
>問題9
>整数型変数a,b,cを宣言して、aとbを比較してaを代入して表示する文を記述して下さい。
この問題も、C言語の超基本である
if文
を使って書くことが出来ます。
かなり基本なので、ここで答えを聞いてしまうのは避けたほうがいいと思います。
(明日まで期限というわけでないのでしたら)
勉強の仕方ですが、
http://www5c.biglobe.ne.jp/~ecb/c/c00.html
例えばここにアクセスして
「if文ってどこをクリックしたら説明が出てくるんだろう」
と思いながらあちこちクリックしてください。
「基本だから項目は上のほうにあるはずだよな。しかしprintf文より後に出てくるんならprintfの解説より下にあるはずだよな」
など、色々考えて読んでみてください。
最初は調べる事も非常に大事なので。
問題の回答の考え方ですが、
問題9はif文について勉強してください。
問題10についてはscanf文とif文を勉強してください。
問題11についてはscanf文とif文(この文法の中にelse ifという物があり、これも)を勉強してください。
そうすれば解けるはずです。
もし解けなければ、ここまでコード書いたよっていうの見せてもらえないでしょうか。
530ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(114,972ポイント)
Date: 2006/12/06(水) 17:08
No:2423
|
|
Title: Re:C言語の課題について
|
|
>問題8はなんとかとけたのですが
プログラムは数学と同じです。
答えをみながら読んでいくとわかった気にだけなって、実際わかってないってことが
よくありますので、しっかり練習問題をしてくださいね。
よければ、わかっているか確認するためにこちらの問題をやってみてください。
問題
整数型変数a,b,cを宣言し、aには3,bには4を代入し、これらの足し算した計算結果をcに代入して表示しなさい。
その後、a×bの計算結果もcに代入して表示しなさい。
表示は以下のようになるようにしなさい
----------------
a+bの計算結果は
7
a×bの計算結果は
12
----------------
78ポイント を手に入れた。
|
|
|
|
Name: 困ったさん ..ぴよぴよ(887ポイント)
Date: 2006/12/05(火) 19:20
No:2387
|
|
Title: 文字列の中身を反転させるには
|
|
(1)キーボードから文字列を入力し、文字列sに格納する
(2)文字列sを逆順に並べ替えたものを文字列tに格納する
(3)文字列sと文字列tが同一であるかどうかを比較し、その結果を画面表示する
という処理を行なうプログラムなんですけど・・・。ちなみにs,tの要素の数は50です。
また、これもstrlen,strcmp関数の使用は不可となっています。
入力した文字列を逆順表示するにはデクリメントを使えばできますか?
また入力した文字列を逆順表示した文字列を比較した際、同じなら「同一の文字列」、
異なるなら「異なる文字列」と分岐して表示する場合ifの()の中にはどう書けばいいですか?
190ポイント を手に入れた。
|
|
|
|
Name: 管理人 [URL] ..ハッカー(112,988ポイント)
Date: 2006/12/05(火) 20:58
No:2394
|
|
Title: Re:もう1つ問題が・・・
|
|
もしstringの標準関数を使わないで、というのなら
これでどうでしょうか?
#include <stdio.h>
int main() {
int i=0,len;//文字列の長さを格納するlen
char s[50],t[50];
printf("Input a sentence. ->\n");//文章入力を促す
scanf("%s",s);//入力文字を格納
while(s[i]!='\0')//sにはいっている文字が終端記号になるまでiを数える
i++;
len=i-1 , i=0;//\0の手前までの数がほしいからi-1を長さlenに代入
while(i<=len){//文字列の長さだけループさせる
t[i]=s[len-i];//tは0から、sはその逆から代入させる。
i++;
}
t[i]='\0';//tに逆の順番で格納した。最後には終端記号をいれる。
i=0;
while(s[i]==t[i] && i<=len)//同じかどうか比較する。
i++;
if(i==len+1)//文字列の数だけループがされていたら、最後まで同じだったということ
printf("2つの文字列は一致しています。\n");
else
printf("2つの文字列は一致していません。\n");
printf("1: %s\n",s);//表示
printf("2: %s\n",t);
return 0;
}
上記
while(s[i]==t[i] && i<=len)//同じかどうか比較する。
という部分はsの要素とtの要素を比較しています。
iがlen+1になるまでループが続いたら、配列要素全部が同じだったということです。
481ポイント を手に入れた。
|
|
|
|
|
Name: 困ったさん ..ぴよぴよ(875ポイント)
Date: 2006/12/06(水) 15:23
No:2413
| 解決!
|
Title: Re:質問
|
|
なるほど…。細かくコメントでご説明いただきありがとうございます。
プログラムの理解度はまだまだですけど、これから疑問をいろいろ聞きながら
自分でも簡単にプログラミングができるようになりたいです。
管理人さんありがとうございました。
26ポイント を手に入れた。
|
|
|
|
Name: 新人 ..ぴよぴよ(372ポイント)
Date: 2006/12/05(火) 18:32
No:2383
|
|
Title: ファイル出力について
|
|
昨日の問題の延長なんですが、仕様が多くて困っています。
昨日教えて頂いたソースを参考に自分なりに考えて見たソースが下記です。
作成したファイルは"word.txt"としました。
ファイルの書き換えを行うプログラムを作成して下さい。
1:書き換えるファイル名の入力を促すメッセージを画面に出力し、キーボードからの入力を行う。
2:1文字以上入力された場合「1」で入力した名前でファイルの読み込みを行う。
読み込むファイルが存在しない場合は新規に作成する。
3:ファイルの内容の入力を促すメッセージを画面に出力し、キーボードからの入力を行う。
4:「1」で指定したファイルの内容を「3」で入力した内容にする。
#include <stdio.h>
#include <string.h>
int main()
{
char str[128];
FILE *fp;
printf("ファイル名を入力してください。\n");
fgets(str,sizeof(str),stdin);
if(strcmp(str,"\n")){
strtok(str,"\n");
fp=fopen(str,"w");
if(fp==NULL){
fprintf(stderr,"ファイルが作成できません。\n");
return 0;
}
printf("ファイルが作成されました。\n");
fclose(fp);
}
else{
printf("ファイルが作成されませんでした。\n");
}
return 0;
}
仕様はまた後で記述します。
13ポイント を手に入れた。
|
|
|
|
Name: 管理人 [URL] ..ハッカー(112,809ポイント)
Date: 2006/12/05(火) 20:18
No:2389
|
|
Title: Re:続・課題
|
|
#include <stdio.h>
int main() {
char str[128],str2[256];
FILE *fp;
printf("ファイル名を入力してください。\n");
scanf("%s",str);//ファイル名入力
if((fp=fopen(str,"w"))==NULL){//ファイルポインタ格納し、無効なら終了
printf("error\n");
return 1;//以上終了を示す1
}
printf("ファイルに書き込む文章を入力してください。\n");
scanf("%s",str2);//ファイルに書き込む内容
fprintf(fp,"%s",str2);//str2の内容をfpが示す中に出力する
printf("正常終了\n");
fclose(fp);//閉じる。
return 0;
}
こんな感じでどうでしょうか。
82ポイント を落としてしまった。
|
|
|
|
|
Name: 新人 ..ぴよぴよ(739ポイント)
Date: 2006/12/05(火) 20:46
No:2392
|
|
Title: Re:続・課題
|
|
早速のレスありがとうござます。
コメント付きで大変分かりやすいです。仕様書で
1回目文字入力後、リターンを押した場合(同一名称のファイルが作成されていない場合)
「ファイルが存在しないので新規に作成する旨のメッセージを表示されているか確認」
「ファイル内容の作成を促すメッセージが画面に出力されていることを確認」
「文字入力が出来ることを確認」(2回目文字入力)
1回目文字入力時、文字入力せずにリターンを押した場合
「ファイル名未入力のメッセージが画面に出力されることを確認」
上のブロックは同一名称のファイルがあるか比較して各々の処理をするのでしょうか?
下のブロックはエンターを認識させれば良いのでしょうか?
また、scanfとfgetsを一緒に使うことはあまりよろしくないのでしょうか?
質問ばかりで申し訳ありません。
ソフトウェア会社に入社したばかりで、今はC言語の本と毎日戦っています(笑)
367ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(113,943ポイント)
Date: 2006/12/05(火) 21:22
No:2396
|
|
Title: Re:続・課題
|
|
恐らく大学生の宿題のように、
「その時答えがわかって提出すればいいや」って物じゃないと思うので、
勉強の仕方を勉強されたらよいかと思います。
専門職につくための、研修みたいな感じですかね?
何かわからないコードがあれば、たいていその箇所をgoogleで検索すればわかります。
例えば、fopen関数のwだとかrだとか書いてあるものの意味が判らない時は
fopen
と検索すれば
http://www.google.co.jp/search?hl=ja&q=fopen&lr=
このような一覧が表示されます。最初のmanは結構最初のうちは難しいので
2件目くらいにヒットするサイトを見てみましょう。
fopenの使い方を
http://www9.plala.or.jp/sgwr-t/c/sec17.html
この辺で調べてみて、こんな表を発見します。
モード 動作 ファイルがあるとき ファイルがないとき
"r" 読み出し専用 正常 エラー(NULL返却)
"w" 書き込み専用 サイズを 0 にする(上書き) 新規作成
"a" 追加書き込み専用 最後に追加する 新規作成
"r+" 読み込みと書き込み 正常 エラー(NULL返却)
"w+" 書き込みと読み込み サイズを 0 にする(上書き) 新規作成
"a+" 読み込みと追加書き込み 最後に追加する 新規作成
これをみたら、fopenの返り値によってどのように条件分岐させたらよいかわかりますね。
このように、何かわからない箇所があれば、ぐぐって調べてみることです。
人に聞くにしても、ある程度自分で調べてから聞いたほうがずっとよくわかります。
手元に本をもっていることも大事ですが、今ではウェブでずいぶん勉強できます。
2倍のポイントを手に入れた! 936ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(114,313ポイント)
Date: 2006/12/05(火) 21:46
No:2397
|
|
Title: Re:続・課題
|
|
書きそびれました。
scanfとfgetsについてですが、
scanfは悪名高い関数だといわれています。
ほとんどの環境で依存せず使えて、とてもわかりやすく便利な関数ですが、
最大入力文字数が指定できないという点に問題があり、
実際にソフトウェア開発などに携わるんでしたらまず、使う機会がないと思います。
例えば
fgets(str,sizeof(str),stdin);
と指定すればstrのサイズだけですみますが、
scanfは最大の文字数が不定のため、バッファがあふれてしまうことがります。
どんなに沢山10メガバイト位容量を確保したとしても、この関数で10MB+1バイトになってしまうかもしれません。
このような事からscanfはプロの書く関数ではないと思います。
また、scanf("%d %d", &x, &y); このように書いた時、
1
と入力してエンターを押したとしましょう。
改行コードは空白と同じ扱いなのでずっと待機状態になります。
いくらエンターを押しても待機したままということになります。
他にも色々理由はあるのでしょうが、scanfはプログラマーからは嫌われる存在らしいです。
私は完成度よりわかりやすさを重要視したいので、scanfはよく使います。
みんな見慣れてると思いますしね。
そこまで高度なプログラムが書けるようになるまでのお手伝いですから、
そのレベルまでいけば、自分で学べるでしょう。
370ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..プログラマー(32,862ポイント)
Date: 2006/12/05(火) 21:54
No:2398
|
|
Title: Re:続・課題
|
|
明確にしなれければないのは、これは会社から新人向けに出された課題なのか、それとも(クライアントがついている等)正規の案件での問題なのか、ということです。
それ次第で、エラーチェック1つとってもがらりと変わります。
どちらにしても業務の一環なので社内で解決してほしいところですが。
>上のブロックは同一名称のファイルがあるか比較して各々の処理をするのでしょうか?
そうです。
fopenの戻り値でもいけますが、本来なら各OSの APIを使って確認するべきでしょう。
>下のブロックはエンターを認識させれば良いのでしょうか?
fgetsを使っているならエンターは内部で勝手に認識しています。
fgetsから返ってきた入力された文字列の長さを調べるといいでしょう。
>scanfとfgetsを一緒に使うことはあまりよろしくないのでしょうか?
そんなことはないです。
根本的に業務でその2つはほとんど使わないませんが、どちらにしても気をつけなければならないのはバッファをオーバーしてしまうことで、その際のエラー処理を忘れないようにすれば大丈夫です。
498ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..プログラマー(32,708ポイント)
Date: 2006/12/05(火) 21:59
No:2399
|
|
Title: Re:続・課題
|
|
>最大入力文字数が指定できないという点に問題があり、
あ、一応できますよ。
char buff[8];
scanf("%7s", buff);
出来ても管理人さんの仰るとおり、業務では scanf自体使うことはまずないです。
154ポイント を落としてしまった。
|
|
|
|
|
Name: 新人 ..ぴよぴよ(835ポイント)
Date: 2006/12/05(火) 22:06
No:2401
|
|
Title: Re:続・課題
|
|
皆様回答ありがとうございます。まだまだクライアントの業務を
こなせるレベルではありませんので大丈夫です(汗)
それが社内の上司は教えてくれないことになってるんですよ。
まぁいろいろ試してやってみますね。
96ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..プログラマー(33,130ポイント)
Date: 2006/12/05(火) 22:17
No:2402
|
|
Title: Re:続・課題
|
|
ちなみに buff[8]の 8を defineによる定数化した場合、以下のように工夫が必要になります。
#define MAX_STRING_SIZE 7
#define STRING_BUFFER_SIZE (MAX_STRING_SIZE+1)
#define STRING_VALUE_(n) #n
#define STRING_VALUE(n) STRING_VALUE_(n)
int main(){
char buff[STRING_BUFFER_SIZE];
scanf("%" STRING_VALUE(MAX_STRING_SIZE) "s", buff);
return 0;
}
>業務で使うにはキー入力は何の関数を使用するのが一般的なんですか?
状況にもよりますが、例えば GUIを使うなら各 OSの APIということになりますし、仮にコンソールで作るとしたら、処理の自動化の為に WSHとかバッチで処理できるようにしたいので、アプリへの引数として渡してしまいます。
コンソールで対話型なんて、作る機会は業務では今まで一度もないですね・・・。
もしあったとしたら、多分 C#か C++で作るのでやっぱり scanfとかは使わないかと。
422ポイント を手に入れた。
|
|
|
|
|
Name: 新人 ..ぴよぴよ(914ポイント)
Date: 2006/12/06(水) 09:24
No:2407
| 解決!
|
Title: Re:続・課題
|
|
業務に関わることを教えていただきありがとうございます。
これからは「なぜ?」を大切にしていきたいと思います。
またお世話になると思います。Justyさん管理人さん
大変有用な回答、解説ありがとうございまいた。
79ポイント を手に入れた。
|
|
|
|
Name: 困ったさん ..ぴよぴよ(522ポイント)
Date: 2006/12/05(火) 16:43
No:2367
|
|
Title: 文字列について
|
|
二つの文字列s1,s2 をキーボードから入力し,それぞれの文字列の長さ(NULL 文字は含まな
い)を画面表示し,さらに文字列s1 の後ろに文字列s2 を連結して画面表示する
(ただし,文字列s1 と文字列s2 を連結したものを一度文字列s1 に格納してから
表示を行うこと.)っていうプログラムの作成が課題で出たんですけど
strlen(),strcat()等の関数が使えなくて・・・。
文字列の長さにstrlenが使えないし、文字列を連結するのにもstrcatが使えないなんて・・・(汗)
どうしたらいいんですか?
187ポイント を手に入れた。
|
|
|
|
Name: GPGA ..中級者(13,628ポイント)
Date: 2006/12/05(火) 16:57
No:2371
|
|
Title: Re:文字列について
|
|
関数を作ってしまうのが普通ですね。
int _strlen(const char* str)
{
int i;
for (i = 0; *str != '\0'; i++) {
str++;
}
return i;
}
char* _strcat(char* str1, const char* str2)
{
char* tmp = str1;
int i;
for (i = 0; *str1 != '\0'; i++) {
str1++;
}
for (i = 0; *str2 != '\0'; i++) {
*str1 = *str2;
str1++;
str2++;
}
*str1 = '\0';
return tmp;
}
188ポイント を手に入れた。
|
|
|
|
|
Name: box ..中級者(12,754ポイント)
Date: 2006/12/05(火) 16:58
No:2372
|
|
Title: Re:文字列について
|
|
サンプルです。
#include <stdio.h>
#define BUFLEN (512)
int main(void)
{
char s1[BUFLEN], s2[BUFLEN];
int len1, len2, i;
printf("文字列s1:"), scanf("%s", s1);
printf("文字列s2:"), scanf("%s", s2);
for (len1 = 0; s1[len1] != '\0'; len1++)
;
for (len2 = 0; s2[len2] != '\0'; len2++)
;
printf("s1の長さ=%d, s2の長さ=%d\n", len1, len2);
for (i = len1; i < len1 + len2; i++)
s1[i] = s2[i-len1];
s1[i] = '\0';
printf("連結後のs1='%s'\n", s1);
return 0;
}
239ポイント を手に入れた。
|
|
|
|
|
Name: box ..中級者(12,682ポイント)
Date: 2006/12/05(火) 17:05
No:2374
|
|
Title: Re:文字列について
|
|
BUFLENは、結合後の文字列s1を格納するのに十分な大きさを表わす値です。
サンプルでは、文字列終端の'\0'を含めて512バイトまで対応している、ということです。
72ポイント を落としてしまった。
|
|
|
|
|
Name: 困ったさん ..ぴよぴよ(589ポイント)
Date: 2006/12/05(火) 17:10
No:2376
|
|
Title: Re:文字列について
|
|
なるほど・・・初めて見ました(笑)
勉強になります。
2倍のポイントを手に入れた! 42ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(112,908ポイント)
Date: 2006/12/05(火) 17:15
No:2378
|
|
Title: Re:文字列について
|
|
では、私は違った方向で・・ってやってること一緒ですが
#include <stdio.h>
int main(){
int i=0,j=0;
char s1[512],s2[512];
printf("1つ目の文字列入力 ->\n") , scanf("%s",s1);
printf("2つ目の文字列入力 ->\n") , scanf("%s",s2);
printf("1: %s\n" ,s1);
printf("2: %s\n\n",s2);
while(s1[i]!='\0')
i++;
while((s1[i+j]=s2[j]) != '\0')
j++;
printf("連結: %s\n",s1);
return 0;
}
文字列の長さがわからなくても、\0が出てくるまでカウントアップしてやればわかります。
最初のループの部分ですね。
次のループはs1は先ほど\0だったところをスタート地点にして、s2は最初をスタート地点にして代入をおこないます。
代入されたものが\0ではなかったらjをカウントアップして次々に代入していきます。
355ポイント を手に入れた。
|
|
|
|
|
Name: keichan ..初心者(6,178ポイント)
Date: 2006/12/05(火) 17:29
No:2379
|
|
Title: Re:文字列について
|
|
>strlen(),strcat()等の関数が使えなくて・・・。
ではこれならいいですか?
#include <stdio.h>
int main()
{
char s1[512], s2[512];
scanf("%s", s1);
scanf("%s", s2);
sprintf(s1, "%s%s", s1, s2);
printf("%s\n", s1);
return 0;
}
45ポイント を手に入れた。
|
|
|
|
|
Name: 困ったさん ..ぴよぴよ(697ポイント)
Date: 2006/12/05(火) 19:10
No:2386
|
|
Title: Re:文字列について
|
|
管理人さんへ
> char s1[512],s2[512];
もし[]に512みたいな具体的な数値がなかったらどうなりますか?
> printf("1つ目の文字列入力 ->\n") , scanf("%s",s1);
> printf("2つ目の文字列入力 ->\n") , scanf("%s",s2);
は
printf("1つ目の文字列入力 ->\n");
scanf("%s",s1);
printf("2つ目の文字列入力 ->\n");
scanf("%s",s2);
と同等の意味なんですか?どちらの書き方でもOKですか?
2つともバカみたいな質問でごめんなさい。
108ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(112,460ポイント)
Date: 2006/12/05(火) 20:27
No:2390
|
|
Title: Re:文字列について
|
|
>> char s1[512],s2[512];
>もし[]に512みたいな具体的な数値がなかったらどうなりますか?
[512]という数字は「配列の要素数」と呼ばれ、配列の要素をいくつ作るか示すものです。
宣言の時にはいくつ生成するか決めているので、具体的な数字を書いてやらないと、
コンパイラはいくつ配列要素を作ればいいかわからず、エラーを吐き出してしまいます。
しかし、省略できる時もあります。
char s1[]="省略可能なkakikata..";
このように宣言と同時に格納する文字を示してやれば、いくつ用意すればいいのか
わかりますのでエラーになりません。
こうすると、全角文字が5つ、半角文字が10文字あるから、配列要素は20個必要です。
文字列は最後に終端記号である\0を入れる必要がありますから、
合計21個配列要素が必要だとわかりますね。
つまり宣言と同時に初期化しないときには、配列要素数の省略は不可。
同時に初期化するなら省略は可能ということです。
後、コンマについてですが、
@,A,B
と書けば、@から順番にBまで処理をしろといういみなので、
普通にたてに書いても同じです。
2つの値を交換する時など、1行の処理が少ない時や、
短く書きたい時によく使用します。
>2つともバカみたいな質問でごめんなさい。
全然そんなことないので、少しでも疑問があれば、何でも聞いてくださいね。
349ポイント を落としてしまった。
|
|
|
|
|
Name: box ..中級者(12,856ポイント)
Date: 2006/12/05(火) 20:46
No:2393
|
|
Title: Re:文字列について
|
|
> 先生がさせようとしていることを賢くうまく外して見せるのも
文字列の連結は、keichanさんがお書きになった
sprintf関数を使う方法が最良です。
標準関数のstrcatを使う場合、下手なコーディングをすると
strcatの連鎖地獄に陥ってしまいます。
しかし、sprintf関数を使えば、
sprintf(dest, "%s%s%s", src1, src2, src3);
のように、おそらく誰が見てもスッキリしたコードとなります。
コードがスッキリしている分、テストや保守が楽です。
155ポイント を手に入れた。
|
|
|
|
|
Name: 困ったさん ..ぴよぴよ(849ポイント)
Date: 2006/12/06(水) 14:55
No:2412
| 解決!
|
Title: Re:質問
|
|
いろいろと細かい所も質問できたおかげで理解が深まりました。
みなさんご指導ありがとうございました。
38ポイント を落としてしまった。
|
|
|
|
Name: みん ..かけだし(1,421ポイント)
Date: 2006/12/05(火) 16:23
No:2365
|
|
Title: エラー表示+再入力
|
|
質問をさせていただきます。
下のプログラムを数字以外がでると
再入力させたいのですが、isdigitでうまくできません。
ifで判定処理をするのにはどのようにしたら
よいのでしょうか。すみませんが
おしえてください。
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
/*猫の定義*/
class Neko
{
private:
string name; //名前
public:
Neko(string); //コンストラクタ
void naku() const;
};
Neko::Neko(string s) : name(s){}
void Neko::naku() const{
cout << "にゃあ。私は" << name << "だ。" << endl;
}
/*猫の稼ぎの定義*/
class SalaryNeko : public Neko
{
private:
int gekkyu; //月給
public:
SalaryNeko(string, int); //コンストラクタ
int get_nensyu() const { return gekkyu * 12; }//年収を戻す関数
void syoukyu() { gekkyu++; } //月給を増やす関数
int get_gekkyu() const{ return gekkyu; }//月給の値を戻す関数
};
SalaryNeko::SalaryNeko(string s, int x) : Neko(s), gekkyu(x){} //コンストラクタ
/*猫の派生クラス*/
class SalaryNekoWithBonus :public SalaryNeko
{
private:
int bonus; //ボーナス
public:
//コンストラクタ
//第1引数が名前、第2引数が月給、第3引数がボーナスを表す
SalaryNekoWithBonus(string, int, int);
//年収を戻す関数
int get_nensyu() const{return get_gekkyu() * (12 + bonus);}
};
SalaryNekoWithBonus::SalaryNekoWithBonus(string s, int g, int b) : SalaryNeko(s, g), bonus(b){}
/*メイン*/
int main()
{
string name; //名前の一時格納場所
int gekkyu; //月給
int bonus; //ボーナスが月給の何ヶ月分か
cout << "金稼ぎ猫・ボーナスを生成します。\n名前を決めて入力してください。" << endl;
cin >> name;
cout << "月給を決めて入力してください。(1万円単位)" << endl;
cout << "(数字は半角で入力してください。)" << endl;
cin >> gekkyu;
if(isdigit==0){
cout << "エラー";
}
cout << "ボーナスは月給の何ヶ月分か、入力してください。" << endl;
cin >> bonus;
SalaryNekoWithBonus dora(name, gekkyu, bonus); //サラリー猫・ウイズ・ボーナスの生成
while(1)
{
//動作内容入力処理
int ans;
cout << "どうしますか?" << endl;
cout << "1 鳴かす 2 年収を表示 3 昇給 4 やめる"<<endl;
cin >> ans;
//動作内容判定処理
if(ans == 1)
{
dora.naku();
}
else if(ans == 2)
{
//2 年収を表示
cout << "年収は現在" << dora.get_nensyu() << "です。" << endl;
}
else if(ans == 3)
{
dora.syoukyu();
cout << "1万円昇給しました。" << endl;
}
/*else if(ans<1 && ans>4)
{
cout << " 数値が異常です.再入力してください";
}*/
else if(ans == 4)
{
break;
}
cout << endl;
}
cout << "おわり" << endl;
}
1,421ポイント を手に入れた。
|
|
|
|
Name: keichan ..初心者(6,007ポイント)
Date: 2006/12/05(火) 17:09
No:2375
|
|
Title: Re:エラー表示+再入力
|
|
isdigitは標準"関数"ですから
if( isdigit == 0 )
と書くと「isdigitのアドレスが0番地であるか評価する」になります。
当然0番地に配置される事はあり得ませんので"エラー"と表示することはありません。
また isdigit は指定した'一文字'が数値であるかどうかをチェックする関数ですので
2桁以上の文字を入力したときにちゃんとエラーチェックできません。
例)月給を決めて入力してください -> 1a
上記例だとスルーされる可能性があるということです。
C++ですので、私であればこう書くかな(要BOOSTインストール)
#include <boost/lexical_cast.hpp>
std::string gekkyu_buf;
while(1)
{
cin >> gekkyu_buf;
try {
gekkyu = boost::lexical_cast<int>(gekkyu);
break;
} catch( boost::bad_lexical_cast& ) {
std::cout << "エラー" << std::endl;
}
}
215ポイント を手に入れた。
|
|
|
|
|
Name: keichan ..初心者(6,133ポイント)
Date: 2006/12/05(火) 17:12
No:2377
|
|
Title: Re:エラー表示+再入力
|
|
typo
× gekkyu = boost::lexical_cast<int>(gekkyu);
↓
○ gekkyu = boost::lexical_cast<int>(gekkyu_buf);
2倍のポイントを手に入れた! 126ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..プログラマー(32,295ポイント)
Date: 2006/12/05(火) 17:53
No:2380
|
|
Title: Re:エラー表示+再入力
|
|
boostが入ってるなら spiritでもいいかも。
#include <boost/spirit/core.hpp>
#include <boost/spirit/phoenix/primitives.hpp>
#include <boost/spirit/phoenix/operators.hpp>
#include <iostream>
#include <string>
using namespace boost::spirit;
using namespace phoenix;
int main()
{
std::string gekkyu_buf;
std::cin >> gekkyu_buf;
int n;
if(parse(gekkyu_buf.begin(), gekkyu_buf.end(), int_p[var(n) = arg1], space_p).full)
std::cout << "整数 " << n << std::endl;
else
std::cout << "整数以外が入力された " << std::endl;
return 0;
}
288ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..プログラマー(32,364ポイント)
Date: 2006/12/05(火) 18:06
No:2381
|
|
Title: Re:エラー表示+再入力
|
|
boostがないのならこういう感じで数字かどうか、というより数値に正しく代入できたかどうかが確認できます。
int n;
std::cin >> n;
if(!std::cin.fail())
std::cout << "n = " << n << std::endl;
else
std::cout << "error"<< std::endl;
69ポイント を手に入れた。
|
|
|
|
Name: su- ..ぴよぴよ(25ポイント)
Date: 2006/11/28(火) 20:53
No:2141
|
|
Title: ファィルの入出力
|
|
以下に示すように,任意の長さの文字列が数行に渡って記述されているファイルがあるものとする.このファイルの最長の文字列が記述されている行が何行目であるかとその文字数を答えるプログラムを作成せよ.
『
The technology of a home network system (HNS) allows
integration of several kinds of home appliances to provide
a user with value-added integrated services.
Development of the integrated HNS services requires
implementation of the appliance components (with APIs)
and the services, according to each home-network environment.
There are various implementation standards such as DLNA, ECHONET, OSGi
and Jini for the HNS applications.
Therefore, even if a developer can choose the optimal one,
it's very difficult to develop the integrated services by composing
a new HNS implementation.
』
っという問題です。
<実行結果>
Input file name:mojiretsu.dat
最長文字列は7行目の72文字です。
〆切が今日中で非常に焦っています。
教えてもらえませんか。
おねがいします。
25ポイント を手に入れた。
|
|
|
|
Name: su- ..ぴよぴよ(69ポイント)
Date: 2006/11/28(火) 21:02
No:2142
|
|
Title: Re:ファィルの入出力
|
|
本当に申し訳ありません。
問題の丸投げはいけないって十分分かってるんですけど。。本当に焦っています。お願いします。助けてください。ごめんなさい。
44ポイント を手に入れた。
|
|
|
|
|
Name: box ..初心者(6,728ポイント)
Date: 2006/11/28(火) 21:15
No:2143
|
|
Title: Re:ファィルの入出力
|
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXBUF (256)
int main(void)
{
char file[MAXBUF], s[MAXBUF], str[MAXBUF] = "\0";
int n, maxline, maxlen;
FILE *fp;
printf("Input file name:"), scanf("%s", file);
fp = fopen(file, "r");
if (fp == NULL)
fprintf(stderr, "file open error\n"), exit(1);
for (maxline = n = 1; fgets(s, sizeof(s), fp) != NULL; n++) {
if (strlen(s) > strlen(str)) {
strcpy(str, s);
maxline = n;
maxlen = strlen(s);
}
}
printf("最長文字列は%d行目の%d文字です。\n", maxline, maxlen);
fclose(fp);
return 0;
}
265ポイント を手に入れた。
|
|
|
|
|
Name: box ..初心者(6,917ポイント)
Date: 2006/11/28(火) 21:31
No:2147
|
|
Title: Re:ファィルの入出力
|
|
入力ファイルの各行の末尾にある'\n'を文字数としてカウントしないバージョンです。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXBUF (256)
int main(void)
{
char file[MAXBUF], s[MAXBUF], str[MAXBUF] = "\0";
int n, maxline, maxlen;
FILE *fp;
printf("Input file name:"), scanf("%s", file);
fp = fopen(file, "r");
if (fp == NULL)
fprintf(stderr, "file open error\n"), exit(1);
for (maxline = n = 1; fgets(s, sizeof(s), fp) != NULL; n++) {
s[strlen(s)-1] = '\0';
if (strlen(s) > strlen(str)) {
strcpy(str, s);
maxline = n;
maxlen = strlen(s);
}
}
printf("最長文字列は%d行目の%d文字です。\n", maxline, maxlen);
fclose(fp);
return 0;
}
189ポイント を手に入れた。
|
|
|
|
|
Name: su- ..ぴよぴよ(116ポイント)
Date: 2006/11/28(火) 22:46
No:2149
|
|
Title: Re:ファィルの入出力
|
|
本当にありがとうございます。
今は無理ですが、しっかり復習して、出直して来ます。
本当に無理を言ってごめんさい。
無礼者だと思わないでください。
失礼しました。
47ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..比類無きプログラマー(91,515ポイント)
Date: 2006/11/29(水) 00:00
No:2151
|
|
Title: Re:ファィルの入出力
|
|
su-さん、大丈夫ですよ^^
私も宿題の期限が迫って困ったこともありますしw
以下を読んで、必ずアリゴリズムを確認してくださいね。
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *fp;
int n=0;
char st='\0';
fp = fopen("mojiretu.txt", "r");
if (fp == NULL)
return 1;
while ((st = fgetc(fp)) != EOF){
if(st=='\n')
n++;
}
printf("%d行\n",n);
fclose(fp);
}
これを見て何をするプログラムだか、わかりますか?
もしわからなかったら以下の説明を読んで確認してください。
これは先ほどのプログラムをちょっといじって、
ファイルから読み取った文章が何行であるか調べるプログラムです。
以下のプログラムは上記と全く同じです。注釈でアルゴリズムを確認してください。
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *fp;//ファイルを扱うための変数を宣言。
int n=0;//行数をカウントするための変数
char st='\0';//読み取った1文字を格納するための変数
fp = fopen("mojiretu.txt", "r");//ファイルの情報がある住所をfpに格納
if (fp == NULL)//その住所が無効なら強制終了
return 1;
/*
fgetc関数でファイルから1文字読み取って変数stにその1文字を格納
格納したstがファイルの終端を表すEOFだったらループを抜ける
一度処理が終わるとファイルポインタが1進む。
つまり次に処理をすると今読み取った次の文字ポインタがあわさる
*/
while ((st = fgetc(fp)) != EOF){
if(st=='\n')//読み取った1文字が改行コードなら
n++;//行数カウントアップ
}
printf("%d行\n",n);
fclose(fp);
}
使っていたmojiretu.datは拡張子がこのままでは使いにくいのでmojiretu.txtとしています。
ファイルの内容は同じものです。
わからない関数があれば、その関数名をグーグルで検索すればたいていすぐ説明が書いてあるサイトがみつかります。
このプログラムを参考に以下の問題をやってみましょう。
問題1:
文章の中に「a」が何文字出てくるかカウントするプログラムを書きましょう。
問題2:
7行目に「a」は何行出てくるかカウントするプログラムを書きましょう。
是非、回答を後日投稿してください☆
670ポイント を手に入れた。
|
|
|
|
|
Name: ★ ..かけだし(1,255ポイント)
Date: 2006/12/05(火) 22:55
No:2405
|
|
Title: Re:ファィルの入出力
|
|
今、私、これ必死に考えてますよ★★
もーちょっと、時間くださいねぇー♪
頑張ってますから(笑)
25ポイント を手に入れた。
|
|
|
|
Name: idiot ..ぴよぴよ(354ポイント)
Date: 2006/12/05(火) 14:24
No:2354
|
|
Title: 「シンゴ」さんと同じ問題なんですが…
|
|
下のような問題の時にはどうすればよいでしょうか?
<問題>
実行結果が次のようになるプログラムをつくりなさい。
例
Please enter a statemant: This is a programming class
Total 5 words. Each word contains;
This: 4 letters.
is: 2 letters.
a: 1 letters.
programming: 11 letters.
class: 5 letters.
ただし、単語数の上限は30、一単語の最大文字数は20と仮定する。
文章入力にはgets関数を使用する。
ブラケット演算子なしでポインタだけで書く。
プログラム一部
#include <stdio.h>
#include <string.h>
#define MAX_WORD 30
#define MAX_CHAR 20
int main(void);
int get_word(char *, char (*)[MAX_CHAR]);
void print_word(int, char (*)[MAX_CHAR]);
int main(void)
{
char line[MAX_WORD*MAX_CHAR];
char str[MAX_WORD][MAX_CHAR];
int num;
printf("Please enter a statemant:");
gets(line);
num =get_word(line, str);
print_word(num,str);
return 0;
}
354ポイント を手に入れた。
|
|
|
|
Name: 管理人 [URL] ..ハッカー(111,590ポイント)
Date: 2006/12/05(火) 15:01
No:2363
|
|
Title: Re:「シンゴ」さんと同じ問題なんですが…
|
|
シンゴさんの投稿をみていらっしゃるのでしたらkeichanさんの投稿もみていらっしゃいますか?
それでしたらkeichanさんのプログラムを少しいじれば出来ると思います。
普通に関数化したいだけですよね?
関数化するとこうなるんじゃないでしょうか。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_WORD (30) ///< 最大単語数
#define MAX_LENGTH (20) ///< 単語毎の最大文字数
#define BUFFER_SIZE (1024) ///< 入力バッファサイズ
int get_word(char *, char (*)[MAX_LENGTH]);
void print_word(int, char (*)[MAX_LENGTH]);
int get_word(char buffer [MAX_LENGTH],char word[MAX_WORD][MAX_LENGTH]){
char* token = NULL; ///< トークン操作用
const char separator[] = " ,\t\n"; ///< トークンを分割する文字達
int token_num = 0; ///< トークン数
if( gets(buffer) == NULL )
exit (1);
token = strtok(buffer, separator);
while( token != NULL ) {
strcpy(word[token_num++], token);
token = strtok(NULL, separator);
}
return token_num;
}
void print_word(int token_num,char word[MAX_WORD][MAX_LENGTH]){
int token_count; ///< トークンカウンタ(コンソール出力制御に使用)
printf("\nTotal %d words. Each word contains;\n", token_num);
for( token_count = 0; token_count < token_num; token_count++ ) {
printf("%s: %d letters.\n", word[token_count], strlen(word[token_count]));
}
}
int main(){
char word[MAX_WORD][MAX_LENGTH] = {0}; ///< トークン分割後の単語保存領域
char buffer[BUFFER_SIZE] = {0}; ///< 入力用バッファ
int token_num = 0; ///< トークン数
printf("Please enter a statement: ");
token_num = get_word(buffer,word);
print_word(token_num,word);
return 0;
}
433ポイント を手に入れた。
|
|
|
|
|
Name: idiot ..ぴよぴよ(422ポイント)
Date: 2006/12/05(火) 15:57
No:2364
|
|
Title: Re:「シンゴ」さんと同じ問題なんですが…
|
|
やってもらっておいて大変失礼なんですが、自分まだ学校でトークンというものを学習していないので、できればトークンなしで教えてほしいのですが…
68ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(112,534ポイント)
Date: 2006/12/05(火) 16:48
No:2368
|
|
Title: Re:「シンゴ」さんと同じ問題なんですが…
|
|
strtokは、とても便利な関数です。
そんなに難しい関数じゃないのでこの機会に是非覚えてみてはいかがでしょうか?
#include <stdio.h>
#include <string.h>
int main(void){
int i=0;//forで使うi
char s[5][5],str[] = "8,6,7,9,2",*tp;
tp = strtok( str ,"," );//読み取る文字列はstr。区切るのは「,」
while (1){
if ( tp != NULL ){ //最後まで読み取ってなかったら
strcpy(s[i],tp);//区切られた区間の文字列をsに格納
i++;
}
else//最後まで読み取られたらブレイク
break;
tp = strtok( NULL, "," );//「,」を区切りにして次までのトークンへのポインタを返す
}
for(i=0;i<5;i++)
printf("%s\n",s[i]);
return 0;
}
こちらにサンプルを書いておりますので、実際にコンパイルしてみてください。
char s[5][5],str[] = "8,6,7,9,2",*tp;
ここでstrにこのように代入しています。
tp = strtok( str ,"," );//読み取る文字列はstr。区切るのは「,」
strtokはポインタが返るので、tpにポインタを格納します。
この文字列情報があるアドレスだと思ってください。
具体的には最初、str[0]のアドレスが入ります。
tp = strtok( NULL, "," );
次にこの処理をすると、tpから次に,があるまでの区間を文字列としてくれます。
それは次にある,が\0に変わるのです。
文字列はtpから\0までを示しますから、str[0]から次の,までが文字列となります。
つまりこの時点でtpと示すと8になります。
一回呼ぶと、tpは進みます。tpが示すアドレスは次には先ほど,があった一つ先のところに
つまりstr[2]のアドレスへ移動します。
次に
tp = strtok( NULL, "," );
を呼ぶと、その次の,までを文字列とします。を\0に変換してかえしてくれるので、
str[2]からstr[3]までを文字列としてくれます。
つまりこのとき、tpと示すと、6となるわけです。
sにはその区切られた文字が個別にはいるので、printf文でこのように表示されるわけですね。
944ポイント を手に入れた。
|
|
|
|
|
Name: idiot ..ぴよぴよ(452ポイント)
Date: 2006/12/05(火) 22:32
No:2403
| 解決!
|
Title: Re:「シンゴ」さんと同じ問題なんですが…
|
|
ありがとうございます。いろいろと助かりました。早速勉強してみます。
30ポイント を手に入れた。
|
|
|
|
Name: peace ..かけだし(1,314ポイント)
Date: 2006/12/02(土) 21:29
No:2231
|
|
Title: 行列計算について
|
|
はじめまして!大学生やってるpeaceです。
大学の必修科目の課題ができなくて悩んでいます(;_;)
まず乱数を生成しファイルに出力するプログラムを作成します。
ここで二つのテキストファイルに乱数を出力させました。
次にそのプログラムを実行後テキストファイルに出力された乱数を2つの2次元配列に読み込み行列の和と積を求め演算結果をファイルに出力するプログラムを作るというものです。
乱数をファイルに出力するプログラムは問題無いのですが、乱数を2次元配列に読み込んで行列演算し、結果をファイルに出力するプログラムがうまくできません。取りあえず1個目のプログラムは問題ないと思うので2個目のプログラムを書きます。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *myfile1;
FILE *myfile2;
FILE *myfile3;
int **array1 = (int **)malloc(sizeof(int)*100);
int **array2 = (int **)malloc(sizeof(int)*100);
int i,j,k,num1,num2;
int wa[20][20],seki[20][20];
char line[124];
for(i=0; i<100; ++i)
{
array1[i] = (int*)malloc(sizeof(int)*100);
}
if((myfile1=fopen("1つ目のテキストファイル名","r"))==NULL){
fprintf(stderr,"Cannot open 1つ目のテキストファイル名\n");
return 1;
}
for(i=0; i<10; ++i)
{
for(j=0; j<10; ++j)
{
fgets(line,sizeof(line),myfile1);
sscanf(line,"%d",&num1);
array1[i][j] = num1;
}
}
for(i=0; i<10; ++i)
{
array2[i] = (int*)malloc(sizeof(int)*100);
}
if((myfile2=fopen("二つ目のテキストファイル名","r")) == NULL){
fprintf(stderr,"Cannnot open 二つ目の乱数ファイル名\n");
return 1;
}
for(i=0; i<10; ++i)
{
for(j=0; j<10; ++j)
{
fgets(line,sizeof(line),myfile2);
sscanf(line,"%d",&num2);
array2[i][j] = num2;
}
}
if((myfile3=fopen("演算結果を書き込むテキストファイル名\n")
return 1;
}
fprintf(myfile3,"行列の和\n");
for(i=0; i<10; i++){
for(j=0; j<10; j++){
wa[i][j] = array[i][j] + array2[i][j];
fprintf(myfile3, "%d ",wa[i][j] );
}
fprintf(myfile3, "\n");
fprintf(myfile3,"行列の積\n");
for(i=0; i<10; i++) {
for(j=0; j<10; j++){
seki[i][j] = 0;
for(k=0; k<10; k++)
seki[i][j] += array1[i][k] *array2[k][j];
fprintf(myfile3,"%d",seki[i][j] );}
fprintf(myfile3,"\n" );
}
fclose(myfile3);
fclose(myfile1);
for(i=0; i<100; ++i)
{
free( array1[i] );
}
free( array1 );
fclose(myfile2);
for(i=0; i<100; ++i)
{
free( array2[i] );
}
free( array2 );
return 0;
}
直したいところは固定長の行列の生成と演算しかできないところです。malloc使用も固定長なので駄目だといわれてしまいました。
教えてもらえるような友人もいなく独りでずっと考えてたのですが
手のつけようがなかったので、手助けお願いしますm(_ _)m
年末は何かと忙しい時期なのに、申し訳ないです(T_T)
1,314ポイント を手に入れた。
|
|
|
|
Name: Justy ..プログラマー(29,580ポイント)
Date: 2006/12/02(土) 22:29
No:2232
|
|
Title: Re:大学の課題についてです
|
|
固定サイズの行列がだめなら行列の縦横のサイズはどうやって決定するんでしょう?
又、読み込むテキストファイルはどのように書かれているのでしょうか?
2倍のポイントを手に入れた! 146ポイント を手に入れた。
|
|
|
|
|
Name: peace ..かけだし(1,602ポイント)
Date: 2006/12/03(日) 09:52
No:2244
|
|
Title: Re:大学の課題についてです
|
|
まずは御返事ありがとうございます^_^
>固定サイズの行列がだめなら行列の縦横のサイズはどうやって決定するんでしょう?
そこで手がつけようもなくなり悩んでいます。
動的な行列っていうことは、読み込むデータ数によって縦横のサイズが変わるってことですよね?そうなるとデータの数によって行列が作れない場合など、でてきて一体どうすればって感じです(;_;)先生に一回プログラムを提出したところ、こう直すように言われたのですが先生の言い方が悪かったのか私が理解していないのか・・・。
先生にプログラムの駄目だしされた時点では
int wa[5][5],seki[5][5];/*line11*/
for(文A;条件B;文C)の全ての条件Bを
変数<5としていました。
テキストファイルについては2つとも0~100の範囲の乱数を
i_random=rand()%101
fprintf(myfile1,"%d\n",i_random);
で30個書き込んでます。
45
86
47
1
48
という感じに30行続いてます。
手元にプログラムソースがプリントしかないので読みづらい所が
あるかもしれないですがよろしくお願いします。
288ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..プログラマー(29,817ポイント)
Date: 2006/12/03(日) 12:59
No:2245
|
|
Title: Re:大学の課題についてです
|
|
では、こうしてみてはどうでしょう。
課題1の方のテキストに乱数を出力する際に
・ 乱数5〜30くらいの数値を2つ出して、それを行列サイズX、Yとする。
・ 仮にそのXが8、Yが6だったら
8, 6
726 248 952 828 633 484 436 385
376 927 983 218 712 838 820 645
896 240 500 114 671 48 442 877
342 754 562 807 841 917 117 959
132 662 883 122 654 33 17 977
559 216 475 88 422 657 576 352
のようにテキストを出力してみてはどうでしょうか。
課題2の方ではテキストの先頭に行列サイズが入っているので、そのサイズ情報を信用して次の行からの行列を読む、という方法です。
237ポイント を手に入れた。
|
|
|
|
|
Name: peace ..かけだし(1,648ポイント)
Date: 2006/12/03(日) 16:31
No:2261
|
|
Title: Re:大学の課題についてです
|
|
8,6だけ行列のサイズとして読み込ませるということは
strtok関数を使えばいいのでしょうか・・・
ほとんど知識がないので見当はずれなこと言ってたらすいません。
元々乱数の出力させるファイルを一つにして、strtok関数を使って
2つの行列を作ろうとしてたのですが、使い方がよく分からず、
断念した関数です(T_T)
46ポイント を手に入れた。
|
|
|
|
|
Name: box ..中級者(9,354ポイント)
Date: 2006/12/03(日) 17:12
No:2271
|
|
Title: Re:大学の課題についてです
|
|
> 8,6だけ行列のサイズとして読み込ませるということは
> strtok関数を使えばいいのでしょうか・・・
こんなサンプルを動かしてみてください。
#include <stdio.h>
int main(void)
{
char s[] = "8, 6"; /* 実際にはファイルから読んだつもり */
int m, n;
sscanf(s, "%d,%d", &m, &n);
printf("%d %d\n", m, n);
return 0;
}
120ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(103,705ポイント)
Date: 2006/12/03(日) 17:24
No:2272
|
|
Title: Re:大学の課題についてです
|
|
strtokの使い方はこんな感じでどうでしょうか?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char str[] = "8,6,7,9,2",st[5][5];
char *tp;
int i=0,s[5];
tp = strtok( str, "," );
strcpy(st[i],tp);
i++;
while ( tp != NULL ) {
tp = strtok( NULL,"," );
if ( tp != NULL ){
strcpy(st[i],tp);
i++;
}
}
for(i=0;i<5;i++){
s[i]=atoi(st[i]);
printf("%d\n",s[i]);
}
return 0;
}
もっとスマートにかけると思いますが、わかりやすくダラダラと書きました。
2倍のポイントを手に入れた! 532ポイント を手に入れた。
|
|
|
|
|
Name: peace ..かけだし(1,730ポイント)
Date: 2006/12/03(日) 17:34
No:2273
|
|
Title: Re:大学の課題についてです
|
|
御返事ありがとうございます。
自宅でプログラミングやる環境がないので
明日学校で試してみようと思います。
明日パソコン演習室が使える時間が3時間で、締め切りが火曜日(T_T)
やはり、プログラミングを学ぶには自宅で環境作らないと
よろしくないみたいですね。
82ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(103,853ポイント)
Date: 2006/12/03(日) 17:37
No:2274
|
|
Title: Re:大学の課題についてです
|
|
スマートに書くとこんな感じでしょうか。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char str[] = "8,6,7,9,2";//格納されている文字列
char *tp;//トークンへのポインタ
int i=0,s[5];//forで使うiと数値を格納するs
tp = strtok( str ,"," );//読み取る文字列はstr。区切るのは「,」
while (1){
if ( tp != NULL ){ //最後まで読み取ってなかったら
s[i]=atoi(tp);//区切られた区間の文字列をint型に変換して格納
i++;
}
else//最後まで読み取られたらブレイク
break;
tp = strtok( NULL, "," );//「,」を区切りにして次までのトークンへのポインタを返す
}
for(i=0;i<5;i++)
printf("%d\n",s[i]);
return 0;
}
148ポイント を手に入れた。
|
|
|
|
|
Name: peace ..かけだし(1,806ポイント)
Date: 2006/12/03(日) 18:03
No:2276
|
|
Title: Re:大学の課題についてです
|
|
コンパイラはDLできたみたいですが
CPad for Borland C++Compilerっていうテキストエディタが
お金かかるみたいで・・・。
今すぐに導入するのは難しそうです。
76ポイント を手に入れた。
|
|
|
|
|
Name: peace ..かけだし(1,850ポイント)
Date: 2006/12/03(日) 19:42
No:2279
|
|
Title: Re:大学の課題についてです
|
|
ありがとうございます。
ちょっと今から用事あるので22時過ぎからチャレンジしてみようと思います^^
44ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..プログラマー(30,050ポイント)
Date: 2006/12/03(日) 20:17
No:2280
|
|
Title: Re:大学の課題についてです
|
|
よくかんがえたら。
行列のサイズ情報をテキストに書き出してるんだから、わざわざ数値を横に並べなくても良かったですよね。
8, 6
726 248 952 828 633 484 436 385
..... じゃなくて
8
6
726
248
952
828
633
484
436
385
..... こうとか。
この方が楽かも。
233ポイント を手に入れた。
|
|
|
|
|
Name: peace ..かけだし(1,943ポイント)
Date: 2006/12/04(月) 00:07
No:2284
|
|
Title: Re:大学の課題についてです
|
|
とても親切に答えていただいて凄く助かります^^
一応コンパイラの環境設定まで終わったのですが
色々と手間取って思ったよりも時間がかかりそうなので、
家で環境を作るのは明日にしようと思います。
明日は朝5時に起きないといけないので今日は寝ます。
留年の2文字が背後から近づいてきてる(T_T)
93ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(104,271ポイント)
Date: 2006/12/04(月) 01:06
No:2285
|
|
Title: Re:大学の課題についてです
|
|
コンパイラの設定って慣れてないと時間かかりますよね!
特に「環境変数?」なんじゃそりゃ!
みたいなツボにはまると朝までかかったりw
とりあえずコマンドプロンプト出して
bcc
と入力したら説明が色々出てくるようになれば、OKです。
留年の危機とは、私と同じような道通ってますねぇ。
嫌いな科目はほんとほっとくタイプなんで^^;
スレスレで進級してきましたよw
また何かわからなかったら聞いてください☆
149ポイント を手に入れた。
|
|
|
|
|
Name: peace ..かけだし(1,770ポイント)
Date: 2006/12/04(月) 12:46
No:2289
|
|
Title: Re:大学の課題についてです
|
|
色々と設定が多く(ファイルの拡張子?とか・・)時間がかかり、課題の方に支障がでそうなので
時間に余裕ができてから、プログラミングできる環境を作ってみようと思います(^_^;)
取りあえずはJustyさんと管理人さんとboxさんのプログラムを参考に
今日はやってみようと思います。
まだ明日も3時間程演習室が使えるのでがんばってっ見ようと思います!
173ポイント を落としてしまった。
|
|
|
|
|
Name: peace ..入門者(2,807ポイント)
Date: 2006/12/04(月) 20:19
No:2302
|
|
Title: Re:大学の課題についてです
|
|
学校行ったんですがこの掲示板がアクセス禁止になってて見れませんでした(T_T)
皆さんのせっかくの助言を思い出しながらやったのですが、
自分の力不足のせいで活かすことができませんでした、ごめんなさいm(_ _)m
結局行列のサイズの指定は行列を全て正方行列にし、
コマンドラインから行おうとしてみたのですが、
セグメンテーションエラーが出てうまくいきませんでした。
取りあえずやったところまで載せてみますが、全然自信がないです・・・。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *myfile1;
FILE *myfile2;
FILE *myfile3;
int **array1 = (int **)malloc(sizeof(int)*100);
int **array2 = (int **)malloc(sizeof(int)*100);
int i,j,k,num1,num2,a;
int wa[20][20],seki[20][20];
char line[124],buff[124];
for(i=0; i<100; ++i)
{
array1[i] = (int*)malloc(sizeof(int)*100);
}
printf("何次正方行列にするか指定してください>>");
fgets(buff,sizeof(buff),stdin);
sscanf(buff,"%d",&a);
if((myfile1=fopen("1つ目のテキストファイル名","r"))==NULL){
fprintf(stderr,"Cannot open 1つ目のテキストファイル名\n");
return 1;
}
for(i=0; i<a; ++i)
{
for(j=0; j<a; ++j)
{
fgets(line,sizeof(line),myfile1);
sscanf(line,"%d",&num1);
array1[i][j] = num1;
}
}
for(i=0; i<100; ++i)
{
array2[i] = (int*)malloc(sizeof(int)*100);
}
if((myfile2=fopen("二つ目のテキストファイル名","r")) == NULL){
fprintf(stderr,"Cannnot open 二つ目の乱数ファイル名\n");
return 1;
}
for(i=0; i<a; ++i)
{
for(j=0; j<a; ++j)
{
fgets(line,sizeof(line),myfile2);
sscanf(line,"%d",&num2);
array2[i][j] = num2;
}
}
if((myfile3=fopen("演算結果を書き込むテキストファイル名\n")
return 1;
}
fprintf(myfile3,"行列の和\n");
for(i=0; i<a; i++){
for(j=0; j<a; j++){
wa[i][j] = array[i][j] + array2[i][j];
fprintf(myfile3, "%d ",wa[i][j] );
}
fprintf(myfile3, "\n");
fprintf(myfile3,"行列の積\n");
for(i=0; i<a; i++) {
for(j=0; j<a; j++){
seki[i][j] = 0;
for(k=0; k<a; k++)
seki[i][j] += array1[i][k] *array2[k][j];
fprintf(myfile3,"%d",seki[i][j] );}
fprintf(myfile3,"\n" );
}
fclose(myfile3);
fclose(myfile1);
for(i=0; i<100; ++i)
{
free( array1[i] );
}
free( array1 );
fclose(myfile2);
for(i=0; i<100; ++i)
{
free( array2[i] );
}
free( array2 );
return 0;
}
拙いプログラムでごめんなさいm(_ _)m
どうか間違いの指摘をお願い致します。
全然違う!って場合は申し訳ないですが完成したプログラムを頂きたいです。
1,037ポイント を手に入れた。
|
|
|
|
|
Name: box ..中級者(11,512ポイント)
Date: 2006/12/04(月) 21:27
No:2306
|
|
Title: Re:大学の課題についてです
|
|
【乱数を2つのテキストファイルに書き込むプログラム】
この例では、正方行列の行(=列)の数を2〜10とし、1〜20の範囲の乱数を
2つのファイルに書き込んでいます。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
FILE *fp1, *fp2;
int row, i;
fp1 = fopen("rand1.dat", "w");
if (fp1 == NULL)
fprintf(stderr, "file open error\n"), exit(1);
fp2 = fopen("rand2.dat", "w");
if (fp2 == NULL)
fprintf(stderr, "file open error\n"), exit(1);
do {
printf("正方行列の行(列)の数(2〜10):");
scanf("%d", &row);
} while (row < 2 || 10 < row);
fprintf(fp1, "%d\n", row);
fprintf(fp2, "%d\n", row);
srand((unsigned int) time(NULL));
for (i = 0; i < row * row; i++) {
fprintf(fp1, "%d\n", rand() % 20 + 1);
fprintf(fp2, "%d\n", rand() % 20 + 1);
}
fclose(fp1), fclose(fp2);
return 0;
}
【2つのファイルから乱数を読み込んで2つの正方行列にセットし、和と積を求めるプログラム】
上のプログラムで作成したテキストファイルから正方行列の要素を読み取り、
和と積を求めます。計算結果を、テキストファイルに書き込みます。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fp1, *fp2, *fp3;
int row, i, j, k;
int **arr1, **arr2;
fp1 = fopen("rand1.dat", "r");
if (fp1 == NULL)
fprintf(stderr, "file open error\n"), exit(1);
fp2 = fopen("rand2.dat", "r");
if (fp2 == NULL)
fprintf(stderr, "file open error\n"), exit(1);
fp3 = fopen("result.dat", "w");
if (fp3 == NULL)
fprintf(stderr, "file open error\n"), exit(1);
fscanf(fp1, "%d", &row);
fscanf(fp2, "%d", &row);
arr1 = (int **) malloc(sizeof(int *) * row);
if (arr1 == NULL)
fprintf(stderr, "out of memory\n"), exit(1);
for (i = 0; i < row; i++) {
arr1[i] = (int *) malloc(sizeof(int) * row);
if (arr1[i] == NULL)
fprintf(stderr, "out of memory\n"), exit(1);
}
arr2 = (int **) malloc(sizeof(int *) * row);
if (arr2 == NULL)
fprintf(stderr, "out of memory\n"), exit(1);
for (i = 0; i < row; i++) {
arr2[i] = (int *) malloc(sizeof(int) * row);
if (arr2[i] == NULL)
fprintf(stderr, "out of memory\n"), exit(1);
}
fprintf(fp3, "【行列1】\n");
for (i = 0; i < row; i++) {
for (j = 0; j < row; j++) {
fscanf(fp1, "%d", &arr1[i][j]);
fprintf(fp3, "%5d", arr1[i][j]);
}
fprintf(fp3, "\n");
}
fprintf(fp3, "\n\n");
fprintf(fp3, "【行列2】\n");
for (i = 0; i < row; i++) {
for (j = 0; j < row; j++) {
fscanf(fp2, "%d", &arr2[i][j]);
fprintf(fp3, "%5d", arr2[i][j]);
}
fprintf(fp3, "\n");
}
fprintf(fp3, "\n\n");
fprintf(fp3, "【和】\n");
for (i = 0; i < row; i++) {
for (j = 0; j < row; j++)
fprintf(fp3, "%8d", arr1[i][j] + arr2[i][j]);
fprintf(fp3, "\n");
}
fprintf(fp3, "\n\n");
fprintf(fp3, "【積】\n");
for (i = 0; i < row; i++) {
for (j = 0; j < row; j++) {
int sum;
for (sum = k = 0; k < row; k++)
sum += arr1[i][k] * arr2[k][j];
fprintf(fp3, "%8d", sum);
}
fprintf(fp3, "\n");
}
fprintf(fp3, "\n\n");
for (i = 0; i < row; i++)
free(arr1[i]), free(arr2[i]);
free(arr1), free(arr2);
fclose(fp1), fclose(fp2), fclose(fp3);
return 0;
}
2倍のポイントを手に入れた! 2,074ポイント を手に入れた。
|
|
|
|
|
Name: peace ..入門者(3,029ポイント)
Date: 2006/12/04(月) 21:44
No:2308
|
|
Title: Re:大学の課題についてです
|
|
boxさん本当に有難うございます(T_T)
それにしても私のプログラムは全然違ってたみたいですね・・・
あとで皆さんのプログラムを見てじっくり勉強させていただきます。
今はレポートの完成が最優先ですが。
アドバイスを頂いた皆さんにはとても感謝してますm(_ _)m
今までプログラミングに苦手意識をもってて遠ざけてきましたが
今回真正面からぶつかってみて少しC言語に興味がもてました。
次回ここの掲示板に現れるときはアドバイスする側になってるようにしたいです。
本当にありがとうございました。
222ポイント を手に入れた。
|
|
|
|
|
Name: peace ..入門者(3,054ポイント)
Date: 2006/12/04(月) 22:15
No:2311
|
|
Title: Re:大学の課題についてです
|
|
あ、そうです。
プリントに印刷したのを見ながら打ってるので抜けちゃってました。
ごめんなさい。
25ポイント を手に入れた。
|
|
|
|
|
Name: peace ..入門者(3,123ポイント)
Date: 2006/12/05(火) 19:40
No:2388
| 解決!
|
Title: Re:大学の課題についてです
|
|
無事終わったので解決にしときます。
それにしてもC言語について余り知識がない私でも
boxさんのプログラムは凄い綺麗だなぁと感じました。
本当に皆さんありがとうございました。
69ポイント を手に入れた。
|
|
|
|
Name: メンチ ..ぴよぴよ(386ポイント)
Date: 2006/12/04(月) 11:57
No:2286
|
|
Title: シューティングゲームの館についての質問
|
|
現在、6. 先ほどのプログラムを分割する。をやっているのですが
initial.obj : error LNK2005: "struct BODY_player_t Player" (?Player@@3UBODY_player_t@@A) はすでに img_sound_load.obj で定義されています
background.obj : error LNK2005: "struct BODY_player_t Player" (?Player@@3UBODY_player_t@@A) はすでに img_sound_load.obj で定義されています
player.obj : error LNK2005: "struct BODY_player_t Player" (?Player@@3UBODY_player_t@@A) はすでに img_sound_load.obj で定義されています
fps.obj : error LNK2005: "struct BODY_player_t Player" (?Player@@3UBODY_player_t@@A) はすでに img_sound_load.obj で定義されています
main.obj : error LNK2005: "struct BODY_player_t Player" (?Player@@3UBODY_player_t@@A) はすでに img_sound_load.obj で定義されています
LIBCMT.lib(wwincrt0.obj) : error LNK2001: 外部シンボル "_wWinMain@16" は未解決です
Debug/STG.exe : fatal error LNK1120: 外部参照 1 が未解決です。
link.exe の実行エラー
と、出てしまうのですがどうやって解決したらいいのでしょうか。
386ポイント を手に入れた。
|
|
|
|
Name: 管理人 [URL] ..ハッカー(104,450ポイント)
Date: 2006/12/04(月) 12:32
No:2287
|
|
Title: Re:シューティングゲームの館についての質問
|
|
メンチさん、こんにちは。
構造体の宣言が重複しているのではないでしょうか?
変数宣言集であるGlobalVariable.hでも
グローバル宣言集であるExternGV.hでも
BODY_player_t Player;
と宣言すると、このようなエラーが出ると思いますが、
ExternGV.hでは
extern BODY_player_t Player;
とすればよいと思います。
ExternGV.hではextern BODY_player_t Player;と構造体が宣言されていますか?
179ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(104,491ポイント)
Date: 2006/12/04(月) 12:41
No:2288
|
|
Title: Re:シューティングゲームの館についての質問
|
|
↑画像クリックで拡大↑
先ほど実際に自分でも6章通りにやってみました。
画像の通りに
ExternGV.hを書いてちゃんとコンパイル通りました。
なんら独自の変更は加えていません。
6章どおりコピー・ペーストしていっただけです。
もう一度、コピーペーストがきちんと出来ているか、
特に先ほどのexternの部分がきちんとかけているか、ご確認ください。
41ポイント を手に入れた。
|
|
|
|
|
Name: メンチ ..かけだし(2,102ポイント)
Date: 2006/12/05(火) 10:45
No:2337
|
|
Title: Re:シューティングゲームの館についての質問
|
|
ありがとうございました。
こちらの単純なミスのせいだったので、今後はもっと気をつけて見ようと思います。
ほとんどのエラーは消えたのですが、
リンク中...
LIBCMT.lib(wwincrt0.obj) : error LNK2001: 外部シンボル "_wWinMain@16" は未解決です
Debug/STG.exe : fatal error LNK1120: 外部参照 1 が未解決です。
link.exe の実行エラ
これだけが、消えません。
他のところで、
「「Win32 Application」でmainを実装しているのだと思いますが
とりあえず簡単にはこれではうまくビルドできません(単に僕が知らないだけかも)
「Win32 Console Application」を選べばmainで始まるプログラムを
ビルドできます
WinMainで始まるプログラムで良ければ「Win32 Application」の後のステップ1/1で
「単純なWin32アプリケーション」か「標準的な"Hello World!"アプリケーション」
を選ぶと楽です
また、「Win32 Console Application」でもステップ1/1で
「単純アプリケーション」や「"Hello, World!"アプリケーション」
等を選んでも少し楽ができます
mainで始めたければ「Win32 Console Application」
WinMainで始めたければ「Win32 Application」
とでも覚えておけば、今後このエラーに悩まされる可能性が減ります」
と、書いてあったので試してみたのですが、
コンパイル中...
background.cpp
c:\documents and settings\???\デスクトップ\いろいろ\授業\c\三回目\background.cpp(13) : fatal error C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
fps.cpp
c:\documents and settings\???\デスクトップ\いろいろ\授業\c\三回目\fps.cpp(24) : fatal error C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
img_sound_load.cpp
c:\documents and settings\???\デスクトップ\いろいろ\授業\c\三回目\img_sound_load.cpp(11) : fatal error C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
initial.cpp
c:\documents and settings\???\デスクトップ\いろいろ\授業\c\三回目\initial.cpp(18) : fatal error C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
main.cpp
c:\documents and settings\???\デスクトップ\いろいろ\授業\c\三回目\main.cpp(52) : fatal error C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
player.cpp
c:\documents and settings\???\デスクトップ\いろいろ\授業\c\三回目\player.cpp(10) : fatal error C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
コードを生成中...
cl.exe の実行エラー
三回目.exe - エラー 6、警告 0
と、でてしまいたした。どうすればいいのでしょうか?
2倍のポイントを手に入れた! 1,716ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..プログラマー(31,689ポイント)
Date: 2006/12/05(火) 14:18
No:2352
|
|
Title: Re:シューティングゲームの館についての質問
|
|
>予期しない EOF
このエラーは MSVCのプリコンパイルヘッダ関連のエラーです。
解決方法は2通りあります。
1 stdafx.h
もしソースコードのあるディレクトリに stdafx.hがあるのなら(本当は stdafx.hとは限らないのですが)、各 cpファイルの全ての先頭に
#include "stdafx.h"
を追加してみてください。
2 プリコンパイルヘッダを使わない
ソリューションエクスプローラで対象のプロジェクトを選択して右クリック→プロパティで、プロパティダイアログを出してください。
その中の「構成プロパティ」→「C/C++」→「プリコンパイル済みヘッダ」という項目があるのでクリックしてください。
するとダイアログ内の右側の内容が変化し、「プリコンパイル済みヘッダの作成/使用」という項目があるのでそれを「プリコンパイル済みヘッダを使用しない」、としてください。
同様にソリューションエクスプローラ内にある各 cppファイルも選択して「プリコンパイル済みヘッダの作成/使用」の設定を「プリコンパイル済みヘッダを使用しない」としてください。
402ポイント を手に入れた。
|
|
|
|
Name: シンゴ ..ぴよぴよ(104ポイント)
Date: 2006/12/04(月) 13:15
No:2290
|
|
Title: 文字列の問題について
|
|
学校でだされた問題でよくわからないところがありやってみてもできないので誰かこの問題をやってみていただけないでしょうか?
<問題>
実行結果が次のようになるプログラムをつくりなさい。
例
Please enter a statemant: This is a programming class
Total 5 words. Each word contains;
This: 4 letters.
is: 2 letters.
a: 1 letters.
programming: 11 letters.
class: 5 letters.
ただし、単語数の上限は30、一単語の最大文字数は20と仮定する。
文章入力にはgets関数を使用する。
という問題なんですがよろしくお願いします。
104ポイント を手に入れた。
|
|
|
|
Name: keichan ..入門者(4,795ポイント)
Date: 2006/12/04(月) 16:13
No:2291
|
|
Title: Re:文字列の問題について
|
|
#include <stdio.h>
#include <string.h>
#define MAX_WORD (30) ///< 最大単語数
#define MAX_LENGTH (20) ///< 単語毎の最大文字数
#define BUFFER_SIZE (1024) ///< 入力バッファサイズ
int main()
{
const char separator[] = " ,\t\n"; ///< トークンを分割する文字達
char word[MAX_WORD][MAX_LENGTH] = {0}; ///< トークン分割後の単語保存領域
char buffer[BUFFER_SIZE] = {0}; ///< 入力用バッファ
char* token = NULL; ///< トークン操作用
int token_num = 0; ///< トークン数
int token_count; ///< トークンカウンタ(コンソール出力制御に使用)
printf("Please enter a statement: ");
if( gets(buffer) == NULL ) {
/// エラー発生
return 1;
}
/// トークン分割
token = strtok(buffer, separator);
while( token != NULL ) {
strcpy(word[token_num++], token);
token = strtok(NULL, separator);
}
printf("\nTotal %d words. Each word contains;\n", token_num);
for( token_count = 0; token_count < token_num; token_count++ ) {
printf("%s: %d letters.\n", word[token_count], strlen(word[token_count]));
}
return 0;
}
不明な点があれば何でもどうぞ。
4ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..プログラマー(30,186ポイント)
Date: 2006/12/04(月) 16:25
No:2292
|
|
Title: Re:文字列の問題について
|
|
ざっと見た感じ、
char word[MAX_WORD][MAX_LENGTH] = {0};
は
char word[MAX_WORD][MAX_LENGTH + 1] = {0};
じゃないですか?
136ポイント を手に入れた。
|
|
|
|
|
Name: keichan ..入門者(4,875ポイント)
Date: 2006/12/04(月) 16:50
No:2294
|
|
Title: Re:文字列の問題について
|
|
追記です。
#define MAX_LENGTH (20 + 1) ///< 単語毎の最大文字数
こっちの方がいいですね。^^
54ポイント を手に入れた。
|
|
|
|
|
Name: シンゴ ..ぴよぴよ(184ポイント)
Date: 2006/12/04(月) 21:01
No:2305
| 解決!
|
Title: 文字列の問題について
|
|
keichanさんのプログラムを教科書などを見て調べてやってみたら内容はほとんどわかりました。
今度は自分でできるようにもっと勉強をしていきたいと思います。意見をくださった方にはとても感謝してます。ありがとうございました。
80ポイント を手に入れた。
|
|
|
|
|
Name: シンゴ ..ぴよぴよ(260ポイント)
Date: 2006/12/04(月) 21:57
No:2309
|
|
Title: Re:文字列の問題について
|
|
すいません、わかったつもりだったんですが
token = strtok(buffer, separator);
while( token != NULL ) {
strcpy(word[token_num++], token);
token = strtok(NULL, separator);
のところの意味がいまいち理解できません。教えていただけないでしょうか?
76ポイント を手に入れた。
|
|
|
|
|
Name: シンゴ ..ぴよぴよ(278ポイント)
Date: 2006/12/04(月) 22:58
No:2316
|
|
Title: Re:文字列の問題について
|
|
ありがとうございます。
理解できるまで何回もよんでみます。
18ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(105,520ポイント)
Date: 2006/12/04(月) 23:23
No:2317
|
|
Title: Re:文字列の問題について
|
|
strtok関数の使い方をいかに説明してみました。
strにある文字列を,で区切ってそれぞれの数字を格納しています。
#include <stdio.h>
#include <string.h>
int main(void){
int i=0;//forで使うi
char s[5][5],str[] = "8,6,7,9,2",*tp;
tp = strtok( str ,"," );//読み取る文字列はstr。区切るのは「,」
while (1){
if ( tp != NULL ){ //最後まで読み取ってなかったら
strcpy(s[i],tp);//区切られた区間の文字列をsに格納
i++;
}
else//最後まで読み取られたらブレイク
break;
tp = strtok( NULL, "," );//「,」を区切りにして次までのトークンへのポインタを返す
}
for(i=0;i<5;i++)
printf("%s\n",s[i]);
return 0;
}
382ポイント を手に入れた。
|
|
|
|
|
Name: シンゴ ..ぴよぴよ(304ポイント)
Date: 2006/12/05(火) 13:14
No:2341
| 解決!
|
Title: Re:文字列の問題について
|
|
だいたい使い方がわかりました。
親切に教えていただきありがとうございました。
26ポイント を手に入れた。
|
|
|
|
Name: ten ..ぴよぴよ(568ポイント)
Date: 2006/12/05(火) 01:53
No:2322
|
|
Title: 課題です
|
|
次のようなプログラムを作れ。
1. 数値を順番に読み込んで二次元の配列に格納する。
2. その配列を画面に出力する。
3. 次に、2つの整数を読み込む。
4. 二次元配列のうち、読み込んだ整数に対応する二つの行の内容を交換する。
5. 配列を画面に出力する。配列の読み込み、交換、出力はそれぞれ関数にすること。
という課題をやってます。
コンパイしても、エラーいっぱい困ってます。
どうかアドバイス下さい。
ソースです。
#include <stdio.h>
void reve(int *);
int read(int *);
void write(int *);
int main ()
{
int x[5][5];
read(x);
write(x);
reve(x);
write(x);
return 0;
}
int read(int x[]) /* 読み込み関数 */
{
int i, j;
i=0;
j=0;
while(i <= 5) {
while(j <= 5){
scanf("%d\n", &x[i][j]); /* 配列読み込み */
j += 1;
}
i += 1;
}
return 0;
}
void reve(int x[]) /* 交換関数 */
{
int n, i, j, y;
printf("何行目と何行目を入れ替えますか?\n");
scanf("%d", &n);
scanf("%d", &j);
for(n=0; n <=5 ; n++) {
y = x[j][n];
x[j][n] = x[i][n];
x[i][n] = y;
}
return;
}
void write(int x[]) /* 出力関数 */
{
int i, j;
j=0;
for(i = 0; i <= 5; i++) {
while(j <=5){
printf("x[%d][%d]=%d\n", i, j, x[i][j]);
j += 1;
}
}
return;
}
503ポイント を手に入れた。
|
|
|
|
Name: 管理人 [URL] ..ハッカー(106,927ポイント)
Date: 2006/12/05(火) 03:52
No:2323
|
|
Title: Re:課題です
|
|
このサンプルは、改良前のものです。
もっと下の投稿に改良版を投稿したので、そちらを参考にしてください。
#include<stdio.h>
void read(int x[5][5]){
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
printf("%d-%d(残り%d個) -> ",i+1,j+1,25-(i*5+j));
scanf("%d",&x[i][j]);
}
}
return;
}
void write(int x[5][5]){
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
printf("x[%d][%d]=%d\n",i,j,x[i][j]);
return;
}
void reve(int x[5][5]){
int i,y,n,m;
printf("何行目と何行目を入れ替えますか?\n");
printf("1行目 -> ");
scanf("%d",&n);
printf("2行目 -> ");
scanf("%d",&m);
n=n-1; m=m-1;
for(i=0;i<5;i++)
y=x[n][i] , x[n][i]=x[m][i] , x[m][i]=y;
return;
}
int main(){
int x[5][5];
read(x);
write(x);
reve(x);
write(x);
return 0;
}
悪いとこなおしておきました。
説明は後書きますね。
これでやりたいことあってるか、実際にコンパイルして確かめてみてください。
264ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..プログラマー(30,413ポイント)
Date: 2006/12/05(火) 03:57
No:2324
|
|
Title: Re:課題です
|
|
int x[5][5]がいっぱい出てきてますが、(ちょっと難しいかもしれませんが)こうすると楽ですよ。
typedef int array_type[5][5];
int read(array_type x);
.....
int main()
{
array_type x;
read(x);
.....
}
128ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..プログラマー(31,264ポイント)
Date: 2006/12/05(火) 04:07
No:2325
|
|
Title: Re:課題です
|
|
@@@tenさんへ
順番に行きます。
1 read() / reve() / write()各関数の引数の型
それぞれの関数の宣言では引数が int x[]のように一次元配列だったり int *のようにポインタで宣言されており、宣言と実装で型が違う上、更に実際に main関数から呼ばれている時は intの二次元配列の型を指定しています。つまり、プロトタイプ宣言、実装、使用時の3つ全てで全部型が異なっています。
型はプロトタイプ宣言と実装は統一を、使用時とは互換性のある型を指定しなければなりません。
ここでは型は全て intの[5, 5]の二次元配列なので、判りやすくするために typedefした型に置き換えて行きましょう。
typedef int array_type[5][5];
int read(array_type x);
.....
int main()
{
array_type x;
read(x);
.....
}
ここまででコンパイルは通るかと思います。
3 read()のアルゴリズム
5x5の二次元配列なので 25回処理を繰り返す必要があるのですが、このアルゴリズムではそうはなりません。
問題点は2つ。
1つはループ条件です。
配列の要素は5x5しかないので、アクセスできるのは x[4][4]までです。
が、各ループ終了条件が i <= 5と5以下なループするになっている為、x[5][5]までアクセスしてしまっています。
2つ目は jの初期化です。
最初に jのループが終わった後、i+=1されて、もう一度 jのループに入りますが、このとき jの値は前回のループを抜けたときの値・・・ここでは 6になっています。
なので、i+=1の処理の後に j=0と jの値を初期化してあげてください。
3 write()のアルゴリズム
こちらも read()同様、ループ条件に5が含まれています。
0〜4になるように修正してください。
さらに iの値が変更されていません。
jのループが終わった後 iを加算しないと iを使った終了条件のループが終わらないので、無限ループになってしまいます。
4 reve()のアルゴリズム
行を入れ替えるとありますが、あまり意味がわからないので仕様面で合っているかどうかはよくわかりませんが、こちらも read()同様、ループ条件に5が含まれています。
2つの値を入力するところで、n と jの変数に入れていますが、これは iと jの間違いでしょう。
851ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(107,421ポイント)
Date: 2006/12/05(火) 04:08
No:2326
|
|
Title: Re:課題です
|
|
間違いを注釈として書きました。
#include <stdio.h>
void reve(int *);//最上位のみ省略出来る。 つまり(int (*)[5])このように書く必要がある
int read(int *);//int型関数にする必要が無いので、void関数でいい
void write(int *);
int main () {
int x[5][5];
read(x);
write(x);
reve(x);
write(x);
return 0;
}
int read(int x[]) //上で説明したように、最下位の[5]は省略不可。(int (*)[5])と書く
{
int i, j;
i=0;
j=0;
while(i <= 5) {//while文にせず、for文にするほうが楽 i<5でなければならない。
while(j <= 5){//[5]で宣言したのに、5含め、0,1,2,3,4,5で回すと計6回、まわる。
scanf("%d\n", &x[i][j]);//\nは要らない。今何個目入力かわからない。
j += 1;
}
i += 1;
}//jが0で初期化していないせいで2周目以降条件にはいらない、0~4の繰り返しにならない。
return 0;
}
void reve(int x[]) //同様の間違い
{
int n, i, j, y;
printf("何行目と何行目を入れ替えますか?\n");
scanf("%d", &n);
scanf("%d", &j);
for(n=0; n <=5 ; n++) { //せっかくnで入力を受けたのに、n=0で0で初期化してしまっている。
y = x[j][n];
x[j][n] = x[i][n];// iの値は何も入っていない。
x[i][n] = y;
}
return;
}
void write(int x[]) //同様の間違い
{
int i, j;
j=0;
for(i = 0; i <= 5; i++) { //for文とwhile文の混在 i<5まででなければ6回まわってしまう
while(j <=5){
printf("x[%d][%d]=%d\n", i, j, x[i][j]);
j += 1;
}//jを初期化していないので、2周目以降jは6となり条件に入らない。
}
return;
}
私が書いたプログラムで、main文を最初に書きたければ、プロトタイプ宣言は
void read (int (*)[5]);
void write(int (*)[5]);
void reve (int (*)[5]);
このようになります。
私の書いたプログラムでどこかわからない部分があれば聞いてください。
>Justyさん、
3、のwhite関数の中のiはforでまわっているので、無限ループの危険性は無いのではないでしょうか。
494ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(107,609ポイント)
Date: 2006/12/05(火) 04:26
No:2330
|
|
Title: Re:課題です
|
|
(int (*)[5])と書く、といいましたが、
int *
と似たような書き方をするなら・・という意味なので、
最初のうちは
(int x[5][5])
と書いておいたほうがわかりやすくていいかもしれません。
5という数は最初からわかっているなら#defineで定義するのが一般的です。
#define A1 5
#define A2 5
(int x[A1][A2])
こんな感じがいいかもしれません。
128ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(107,983ポイント)
Date: 2006/12/05(火) 04:44
No:2332
|
|
Title: Re:課題です
|
|
先ほど私が書いたプログラム、
「1行目」
「2行目」
という表示はおかしいですね。
行列らしく表示の方法を変えて、再度書き直しました。
こちらが改良版です
アルゴリズムは全く同じです。
実際にコンパイルして、実行してみて、自分がやりたいこととあっているか確認してください。
#include<stdio.h>
void read(int x[5][5]){
for(int i=0;i<5;i++){//このfor文を2つ組合わせることで5*5=25回ループできる。
for(int j=0;j<5;j++){
printf("%d-%d(残り%d個) -> ",i+1,j+1,25-(i*5+j));//入力を促す
scanf("%d",&x[i][j]);//入力を格納
}
}
return;
}
void write(int x[5][5]){
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
printf("%4d ",x[i][j]);//%4dというのは4桁表示するという意味。
}
printf("\n");//各行が表示できたら改行する
}
return;
}
void reve(int x[5][5]){
int i,y,n,m;
printf("何行目と何行目を入れ替えますか?\n");
printf("入れ替える行1 -> ");
scanf("%d",&n);
printf("入れ替える行2 -> ");
scanf("%d",&m);
n=n-1; m=m-1;//1行目といわれたら[0][]を交換する為、1を引く
for(i=0;i<5;i++)
y=x[n][i] , x[n][i]=x[m][i] , x[m][i]=y;//交換作業
return;
}
int main(){
int x[5][5];
read(x);
write(x);
reve(x);
write(x);
return 0;
}
実行結果
・・・(略)
5-3(残り3個) -> 23
5-4(残り2個) -> 24
5-5(残り1個) -> 25
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
何行目と何行目を入れ替えますか?
入れ替える行1 -> 2
入れ替える行2 -> 3
1 2 3 4 5
11 12 13 14 15
6 7 8 9 10
16 17 18 19 20
21 22 23 24 25
これで入れ替わったかどうか確認しやすくなったと思います。
1行目というのは配列でいうx[0][]ここの0の事ですから、お間違いないよう。
%4dというのは「少なくとも4桁で表示せよ」という意味です。
1桁でも4マススペース使いますし、3桁でも4スペース使います。
ですから、4桁までの数値がはいっていれば、キレイにならんで表示されます。
もし5桁の数字が入力されることがあるなら5にしましょう。
84ポイント を手に入れた。
|
|
|
|
|
Name: ten ..ぴよぴよ(618ポイント)
Date: 2006/12/05(火) 08:34
No:2334
|
|
Title: Re:課題です
|
|
Justyさん、管理人さんホントにありがとうございます。
凄く分かり安かったです!
アルゴリズムの細かいところまで解説していただき
スッキリしました!
50ポイント を手に入れた。
|
|
|
|
|
Name: バグ ..中級者(14,721ポイント)
Date: 2006/12/05(火) 11:38
No:2338
|
|
Title: Re:課題です
|
|
行を入れ替えるだけならば、指定列の先頭アドレスを渡してコピーを作って、丸々入れ替えてしまうようなやりかたもできそうですね(^-^)
58ポイント を手に入れた。
|
|
|
|
Name: 新人 ..ぴよぴよ(5ポイント)
Date: 2006/12/04(月) 20:03
No:2297
|
|
Title: 入力されたキーを調べる方法
|
|
始めまして。C言語を始めて約1ヶ月の初心者です。
問1 ファイルを作成するプログラムを作成してください。
1:ファイル名作成を促すメッセージを画面に出力し、キーボードからの入力を行う。
2:1文字以上入力された場合、「1:」で入力した名前でファイルを作成する。
3:ファイル名の作成が完了した胸を画面に出力する。
というものなんですが、仕様書に
「文字入力後、リターンキーを押した場合」
1:現在のディレクトリに入力した文字と同じ名前のファイルがあることを確認。
2:ファイル作成完了のメッセージが画面に出力されることを確認。
「文字入力せずに、リターンキーを押した場合」
1:ファイルが作成されないことを確認
と書かれていてエビデンスを行う際に、ファイルが作成されないことの確認
が出来なくて困っています。(エンターを押しても、証拠が出ないので困ってます)
かなり分かりにくい文ですが、よろしくお願いします。
5ポイント を手に入れた。
|
|
|
|
Name: バグ ..中級者(14,663ポイント)
Date: 2006/12/04(月) 20:10
No:2299
|
|
Title: Re:課題が出来なくて困っています
|
|
strlen関数で文字列の長さを調べて、0だったらファイルを作成しなかったというメッセージを出力してはどうでしょうか?
38ポイント を手に入れた。
|
|
|
|
|
Name: 新人 ..ぴよぴよ(230ポイント)
Date: 2006/12/04(月) 20:35
No:2303
|
|
Title: Re:課題が出来なくて困っています
|
|
さっそくのレスありがとうございます。
#include<stdio.h>
int main()
{
FILE *fp;
char fname[64];
printf("ファイルを作成して下さい。\n");
scanf("%s",fname);
fp=fopen(fname,"w");
if(fp==NULL){
printf("ファイルが作成出来ません。\n");
fclose(fp);
}
return 0;
}
一応こんな感じなんですが、どこがいけないのでしょうか?
まだ知識不足で皆様からのアドバイスをいただいても中々
実践出来なくて申し訳ないです。
225ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(104,863ポイント)
Date: 2006/12/04(月) 20:45
No:2304
|
|
Title: Re:課題が出来なくて困っています
|
|
これは入力を受けた変数に何が入っているかどこにも判定している箇所がありません。
fp==NULL
はなにを判定しているか。
これは入力を受けたキーの調査をしているわけではありません。
先ほどのリンクを参考にしてください。
scanfで取り込んだデータの調査方法は先ほど書いたので参考にしてみてください。
114ポイント を手に入れた。
|
|
|
|
|
Name: 新人 ..ぴよぴよ(322ポイント)
Date: 2006/12/04(月) 22:18
No:2312
|
|
Title: Re:課題が出来なくて困っています
|
|
すみません。無知の極みで管理人さんのおっしゃってる意味が
わかりません。
とりあえず明日までに完成させないといけないので、もう少し
具体的に教えていただけないでしょうか?お忙しい中、本当に
すみません。
92ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(105,026ポイント)
Date: 2006/12/04(月) 22:39
No:2313
|
|
Title: Re:課題が出来なくて困っています
|
|
#include<stdio.h>
void main()
{
int i=0;
char fname[64];
while(fname[i]=getchar() != '\n')
i++;
if(i==0)
printf("何も入力されずにエンター押されました。");
}
これがエンターが押された時、何か入力があったかどうか判定するプログラムです。
これは入力を受けるプログラムと、判定するプログラムが合体しています。
getcharで入力を受けた1文字ずつをfnameに格納していき、それが\nなら
エンターによる改行だとわかります。
最初からループにはいらないということは、
最初に\nが来たということなのでなにも入力がなかったということですね。
130ポイント を手に入れた。
|
|
|
|
|
Name: 新人 ..ぴよぴよ(385ポイント)
Date: 2006/12/04(月) 23:41
No:2318
|
|
Title: Re:課題が出来なくて困っています
|
|
ありがとうございます。上記ソースの意味は理解できたのですが、
このソースを私が記入したソースのどこに当てはめればいいのでしょうか?
質問ばかりで申し訳ありません。課題が出来たら、管理人さの解説を元に
確実に理解したいと思っています。
63ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(105,932ポイント)
Date: 2006/12/05(火) 00:12
No:2319
|
|
Title: Re:課題が出来なくて困っています
|
|
この意味がわかったのでしたら、課題は必ずできます。
答えばかりを追い求めるのではなく、アリゴリズムを確認してください。
#include<stdio.h>
void main()
{
int i=0;//カウントするための変数
char fname[64]; //ファイル名入力を受けるための変数
while(1){//無限ループ
fname[i]=getchar();//キー入力から1文字を受け取る
if(fname[i] == '\n')//受け取った文字が改行コードなら
break;//ループを抜ける。
else//受け取った文字が改行コード以外なら
i++;//次の文字を格納するためにカウントアップ
}
if(i==0)//最初に改行文字が入力されていたら何も入力されなかったということ
printf("何も入力されずにエンター押されました。");
}
これと
#include<stdio.h>
int main()
{
FILE *fp;
char fname[64];
printf("ファイルを作成して下さい。\n");
scanf("%s",fname); //ファイル名を格納する配列に文字列を格納
fp=fopen(fname,"w"); //ファイルを書き込みモードで開く。ファイルの情報があるアドレスをfpに格納
if(fp==NULL){ //格納したアドレスが無効なら
printf("ファイルが作成出来ません。\n");
return 1;
}
fclose(fp); //fpを閉じる
return 0;
}
これですね。
役割が重複している箇所がありますね。
何の行が何の役割をしているか、考えて、うまくあてはめてみてください。
412ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(106,561ポイント)
Date: 2006/12/05(火) 00:20
No:2320
|
|
Title: Re:課題が出来なくて困っています
|
|
getchar関数の仕組みがよくわからなければ、こちらをコンパイルしてみてください。
#include<stdio.h>
void main()
{
int i=0,j;
char fname[64];
while(1){
fname[i]=getchar();
printf("%c\n",fname[i]);
if(fname[i] == '\n')
break;
else
i++;
}
}
getchar関数は、キーボード入力から1文字を受け取る関数です。
sampleと入力してエンターを押すとします。
最初getchar関数を呼ぶと「s」が返ってきます。
次にgetchar関数を呼ぶと「a」が返ってきます。
次にgetchar関数を呼ぶと「m」が返ってきます。
次にgetchar関数を呼ぶと「p」が返ってきます。
次にgetchar関数を呼ぶと「l」が返ってきます。
次にgetchar関数を呼ぶと「e」が返ってきます。
次にgetchar関数を呼ぶと「\n」が返ってきます。(これは見えません)
\nは改行を表すコードです。
getchar関数を何度もよぶことで、1つずつ格納が出来るんです。
配列に順番に格納したければ、iをカウントしていって、指定すればいいですね。
i=0の状態で、getcharの返り値をfname[i]に格納する。
すると
fname[0]に[s]が格納されます。
i=1の状態で、getcharの返り値をfname[i]に格納する。
すると
fname[1]に[a]が格納されます。
i=2の状態で、getcharの返り値をfname[i]に格納する。
すると
fname[2]に[m]が格納されます。
i=3の状態で、getcharの返り値をfname[i]に格納する。
すると
fname[3]に[p]が格納されます。
i=4の状態で、getcharの返り値をfname[i]に格納する。
すると
fname[4]に[l]が格納されます。
\nが帰ってくればループを抜けたらいいんです。
最初に\nが帰ってくるなら何も入力されていないことがわかります。
629ポイント を手に入れた。
|
|
|
|
|
Name: 新人 ..ぴよぴよ(359ポイント)
Date: 2006/12/05(火) 08:25
No:2333
| 解決!
|
Title: Re:課題が出来なくて困っています
|
|
とても丁寧な解説ありがとうございました。
また分からないことがあったら質問するかもしれません。
その際はよろしくお願いします。
26ポイント を落としてしまった。
|
|
|
|
Name: 新米 ..ぴよぴよ(290ポイント)
Date: 2006/12/04(月) 18:41
No:2295
|
|
Title: 教えてください
|
|
Cでプログラムを書いてコンパイルすると、
「undefined reference to `log10'」
というエラーメッセージが出てきます。
よろしくお願いします。
47ポイント を手に入れた。
|
|
|
|
Name: Justy ..プログラマー(30,285ポイント)
Date: 2006/12/04(月) 19:29
No:2296
|
|
Title: Re:教えてください
|
|
環境はなんですか?
GCCですか?
GCCでそのエラーはリンカのエラーではないかと。
もしそうなら libm.aをリンクすれば解決しますが・・・。
実際のところコンパイル手段がわからないので、これ以上は判りません。
99ポイント を手に入れた。
|
|
|
|
Name: ウィーヤ ..ぴよぴよ(834ポイント)
Date: 2006/12/03(日) 18:59
No:2278
|
|
Title: \tって何?
|
|
プログラムの構成方法については、理解することができました。
しかし、ちょっとした小技なのでしょうか、その仕組みがちょっとわかりません。
23行目の
printf(" t\t x\t y\t v_x\t v_y\n");
の「\t」。
「\n」は改行ということを学んだのですが、「\t」は知らないです。
今後出力されたとき綺麗に表示するようにできるためにも、
教えていただけるとありがたいです。
38ポイント を手に入れた。
|
|
|
|
Name: ウィーヤ ..ぴよぴよ(863ポイント)
Date: 2006/12/03(日) 20:55
No:2283
| 解決!
|
Title: Re:\tって何?
|
|
わかりました。
わざわざリンクまで付けていただき、有り難うございます。
29ポイント を手に入れた。
|
|
|
|
Name: ウィーヤ ..ぴよぴよ(205ポイント)
Date: 2006/12/03(日) 14:41
No:2246
|
|
Title: C言語の課題がわかりません
|
|
プログラムを初めて学んで約2ヶ月しかたっていない学生の者です。
明日提出しなければならないC++の課題が、まったくわからなくて困っています。
課題内容は…
高さh[m]の地点から速度u0(これはuに数字の0を下付けたやつです)[m/s]で質点を水平に投げたとき、質点が地上に到達するまでの時間T[s]、および水平到達距離L[m]を算出するプログラムを作成せよ。ただし、0.1s毎の質点の位置x,yおよび速度成分u,vを画面に出力させること。またTおよいLは質点の位置が地面より下になった時点の値とし、厳密に求める必要はない。下記の関数は必ず作成すること。
・初期条件h、u0を入力する関数
・位置x,yを計算する関数
・速度成分u,vを計算する関数
以上、課題内容です。
今のところ、このプログラムはまったく進んでないです。
下2つの必要記入の関数は何となく理解できるのですが、1つ目の「初期条件h、u0を入力する関数」というものがよくわかりません。
数値演算関数内にprintfを書けということなのでしょうか。
最近、何とかポインタを理解できたという程度の知識しかもっていません。
どうぞよろしくお願いします。
205ポイント を手に入れた。
|
|
|
|
Name: 管理人 [URL] ..ハッカー(101,568ポイント)
Date: 2006/12/03(日) 15:02
No:2247
|
|
Title: Re:C言語の課題がわかりません
|
|
ウィーヤさん、こんにちは。
3つの項目に上から番号を振りましょう。
1番はプログラムの問題ですが、2,3は単純に物理の問題ですね。
プログラムの書き方は、わかりますか?
物理的な式の解き方はわかりますか?
最初に出てくる物理の運動に関する3大公式を用いれば解けます。
最初にプログラムは関係なく、紙とペンでとけるかどうかが重要です。
紙とペンでとけなければ、プログラムがわかっても解けません。
一度問題を解いてみてください。
123ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(101,724ポイント)
Date: 2006/12/03(日) 15:07
No:2248
|
|
Title: Re:C言語の課題がわかりません
|
|
まず、1番はこのようにすればOKです。
必要な変数はここに宣言しました。
#include <stdio.h>
void main(){
double l,u_0,T,L,x,y,u,v;
printf("初速度 u_0(m/s) -> ") , scanf("%lf",&u_0);
printf("高さ h (m) -> ") , scanf("%lf",&h );
}
以後キーボードから代入された値が(u_0,h)使えます。
156ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(101,840ポイント)
Date: 2006/12/03(日) 15:26
No:2249
|
|
Title: Re:C言語の課題がわかりません
|
|
後は、物理の公式に代入するだけです。
水平方向に投げたということは、速度のx成分は初速度に等しく、一定です。
初速度がそのままv_xとなります。
xの距離は素直に、速さ*時間になります。
y方向には最初力が加わっていないので、自由落下と同じになります。
速さのy成分v_yはgtとなります。
yの式から地上にぶつかる時のtが求まります。
この式を使えば解けます。
厳密に計算する必要はないということなので、
0.1秒ごとに増えていく値がこの値より大きくなった時点の値とすればよいわけです。
tを0.1ずつ増加させて計算しましょう。
2倍のポイントを手に入れた! 116ポイント を手に入れた。
|
|
|
|
|
Name: ウィーヤ ..ぴよぴよ(511ポイント)
Date: 2006/12/03(日) 15:41
No:2250
|
|
Title: Re:C言語の課題がわかりません
|
|
ご回答有り難うございます。
今後、質問がわかりやすいように、かつ回答しやすいようにするために、項目に番号を振るようにします。
さて、項目1についてはわかりました。
しかし、理由がいまいちわからないです。
「関数として」というと、
#include <math.h>
は必要なのではないのでしょうか。
また
void main()
内に入れた場合は関数と言えないのでは?
上辺だけの知識しかありませんが、その教えていただけるとあり難いです。
また項目2・3の方ですが、物理の方は何ら問題はありません。
ペンと紙ですぐに解けます(^^
ただ、プログラムとして記入するのはちょっと自信がないですが…。
306ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(102,157ポイント)
Date: 2006/12/03(日) 16:03
No:2253
|
|
Title: Re:C言語の課題がわかりません
|
|
まず、これをコンパイルしてみてください。
実行してみて、自分のやりたいことがあってるか、確認してください。
#include <stdio.h>
#define g 9.80665
void input(double *v_0,double *h){
printf("初速度 v_0(m/s) -> ") , scanf("%lf",v_0);
printf("高さ h (m) -> ") , scanf("%lf",h );
}
void calc_xy(double *v_0,double *v_x,double *x,double *t,double *y){
*x = (*v_x) * (*t);
*y = 0.5f * g * (*t) * (*t);
}
void calc_v(double *v_y,double *t){
*v_y= g * (*t);
}
void main(){
double h,v_0,v_x,v_y,x,y=0,t=0;
input(&v_0,&h);
v_x=v_0;
printf(" t\t x\t y\t v_x\t v_y\n");
while(y<h){
t+=0.1f;
calc_xy(&v_0,&v_x,&x,&t,&y);
printf("%4.1f\t%7.2f\t%7.2f\t",t,x,y);
calc_v(&v_y,&t);
printf("%7.2f\t%7.2f\n",v_x,v_y);
}
printf("T=%4.1f\tL=%7.2f\n",t,x);
}
よければ説明します。
317ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(102,567ポイント)
Date: 2006/12/03(日) 16:09
No:2254
|
|
Title: Re:C言語の課題がわかりません
|
|
まず、数値入力を実現したプログラムはこちらです。
#include <stdio.h>
void main(){
double h,v_0;
printf("初速度 v_0(m/s) -> ") , scanf("%lf",&v_0);
printf("高さ h (m) -> ") , scanf("%lf",&h );
}
scanfの使い方さえわかれば、すんなりわかりますね。
scanfは変数をアドレスで指定している点に注意してください。
この入力部分を関数化するとこうなります。
#include <stdio.h>
void input(double *v_0,double *h){
printf("初速度 v_0(m/s) -> ") , scanf("%lf",v_0);
printf("高さ h (m) -> ") , scanf("%lf",h );
}
void main(){
double h,v_0;
input(&v_0,&h);
}
ポインタはわかるとおっしゃっていたので、説明する必要はないとは思いますが、mainからのinput呼び出しの際、アドレスを渡してやってinputでポインタとして受け取っています。
ポインタで渡された関数内では*をつけることで、main内と同じ変数として扱えますね。
ここでポイントなのは、scanf文の変数の前に&がなくなっていること。
ポインタで渡された変数は*をつければ、値をしめし、それをとればアドレスを示すことになります。
ここまでいいですか?
410ポイント を手に入れた。
|
|
|
|
|
Name: ウィーヤ ..ぴよぴよ(533ポイント)
Date: 2006/12/03(日) 16:18
No:2255
|
|
Title: Re:C言語の課題がわかりません
|
|
長々と説明していただき有り難うございます。
大丈夫です。何とかついていけてます。
22ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(103,172ポイント)
Date: 2006/12/03(日) 16:26
No:2258
|
|
Title: Re:C言語の課題がわかりません
|
|
では、具体的な部分へ。
input関数を作って、入力を受け付ける関数を作りました。
では、次は速さを計算する関数を作ってみましょう。
tが最初0の状態から0.1ずつ増やしていき、2秒になるまでループさせます。
while(t<2.0){
t+=0.1f;
ここの部分ですね。
速さのx成分はずっと変わらないので計算する必要はありません。
今回は用意しましたが、v_xという変数もわざわざ用意することも無いでしょう。
例によってポインタで計算するために、アドレスを渡してやります。
&v_y,&t
ここの部分ですね。
calcは計算する、vは速さという意味です。
速さを計算するcalc_vという関数に変数のアドレスを渡してやり、
v_y = g*t;
を計算します。紙とペンではすぐとけるということなので、物理的な解説ははぶきます。
これでy成分の速さが求まりました。
tは0.1ずつ増えていっているので、時間変化によって、v_yも計算されていきます。
ループを抜けた時、t=2の時の速さが求まっているはずです。
printfの出力を見てください。
#include <stdio.h>
#define g 9.80665
void input(double *v_0,double *h){
printf("初速度 v_0(m/s) -> ") , scanf("%lf",v_0);
printf("高さ h (m) -> ") , scanf("%lf",h );
}
void calc_v(double *v_y,double *t){
*v_y= g * (*t);
}
void main(){
double h,v_0,v_x,v_y,x,y=0,t=0;
input(&v_0,&h);
v_x=v_0;
while(t<2.0){
t+=0.1f;
calc_v(&v_y,&t);
}
printf("v_x=%f v_y=%f\n",v_x,v_y);
}
次、最後の解説をします。
333ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(103,279ポイント)
Date: 2006/12/03(日) 16:28
No:2259
|
|
Title: Re:C言語の課題がわかりません
|
|
あ、今読み返してみると
>3つの項目に上から番号を振りましょう。
この文章は
「3つの項目に上から番号を振ります。」と最初かいていたのに、後から消した文章とつなげて変に「ふりなさいよ!」みたいな発言になってしまってますね^^;
自分が解説しやすいように、番号ふっただけなんで。
気にしてたらごめんなさい^^;
107ポイント を手に入れた。
|
|
|
|
|
Name: ウィーヤ ..ぴよぴよ(548ポイント)
Date: 2006/12/03(日) 16:37
No:2262
|
|
Title: Re:C言語の課題がわかりません
|
|
ん?
while(t<2.0){
t+=0.1f;
この変数tの増やし方は初めて知りました。
数字の増減方法は
i++ やi--
しか知りませんでした。
この場合は(i++,i<20.0)として
t=0.1*i
と書けばよろしいのでしょうか。
15ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(102,742ポイント)
Date: 2006/12/03(日) 16:42
No:2263
|
|
Title: Re:C言語の課題がわかりません
|
|
次にx,yを計算する
calc_xy
という関数を作りましょう。
xとyの計算に必要な変数はなんでしょうか?
まず、当然x,yの計算結果を格納するためのx,yという変数が必要です。
その変数を受け取ります。
次に、
xは
x=v_x*t
で計算できますから、v_xとtが必要です。
これも、main関数から引っ張ってきましょう。
後重力加速度gですが、これは不変なので定義します。
#defineの使い方がわからなければ、また聞いてください。
ここでは「g」と書けば、9.80665という意味になると覚えておいてください。
それでは受け取るべき変数をうけとって、計算したものが
void calc_xy(double *v_x,double *x,double *t,double *y){
*x = (*v_x) * (*t);
*y = 0.5f * g * (*t) * (*t);
}
これです。
なんら難しくないですね?
掛け算の「*」なのか、変数のポインタを表す*なのか混合しそうなので、括弧をつけて明確にしました。
後はmain関数からよんでやればいいだけのことです。
ループの条件はy<hとし、設定したhよりyの方が大きくなれば終了です。
ループを抜けた時の値を表示してやれば、問いの解答となります。
ちなみに
printf("%4.1f %7.2f %7.2f %7.2f %7.2f \n",t,x,y,v_x,v_y);
という表示の仕方は、数値をキレイにそろえて表示させる方法で、
%7.2fとかいたら、
「少なくとも7桁表示し、そのうち小数点以下は2桁表示で浮動小数点型」
という意味になります。
どの数値も7桁表示されるので、値がキレイにそろって表示できます。
これらを全て組み合わせるとこうなります。
#include <stdio.h>
#define g 9.80665
void input(double *v_0,double *h){
printf("初速度 v_0(m/s) -> ") , scanf("%lf",v_0);
printf("高さ h (m) -> ") , scanf("%lf",h );
}
void calc_xy(double *v_x,double *x,double *t,double *y){
*x = (*v_x) * (*t);
*y = 0.5f * g * (*t) * (*t);
}
void calc_v(double *v_y,double *t){
*v_y= g * (*t);
}
void main(){
double h,v_0,v_x,v_y,x,y=0,t=0;
input(&v_0,&h);
v_x=v_0;
printf(" t\t x\t y\t v_x\t v_y\n");
while(y<h){
t+=0.1f;
calc_xy(&v_x,&x,&t,&y);
calc_v(&v_y,&t);
printf("%4.1f %7.2f %7.2f %7.2f %7.2f \n",t,x,y,v_x,v_y);
}
printf("T=%4.1f\tL=%7.2f\n",t,x);
}
若干むだがあったので、改良しました。
これでやりたいことあっていますか?
591ポイント を落としてしまった。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(102,874ポイント)
Date: 2006/12/03(日) 16:45
No:2264
|
|
Title: Re:C言語の課題がわかりません
|
|
>この変数tの増やし方は初めて知りました。
i++
は
i = i+1;
と同じです。
一方
i=i+2;
は
i += 2;
と同じです。
i=i-3;
は
i -= 3;
と同じです。
i=i*0.2;
は
i *= 0.2;
と同じです。
これらはiを2回書かなくて済むので「若干」便利ですw
132ポイント を手に入れた。
|
|
|
|
|
Name: ウィーヤ ..ぴよぴよ(625ポイント)
Date: 2006/12/03(日) 16:54
No:2265
|
|
Title: Re:C言語の課題がわかりません
|
|
なるほど。
よくわかりました。しかし
t+=0.1f
の「f」、位置yの関数でも使用されてますが何なのでしょうか。
あと、実行してみたところ、自分のやりたいこととばっちり合っていました。
77ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(103,256ポイント)
Date: 2006/12/03(日) 17:01
No:2267
|
|
Title: Re:C言語の課題がわかりません
|
|
最後尾にfを付けるとfloat型になり、
最後尾にdを付けるとdouble型、
lを付けるとlong double型に出来ます。
doubleからfloatにする意味は全くないので、省いてください。
こちらに省いたプログラム載せます。
#include <stdio.h>
#define g 9.80665
void input(double *v_0,double *h){
printf("初速度 v_0(m/s) -> ") , scanf("%lf",v_0);
printf("高さ h (m) -> ") , scanf("%lf",h );
}
void calc_xy(double *v_x,double *x,double *t,double *y){
*x = (*v_x) * (*t);
*y = 0.5 * g * (*t) * (*t);
}
void calc_v(double *v_y,double *t){
*v_y= g * (*t);
}
void main(){
double h,v_0,v_x,v_y,x,y=0,t=0;
input(&v_0,&h);
v_x=v_0;
printf(" t\t x\t y\t v_x\t v_y\n");
while(y<h){
t+=0.1;
calc_xy(&v_x,&x,&t,&y);
calc_v(&v_y,&t);
printf("%4.1f %7.2f %7.2f %7.2f %7.2f \n",t,x,y,v_x,v_y);
}
printf("T=%4.1f\tL=%7.2f\n",t,x);
}
353ポイント を手に入れた。
|
|
|
|
|
Name: ウィーヤ ..ぴよぴよ(796ポイント)
Date: 2006/12/03(日) 17:07
No:2268
| 解決!
|
Title: Re:C言語の課題がわかりません
|
|
そうだったんですか…。
わかりました。
ちょっと頭がオーバーヒートしそうなので、
一息入れてから管理人さんの解説をみて、
なぜこうなるのかを考えながらやってみますね。
今のところ、管理人さんの解説を完璧に理解できている自信はないので、また質問することになると思います。
(たしか新しくトピックを作るんでしたね)
解決したわけではありませんが、とりあえずこのトピックは「解決」状態にしておきます。
長く書いていただき、有り難うございました。
171ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(103,173ポイント)
Date: 2006/12/03(日) 17:11
No:2270
|
|
Title: Re:C言語の課題がわかりません
|
|
プログラムは一見ゴミゴミして見えますが、
全く難しい処理はしていませんから、落ち着いてみてください。
最初から完成したプログラムをみるのではなく、私の解説にそってみていけば判ると思います。
少しでもわからない部分があれば、そのままにせずに必ず聞いて「完璧」にわかった状態にしてくださいね☆
107ポイント を落としてしまった。
|
|
|
|
Name: オス豚 ..ぴよぴよ(438ポイント)
Date: 2006/11/30(木) 23:59
No:2192
|
|
Title: モンテカルロ法の積分教えてください。
|
|
2重積分なんですけど、
∬f(x)dxdy
ただしf(x)=√(9-x^2-9/4*y^2)
R={(x,y); 4x^2+9y^2≦36}
という問題です。Rというのは∬の右下に小さく書いてあるものです。
f(x)はなんとか自分でも作れるんですが、2重積分の計算ができません。
97ポイント を手に入れた。
|
|
|
|
Name: 管理人 [URL] ..比類無きプログラマー(93,860ポイント)
Date: 2006/12/01(金) 00:21
No:2193
|
|
Title: Re:モンテカルロ法の積分教えてください。
|
|
2重積分は、2重ループで計算できますよ。
普通の積分はとけますか?
小さくきって、四角形を作っていき、その合計を出す方法。
2重積分は、1方向をとめて、1方向ずつ、加算していきます。
ちょっと出かける用事がありますので、帰宅後、お答えします。
すみません。
118ポイント を手に入れた。
|
|
|
|
|
Name: オス豚 ..ぴよぴよ(488ポイント)
Date: 2006/12/01(金) 00:36
No:2194
|
|
Title: Re:モンテカルロ法の積分教えてください。
|
|
ある枠内に一様に乱数の点を発生させて、その図形の内部に入る割合によって面積を求める方法なんです。
普通の積分は何とかできます。
忙しい中すいません。
50ポイント を手に入れた。
|
|
|
|
|
Name: オス豚 ..ぴよぴよ(530ポイント)
Date: 2006/12/01(金) 11:59
No:2202
|
|
Title: Re:モンテカルロ法の積分教えてください。
|
|
何とかできるかがんばって見ます。ありがとうございました。
2倍のポイントを手に入れた! 42ポイント を手に入れた。
|
|
|
|
|
Name: kuz ..ぴよぴよ(611ポイント)
Date: 2006/12/02(土) 17:19
No:2230
|
|
Title: Re:モンテカルロ法の積分教えてください。
|
|
初めまして、kuzといいます。
最近Cから離れてしまっていて、あっている自信は
ありません(というか間違えてる可能性が高いです)
しかもスマートじゃありません・・・・
ただ、お答えがない様ですので投稿いたします。
参考程度に見ていただければ幸いです
まず、Rの両辺を36で割ると
X^2/3^2 + Y^2/2^2 <=1 となるので
これは楕円の方程式をあらわします。
ここから-3<=X<=3,-2<=Y<=2
であることがわかります。
この範囲内の乱数の組み合わせで
Rを満たすものの組をf(x)に代入した結果の
総計を組数で割った値が近似値となります。
乱数を出力する所が見苦しいですが、以下ソースです
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#define TRY_CNT (10000) //最大試行回数
void main(void){
double randX,randY,ans=0.0f;
int i;
for(i=0;i<TRY_CNT;i++){
srand(time(NULL)); //乱数初期化
for(;;){ //条件に合致するまで
randX = (double)(rand() % 3001);
randY = (double)(rand() % 2001);
if(rand() % 2){
randX = randX / 10000;
}else{
randX = randX / 100000;
}
if(rand() % 2){
randY = randY / 10000;
}else{
randY = randY / 100000;
}
if(rand() % 2){
randX = randX * (-1);
}
if(rand() % 2){
randY = randY * (-1);
}
if(4*randX*randX + 9*randY*randY <= 36){
break;
}
}
ans += sqrt(9-randX*randX - 9/4*randY*randY); //試行回数分集計
}
ans /= TRY_CNT; //試行回数で割る
printf("ans=%f",ans);
}
611ポイント を手に入れた。
|
|
|
|
|
Name: box ..中級者(9,188ポイント)
Date: 2006/12/02(土) 23:23
No:2233
|
|
Title: Re:モンテカルロ法の積分教えてください。
|
|
> randX = (double)(rand() % 3001);
> randY = (double)(rand() % 2001);
randXは0〜3000、randYは0〜2000の範囲の値をとります。
次の、10000または100000で割っている理由がよくわかりません。
いずれにせよ、randXは高々0.3、randYは高々0.2です。
その次に符号を変えるロジックがありますが、
後で2乗しているので不要だと思います。
> if(4*randX*randX + 9*randY*randY <= 36){
> break;
randXの2乗は高々0.09、randYの2乗は高々0.04です。
したがって、ここは必ずbreakします。
forループを回る回数は、常に1回です。
> ans += sqrt(9-randX*randX - 9/4*randY*randY); //試行回数分集計
ansの値は、3にひじょうに近くなります。
求める二重積分の値が楕円の面積だとすると、
π*長径*短径=6π になるはずです。
93ポイント を手に入れた。
|
|
|
|
|
Name: kuz ..ぴよぴよ(922ポイント)
Date: 2006/12/03(日) 15:42
No:2251
|
|
Title: Re:モンテカルロ法の積分教えてください。
|
|
すいません説明不足でした。
R(範囲)が楕円の方程式になっているというこです。
ここでRというのはx,yが満たすべき条件です。
そこで、本来なら適当に乱数を発生させ、
それがRを満たすかどうかを判断し、
満たした場合f(x)に代入し、その総計
(TRY_CNT分)を取得します。そして集計を
TRY_CNTで除算した値が結果となります。
ただ、Rが楕円であることから発生させるべき
乱数の範囲がそれぞれ-3<x<3,-2<y<2ということなのです。
そこでその範囲内の乱数を発生させるために、
randXの場合では2000までの値を1000または10000で
除算することで0.001〜2.000での乱数を発生させています。
Cで少数の乱数を発生させる方法が他に考えつかなかったので、
こんな、見苦しいことをしています、申し訳ありません
負についは確かに不要ですね。範囲内の乱数という意味で
負もあるほうが良いかと思ったのですが、蛇足でした。
まだ、わかりにくい点多々ありそうですが、
あくまで参考程度ということで、ご容赦ください
311ポイント を手に入れた。
|
|
|
|
|
Name: オス豚 ..ぴよぴよ(565ポイント)
Date: 2006/12/03(日) 16:26
No:2257
|
|
Title: Re:モンテカルロ法の積分教えてください。
|
|
ありがとうございます。
レベルの高い話しであまりついていけませんけども笑、参考にさせてもらってできました。
35ポイント を手に入れた。
|
|
|
|
Name: airblaster ..ぴよぴよ(86ポイント)
Date: 2006/12/03(日) 02:15
No:2237
|
|
Title: 全くわかりません
|
|
初めまして、airblasterと申します。
大学の課題なのですが
「文字列にstr[ ]に整数表記(負の場合もある)が入っているとする
。それを整数に変換して返す関数 int atoi(char str[ ])を表記せよ。」なんですがまったくわかりません。
だれか教えていただけないでしょうか、よろしくお願いしますm(__)m
86ポイント を手に入れた。
|
|
|
|
Name: 管理人 [URL] ..ハッカー(100,564ポイント)
Date: 2006/12/03(日) 03:51
No:2238
|
|
Title: Re:全くわかりません
|
|
airblasterさん、
初めてのお話でこのような事を聞くのは、少々抵抗があるとは思いますが聞いてください。
このことはどこに言ってもいえる事ですが
質問する時に「全く判りません」とだけ書くのは良くないです。
「
この辺りまで勉強しています。
授業でこの辺までやりました。
自分ではこの辺まで理解しています。
自分ではこの辺まで調べました。
」
など、という表記が大事です。
これではとりあえず宿題を誰かに解かせたいだけに聞こえてしまいます。
こういう投稿はどこのサイトで質問しても、親身になってくれる回答には出会えないことが多いです。
質問の仕方一つで、どういう回答に出会えるか、密接に関係しています。
一生懸命さが伝わる質問なら回答する側も一生懸命になってくれます。
これは私が実際に体験したことでもあり、あらゆるサイトで見かけることなので、今後airblasterさんが損をしないように、言いました。
気を悪くされたらごめんなさいね。
では、質問の回答ですが、
atoi関数というのは、文字型で取り込んだデータを整数型で返す関数です。
atoiを表記せよということですが、それは、atoiのアルゴリズムを示せということでしょうか?
実際の関数の処理の中身を書けばいいんでしょうか?
まず、それには文字コードの理解が必要です。
全ての文字は文字コードで管理されています。
データは0と1で管理されますから、「文字」というデータがあってはこまります。
ですから数字で管理されているのです。
つまり、「a」という文字は文字コード79で管理されています。
つまり79というデータを「文字型で表示」すると「a」が表示されます。(環境によって変化しますが)
これを実際に実行してみてください。
#include <strio.h>
void main(){
printf("%c",79);
}
79という文字コードデータを文字型表示である%cで表示するとaになります。
実際に実行して確かめてください。
これを80にするとbに、81にするとcになります。
文字コードはこのように順番に並んでるんですね。
では「0」という文字データは数字の何で管理されているでしょうか?
#include <stdio.h>
void main(){
char str[]="0";
printf("%cの文字コードは%d",str[0],str[0]);
}
こちらを実行してみてください。文字コードは48であることがわかります。
#include <stdio.h>
void main(){
printf("%cの文字コードは%d",'0','0');
}
こちらでも同じ意味になります。
数字をシングルコーテーションでかこむと、文字コードをあらわせます。
1の文字コードは49、2の文字コードは50で管理されています。
このように0〜9まで順番の文字コードになっています。
つまり、文字型データの文字コードが「48〜57」だったら文字「0〜9」だということが判ります。
それをふまえてこちらを見てください。
#include <stdio.h>
int a2i(char str[]){
return str[0]-'0';
}
void main(){
int n;
char str[]="1";
n=a2i(str);
printf("%d",n);
}
str[0]から'0'をひくというのはどういう意味なんでしょか?
str[0]は文字「1」であり、文字コード49でしたね。'0'は文字コード48でしたね。
つまり数字の文字コードから'0'を引けば、int型の数字に変換することが出来ます。
例えば、str[0]が文字「3」であるとき、文字コード51です。'0'は文字コード48ですからひけば「3」ですね。
つまり、'0'を引くことで、文字型データを整数型データに変換することが出来るんです。
それが先ほどのプログラムです。
では、2桁の文字データを整数に変換するには?
#include <stdio.h>
int a2i(char str[]){
int n;
n=str[0]-'0';
n=10*n + (str[1]-'0');
return n;
}
void main(){
int n;
char str[]="12";
n=a2i(str);
printf("%d",n);
}
str[0]に1が、
str[1]に2が入っていますね。
まず、10の位である1を整数型に変換してnに代入します。
この時点では一桁ですから、これを10の位にするために10倍します。さらに1の位であるstr[1]を整数型にしてたしてやることで、2桁の数字が表示できます。
#include <stdio.h>
int a2i(char str[]){
int i,n=0;
for (i = 0; (str[i] >= '0') && (str[i] <= '9') ; i++)
n = 10 * n + (str[i]-'0');
return n;
}
void main(){
char str[]="14256";
printf("%d", a2i(str));
}
これが全ての桁数で対応できるようにしたプログラムです。
for文の条件が複雑に見えますが、簡単ですから落ち着いてみてください。
for (i = 0; (str[i] >= '0') && (str[i] <= '9') ; i++)
これは、「iが0から始まって文字データが0から9までの間繰り返す。」というものです。
つまり文字データが数字ではなかったり、数字のデータが終わったりすると終了するループ文です。
このループが終わるまで、先ほど言った容量で、位上げをしながら計算をしています。
このa2i関数がatoi関数の中身です。
toというのはtwoと発音が似ていることからa2iと書いて表現することが多いです。
atoi関数のアルゴリズム、お分かりになったでしょうか?
わからなかったらまた聞いてください。
1,997ポイント を手に入れた。
|
|
|
|
|
Name: airblaster ..ぴよぴよ(388ポイント)
Date: 2006/12/03(日) 15:59
No:2252
| 解決!
|
Title: Re:全くわかりません
|
|
管理人様、丁寧な回答ありがとうございますm(__)m
管理人様が指摘したことに返す言葉もありません。
確かに自分の質問の仕方では、そのように捉えられるし、回答してくださる人の立場に立った場合、回答したいとは思わないと思います。
自分的にも、あまりにも軽い気持ちで書き込んでしまったと思い、反省しています。
そんな質問にも関わらず、丁寧に回答してくれた管理人様には感謝しています。
また質問させてもらうと思いますが、そのときは今回のようにはならないようにしたいと思います。
回答ですが、非常に良くわかりました!本当にありがとうございます。最初、整数表記を整数に変換するという意味がよくわかりませんでした。これは言い換えれば整数で書かれた文字コードを整数型になおして表示するということだったのですね。
馬鹿で面倒かけましたm(__)m本当にありがとうございます!
302ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(102,839ポイント)
Date: 2006/12/03(日) 16:20
No:2256
|
|
Title: Re:全くわかりません
|
|
airblasterさん、お解かりいただけたようでよかったです。
プログラムの説明っていうのは聞いただけじゃよくわかりません。
私が先ほどaやbの文字コードの説明をしましたが、それをうけて、自分でdやCの文字コードを表示させてみることでもっとよくわかります。
自分で類題を作ってみて、ちょっと違ったプログラムを自分の判る範囲で、作ってみるのも大事です。
例えば「5〜8のみint型に変換するにはどうしたらいいか?」など、疑問がわけば、自分でそれが実現できるプログラムを作ってみましょう。
疑問があれば、残したままでは駄目です。
宿題だけやっていたのでは最低限の知識どころか、復習しなければしばらくすれば0に近い状態に戻ってしまうでしょう。
出てきた疑問はとどめておかず、調べたり質問したりして解決してくださいね☆
272ポイント を手に入れた。
|
|
|
|
Name: 管理人 [URL] ..ハッカー(100,968ポイント)
Date: 2006/12/03(日) 06:50
No:2239
|
|
Title: 複数の名前を使って投稿している方へ
|
|
同じ方で、複数の名前を使って質問されてらっしゃる方がいらっしゃいますが、
一度使った名前は、自分はその名前として、ずっと同じ名前を使ってください。
回答する立場として、前回説明した事と重複して説明してしまったり、
どこから説明したらいいかわからなくなったりしてしまうので。
回答される方へ、特に名前のお願いはしません。
質問する立場として、一度に大量に質問すると、問題を投げているように受け止められてしまうのでは、という不安があるのかと思いますが、
この掲示板では、ちゃんとやる気を持っている方に対して非難するような方はいらっしゃいませんので、安心して、投稿してください。
また、私が今回問題をしている方の名前を言ったりする事はないので、安心してください。
また、質問する際は
「どこまでやって、どこがわからなかったのか。」
を明確にしてください。
「本当に最初からわからないんだ」という方もいらっしゃると思いますので、その方はせめて、自分ではどこまで調べたかを書くようにしてください。
「このサイトしらべたんだけど」「この本読んだんだけど」それだけでもかまいませんので。
そして、問題文を投稿する時は自分で読んで本当にそれが意味の通るものか一度確認してください。
質問者・回答者の皆様が情報を円滑に交換でき、有意義に掲示板が使用できるよう、管理人からお願いいたしますm(_ _)m
堅苦しい文章になってしまいましたが、雑談板ポンポン立ててくださって結構ですので、気軽にトピをたててくださいね(*^ー゜)ノ
404ポイント を手に入れた。
|
|
|
|
Name: バグ ..中級者(14,592ポイント)
Date: 2006/12/03(日) 06:58
No:2240
|
|
Title: Re:複数の名前を使って投稿している方へ
|
|
さすがは管理人さん!
最近、課題の丸投げが多くて、しかも質問している人がどこまで理解できているのかが分からない文章だったりで、どう答えたらいいのか正直、困っていたんですよね(;^_^A
3ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(101,344ポイント)
Date: 2006/12/03(日) 07:15
No:2241
|
|
Title: Re:複数の名前を使って投稿している方へ
|
|
バグさんチェック早いですね〜^^w
おはようなのか、おやすみなのか?!
私の部屋では隣の方からものすごい音量で目覚ましが3分間位なっているにもかかわらず、いっこうに止まる気配がありません・・( ̄  ̄;)
これ毎日なんですけど、朝20回位鳴るんですよ・・・。マジでなんとかして欲しいです;
しかし「こっちの方向から・・」というのはわかれど、実際何号室から音がしているのかわからず、
文句を言いにいくことが出来ません;
隣の部屋の人はよく我慢してるな・・。
>最近、課題の丸投げが多くて、しかも質問している人がどこまで理解できているのかが・・
私もそう思ってたんです。
質問の仕方についてはいつかJustyさんとお話しましたが、質問にもスキルがいりますよね。
質問の仕方一つでどれくらい親身な回答がかえってくることかかなり変わりますから。
用件だけで終わる何の味も無い掲示板になってほしくないですし、回答してくださる方に嫌な思いもしていただきたくないですし、質問者も親身な回答が得られるような投稿の仕方をしてほしい・・。
そう思ってお願いしましたm(_ _)m
・・・って、
ダー!うるさい〜!今日は特にひどいぞ〜!30回位目覚ましなりっぱなし(T_T)
376ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..ハッカー(101,445ポイント)
Date: 2006/12/03(日) 07:19
No:2242
|
|
Title: Re:複数の名前を使って投稿している方へ
|
|
あ!いつの間にか一生なる事はないだろうと思ってた最高ランクになってる^^;
10万ポイントって・・よくココまで来たな〜;
・・・称号が立派過ぎて、この上のランク作りたくても、称号の名前が思いつかない^^;
(自分のポイント・称号チェックは掲示板メニューの「昇進状態」から確認できます^^)
この上の称号募集しますw
101ポイント を手に入れた。
|
|
|
|
|
Name: バグ ..中級者(14,625ポイント)
Date: 2006/12/03(日) 08:18
No:2243
|
|
Title: Re:複数の名前を使って投稿している方へ
|
|
実は両隣ともに空き部屋だったりしたら、ホラーで楽しいんですが(笑)
33ポイント を手に入れた。
|
|
|
|
Name: もも ..ぴよぴよ(155ポイント)
Date: 2006/12/03(日) 00:03
No:2234
|
|
Title: int型とdouble型の演算について
|
|
整数型変数a,bの初期値がそれぞれa=2,b=3のとき、以下の式を計算して実数型
変数dを求める(実数となる場合は小数点以下4桁まで記述する)問題なのですが、
d= a += b /= 2;
の答えが3.000
となるようです、 まずb=b/2を計算して a=a+b/2 となって d=a で答えを3.500
となってしまうのですが、どういう順番ですればいいのでしょうか。
教えてください。
155ポイント を手に入れた。
|
|
|
|
Name: box ..中級者(9,234ポイント)
Date: 2006/12/03(日) 00:17
No:2235
|
|
Title: Re:無題
|
|
bはint型です。b/2は1.5ではなく、小数点以下を切り捨てた1です。
その1をaに加えます。aは3です。
その3をdに代入します。
46ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..比類無きプログラマー(98,567ポイント)
Date: 2006/12/03(日) 01:45
No:2236
|
|
Title: Re:無題
|
|
ももさん、こんにちは。
まず、int型を計算してdoubleに当てはめる時には(double)を書いたほうが正しいと思います。
int型は計算結果に小数があると、はぶかれます。
3÷2は1.5ですが、1になります。
1÷2は0.5ですが、0になります。
実際の計算過程はboxさんのおっしゃるとおりです。
140ポイント を手に入れた。
|
|
|
|
Name: たくみ ..ぴよぴよ(35ポイント)
Date: 2006/12/02(土) 02:48
No:2217
|
|
Title: 乱数と2次方程式について
|
|
1〜20までの乱数を3つ発生させ二次方程式ax^2+bx+cを解け。この処理を10回繰り返させる。 という課題を学校の先生からいただいたぼですが、発生させた3つの数をうまくあてはめられず困っています どなたか教えてください お願いします
35ポイント を手に入れた。
|
|
|
|
Name: 管理人 [URL] ..比類無きプログラマー(94,929ポイント)
Date: 2006/12/02(土) 03:53
No:2218
|
|
Title: Re:乱数について
|
|
たくみさん、こんにちは。管理人です。
えぇと、問題の意味がよくわかりません。
乱数を発生させて3点を決定し、そこを通る2次方程式を解くというものなんでしょうか?
3点はそれぞれ格子点でいいんでしょうか?
乱数を3つ発生させ、という問題文が本当なら、
y=x上の点ということになりますが、(例えば(2,2),(6,6)等)そこを通る点でいいんでしょうか?
2次関数は直線と3つの交点を持てないので、
よく調べて、問題文をもう一度かいてみてください。
122ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..プログラマー(29,342ポイント)
Date: 2006/12/02(土) 04:49
No:2221
|
|
Title: Re:乱数について
|
|
>>えぇと、問題の意味がよくわかりません
私も今ひとつよくわからなかったのですが、最大限に推測すると多分
「乱数1〜20を a, b, cに代入し、ax^2+bx+c = 0の x値を解く。これを10回繰り返して結果を表示」
ということなのではないでしょうか。
問題なのはたくみさんがどこまで習っていて、今何で詰まっているのか、ですよね。
25ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 [URL] ..比類無きプログラマー(96,434ポイント)
Date: 2006/12/02(土) 05:02
No:2224
|
|
Title: Re:乱数について
|
|
あ、そういうことですか。
それなら通りますね。
さすが、私とは違う・・。
でもそれならとても簡単ですね、式さえかけば解ける^^;
エックスイコールニエーブンノマイナスビープラスマイ・・って解の公式を。
特定の範囲内の乱数発生方法は、他のトピでも紹介しているので、参考にしてみてください。
それをみてもわからなかったらまた聞いてください。
148ポイント を落としてしまった。
|
|
|
|
|
Name: box ..中級者(9,095ポイント)
Date: 2006/12/02(土) 08:13
No:2227
|
|
Title: Re:乱数について
|
|
サンプルです。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define ITERATION (10) /* 繰り返す回数 */
#define MAXRANDOM (20) /* 発生させる乱数の最大値 */
void get_coefficients(int *a, int *b, int *c);
void solve_equation(int n, int a, int b, int c);
int main(void)
{
int a, b, c, n = ITERATION, i;
srand((unsigned int) time(NULL)); /* 乱数の初期化 */
for (i = 1; i <= n; i++) {
get_coefficients(&a, &b, &c); /* 二次方程式の係数を得る */
solve_equation(i, a, b, c); /* 二次方程式を解く */
}
return 0;
}
void get_coefficients(int *a, int *b, int *c)
{
/* 1〜MAXRANDOMの範囲の乱数を発生させる */
*a = rand() % MAXRANDOM + 1;
*b = rand() % MAXRANDOM + 1;
*c = rand() % MAXRANDOM + 1;
}
void solve_equation(int n, int a, int b, int c)
{
double d = b * b - 4 * a * c; /* 判別式 */
double x1, x2, re, im, e = 2 * a;
printf("%2d) %2dx^2+%2dx+%2d=0\n", n, a, b, c);
if (d > 0) { /* 実数解2個 */
x1 = (-b + sqrt(d)) / e;
x2 = (-b - sqrt(d)) / e;
printf("x1=%f\n", x1);
printf("x2=%f\n\n", x2);
}
else if (d == 0) { /* 実数解1個 */
x1 = -b / e;
printf("x(重解)=%f\n\n", x1);
}
else { /* 虚数解 */
re = -b / e;
im = sqrt(-d) / e;
printf("x=%f±%fi\n\n", re, im);
}
}
414ポイント を手に入れた。
|
|
|
|
|
Name: たくみ ..ぴよぴよ(122ポイント)
Date: 2006/12/02(土) 14:09
No:2229
|
|
Title: Re:乱数について
|
|
アドバイスしてくださったみなさんへ
みなさんアドバイスありがとうございます。 今学校では乱数を習い始めたばかりで、今朝先生にメールして問題の意図を教えていただいたところ 3つ乱数を発生させ二次方程式ax^2+bx+cの式にあてはめ、10回繰り返す という意味ということがわかりました
87ポイント を手に入れた。
|
|
|
|
|