C言語なら俺に聞け(入門篇) Part 4
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2006/11/09(木) 00:31:01・C++言語はスレ違いです。
・分からない事をなるべく詳しく書いて下さい。
・ソースコードを晒すと答えやすくなるかもしれません。
・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。
前スレ
C言語なら俺に聞け(入門篇) Part 3
http://pc8.2ch.net/test/read.cgi/tech/1160682950/
過去スレ
Part 1 http://pc8.2ch.net/test/read.cgi/tech/1146700389/
Part 2 http://pc8.2ch.net/test/read.cgi/tech/1153818463/
関連スレ
くだすれC言語(初心者用)
http://pc8.2ch.net/test/read.cgi/tech/1153542424/
【ISO/ANSI/JIS】 C言語なら俺に聞け! Part 130
http://pc8.2ch.net/test/read.cgi/tech/1159613789/
0577ぴゅあ
2006/11/22(水) 07:48:26>文字/文字列とはどういうことでしょうか?
sprintf(メモリ,printf/fprintf(標準出力/ストリーム)で
結果を出そうとするとき、いずれも結局は文字列ですよね
2進(>>572)を例に採ると"j%2"或いは"j&(2-1)"は数値で0か1
これに文字'0'か文字コード0x30を加えれば文字'0'か'1'
これをprintfで書式"%c"を使えば文字列"0"か"1"として表示される
>>572をなるべく変えないでやろうとするなら
まずその文字列分のメモリ域を確保・初期化しておいて
先に求めた'0','1'を1の位(のメモリ位置)から埋めていく
全て揃ったらprintfなりで文字列(書式"%s")として出力
それが形になれば8/10/16進も同様(2/8/10/16進の違いの部分だけ)
符号の有りは別途後でやってみるのがいいと思うけど
printfの中もこういうことやってたりします
(>>572の例だと一度10進数(int)として扱えるように置き換えているから
桁数に限界がでてきたりするでしょ?)
0578デフォルトの名無しさん
2006/11/22(水) 07:52:170579ぴゅあ
2006/11/22(水) 07:54:19その辺りも勉強するまで置いといて
後でゆっくりやってみるのがいいと思います
0580ぴゅあ
2006/11/22(水) 07:56:21文字列の中から1文字取り出したcharの値が文字コード
後は文字コード表と見比べれば
0581ぴゅあ
2006/11/22(水) 08:41:24(>>577繋がりかと思ってしまいました。。。)
0582デフォルトの名無しさん
2006/11/22(水) 09:15:22えっとファイルから読み込むんですが
そのファイルがEUCであったりSJISであったりUTF-8(だったかな)
であったりするわけです。
そのファイルを処理して別のファイルにまとめたりするのですが
SJISかEUCのどちらかに統一したいんです。
他の言語だともう関数があったりしてそれ利用してたもんで
Cではどうやるのかなぁと
自作するしかないんでしょうか?
0583デフォルトの名無しさん
2006/11/22(水) 09:17:170584ぴゅあ
2006/11/22(水) 09:45:15やはりそうでしたか
タイミング良過ぎ…って感じで勘違いしてしまいました
使うまでに至ったことはないですけど
gccでだったりするとlibiconvとかも使える筈と思います
(glibcのiconvだとオリジナルでは未対応になるのかな?)
0585デフォルトの名無しさん
2006/11/22(水) 10:56:37流れ大きく戻してごめんなさい
>char *string = "ABCDE/FGHIJ";
>これじゃ駄目だから間違えるなよ。
>たとえ上手く動いてるように見えても絶対駄目だからな。
なんでだめなんですか?
char string[]
ぢゃなくて
char *string
をいっつもつかってます
読みにくいからとかですか?
0586デフォルトの名無しさん
2006/11/22(水) 11:05:36(組み込み系なら、ROMに確保される可能性大)
そのどっかが、データ書き換え可能な領域にあるという保証は出来ない。
配列で確保していれば、書き換え可能な領域に確保されている。
0587デフォルトの名無しさん
2006/11/22(水) 11:14:580588デフォルトの名無しさん
2006/11/22(水) 11:17:23文字列を確保するのは"ABCDE/FGHIJ"でそれをあつかうためのポインタをいれるのが=で
ポインタを入れる先がchar[]か、char*のちがいだけではない?ということ?
0589デフォルトの名無しさん
2006/11/22(水) 11:21:08そういうこと。
確保される領域が、可変領域保証かそうでないかの違いがある。
0590ぴゅあ
2006/11/22(水) 11:36:09敢えて補足するまでもないと思いますけど
char *string = "ABCDE/FGHIJ";
のように書いている場合には"ABCDE/FGHIJ"の中を書き換えるような操作をしてはならない
ポインタ変数stringに代入されているものが他でchar[11+1]とかで取っている領域のポインタであるとか
mallocで確保された領域とかであれば
その領域内を書き換えることは可
char string[] = "ABCDE/FGHIJ";
は領域を確保してその中に"ABCDE/FGHIJ"を入れているので書き換え可
("ABCDE/FGHIJ"自身を書き換えているのではなくstring[11+1]の領域の中を触るから)
ということです
0591デフォルトの名無しさん
2006/11/22(水) 11:50:33B b;
} A;
typedef struct {
A a;
} B;
のように相互に型を使う構造体はどうやって定義すればいいんでしょうか。
Aを先に書けばBが定義されていないと言われ、逆にすればAが未定義と
怒られるのですが・・・。
0592デフォルトの名無しさん
2006/11/22(水) 11:51:12char *string = "ABCDE/FGHIJ";
の方が良いけどね。(コピー作る手間がかからないから)
でもその場合はベタ書きするとか
マクロ使うことの方が多いけど。
0593デフォルトの名無しさん
2006/11/22(水) 11:55:25それ流行ってるの?
0594586
2006/11/22(水) 12:02:54そうなのかぁ。ありがとう。
書き換え操作はだめなんですね。勉強になりました。
0595デフォルトの名無しさん
2006/11/22(水) 12:09:590596586
2006/11/22(水) 12:18:420597デフォルトの名無しさん
2006/11/22(水) 12:25:010598デフォルトの名無しさん
2006/11/22(水) 12:26:17(強引なキャストをしない限り)できませんよ。
0599デフォルトの名無しさん
2006/11/22(水) 12:29:36hoge = malloc(256);
wcscpy_s(hoge, 256, TEXT("a"));
hogeが指す先には"a"が入ります。コンパイラは警告してきていますけど。
この警告をはずすのが、強引なキャストという意味でしょうか。
0600デフォルトの名無しさん
2006/11/22(水) 12:52:46警告が出るってことは無理してるってことだ。
「警告をはずす」って日本語はわからん。
0601ぴゅあ
2006/11/22(水) 13:23:14その警告自体は別の意味のものではないですか?
「wcscpy_s関数の第1引数はconstが付いてないものとして宣言されているのに渡されたものにはconstが付いている」とか
const char *hoge = "ABC";
hoge[1] = "1";
とかで判るだろうと思います
>強引なキャスト
((char *)hoge)[1] = '1';
に変えてみることで判るだろうと思います
("だろう"とはコンパイラによっては微妙かもだから)
0602デフォルトの名無しさん
2006/11/22(水) 13:35:14constだと = できないですが、別の方法では書き変えできるということですね。ありがとうございます。
0603ぴゅあ
2006/11/22(水) 13:35:23あと
>hogeが指す先には"a"が入ります。
は実行して(入った)ということだろうと思いますけど
constは飽くまでコンパイラにコンパイル時に判断させるためにコードから教えているだけのものなので
エラーなくコンパイルできれば実行はできてしまいます
>>590の
>char *string = "ABCDE/FGHIJ";
>のように書いている場合には
とかは(それは予期せぬ結果が起こる原因になり得るので)そういうことはやってはいけないということで
constはそれをコードに示してコンパイラを補助するために追加されたものです
なので
const char hoge[] = "ABC";
なんてした場合も、同様に操作が禁止されます(コンパイルのレベルで)
0604デフォルトの名無しさん
2006/11/22(水) 13:50:000605デフォルトの名無しさん
2006/11/22(水) 13:54:32この10部分、添え字のところを外部ファイルのテキストファイルなどから読み込ませることはできないのでしょうか?
#define などを利用すればできるのですかね?
0606デフォルトの名無しさん
2006/11/22(水) 13:58:470607デフォルトの名無しさん
2006/11/22(水) 14:47:460608574
2006/11/22(水) 15:59:14レス遅くなりました.
このレスを保存しておいて,そのレベルまで達したと思えたら挑戦しようと思います.
ありがとうございました.
0609デフォルトの名無しさん
2006/11/22(水) 16:46:58UTF-8もあるんだったら、UTF-16/32とかUCS4とかUnicode使ったコードを使うべきではないか?
0610デフォルトの名無しさん
2006/11/22(水) 18:01:03配列の要素数が実行時に決まる様な場合は、これは出来ないよ。
int n;
scanf("%d", &n);
int array[n];
この場合はmalloc()を使って動的に領域を確保してやる必要があるよ。
int n;
scanf("%d", &n);
int *array = (int*)malloc(sizeof(int) * n);
それとmalloc()で確保した領域は、必ずfree()で開放する必要があるから気を付けて。
上の例だとこんな感じで。
free(array);
0611デフォルトの名無しさん
2006/11/22(水) 19:00:27手元の環境で試したらできましたがやらない方がいいのでしょうか。
0612デフォルトの名無しさん
2006/11/22(水) 19:03:480613デフォルトの名無しさん
2006/11/22(水) 19:06:140614デフォルトの名無しさん
2006/11/22(水) 19:25:14そうだったのか。
古いコンパイラしか使ってなかったので知らんかったよ。
C言語も変わったなぁ。
0615デフォルトの名無しさん
2006/11/22(水) 20:38:07C99対応コンパイラなんて俺はGCCしか知らない。
0616デフォルトの名無しさん
2006/11/22(水) 20:38:180617デフォルトの名無しさん
2006/11/22(水) 20:59:140618デフォルトの名無しさん
2006/11/22(水) 21:01:170619デフォルトの名無しさん
2006/11/22(水) 21:40:010620デフォルトの名無しさん
2006/11/22(水) 21:56:560621デフォルトの名無しさん
2006/11/22(水) 22:20:570622デフォルトの名無しさん
2006/11/22(水) 22:54:530623デフォルトの名無しさん
2006/11/22(水) 23:01:30の両方がある意味がわかりません
計算が速い32ビットの整数型があるなら
uint32_tに割り当てれば済む話のような気もするんですが・・・
0624デフォルトの名無しさん
2006/11/22(水) 23:07:3332bitより64bitが速い環境なら、uint_fast32_tは64bitになるんじゃね?
0625デフォルトの名無しさん
2006/11/22(水) 23:08:01~~~~~
0626デフォルトの名無しさん
2006/11/23(木) 01:23:16string.appendみたいなかんじで文字をくっつけるのを簡単にやりたいです
strcatとかは元のバッファサイズの確保が面倒とおもっています
0627デフォルトの名無しさん
2006/11/23(木) 01:30:55#include<time.h>
#include<stdlib.h>
#define MTX 3
#define CMTX(x) (x)*(x)
//ボード
int board[MTX][MTX];
void initBoard(void);
main(){
srand(time(NULL));
printf("【%d ゲーム】\n",CMTX(MTX));
initBoard();
return 0;
}
0628デフォルトの名無しさん
2006/11/23(木) 01:31:56void initBoard(void){
int i,j;
int r;//ランダムな値
int useDigit[100];//既に数値が使われているか否かを記録する配列
for(j = 1; j <= MTX; j++){//縦方向繰り返し
for(i = 1; i <= MTX; i++){//横方向の繰り返し
//最後のマスなら終了
if((j == MTX) && (i == MTX)){break;}
do{
r = rand()%(CMTX[MTX]-1)+1;
}
while(useDigit[r-1] == 1);
board[j-1][i-1] = r;//ボードに代入する
useDigit[r-1] = 1;//使われた数値をチェックする
printf("%02",r);
}
printf("\n");
}
board[MTX-1][MTX-1] = 0;//最後のマスに0を代入する
}
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
10-1.c:
エラー E2451 10-1.c 32: 未定義のシンボル CMTX(関数 initBoard )
*** 1 errors in Compile ***
この、32行目のエラーがどうしても解決しないので
ご指摘お願いします。
0629デフォルトの名無しさん
2006/11/23(木) 01:34:31strxxx関数の類が面倒というなら、
文字列と長さを格納した構造体と、それを操作する関数群を自作して
stringクラス相当のことをC言語の仕様の中で実装するくらいしかないんじゃない?
探せば既に誰かが作っているかも。標準には存在しない。
0630デフォルトの名無しさん
2006/11/23(木) 01:36:16CMTXはマクロ関数として定義している。
CMTX[MTX]というのは使い方が間違っている。
0631デフォルトの名無しさん
2006/11/23(木) 01:38:13ご返答、ありがとうございます。
本ではこの様になっていますが・・・
では、どのように直せば宜しいのでしょうか?
ご指摘お願いします。
0632デフォルトの名無しさん
2006/11/23(木) 01:39:47CMTX(MTX)にするといいよ!
0633デフォルトの名無しさん
2006/11/23(木) 01:46:11ありがとうございました!
できましたが、一つ問題が発生しました
実行結果が
C:\bbb>10-1
【9 ゲーム】
070801
020403
0605
なってしまいます
C:\bbb>10-1
【9 ゲーム】
07 08 01
02 04 03
06 05
のように一行あけたいのですが・・・
何処をどうかえれば、こうなるでしょうか?
0634デフォルトの名無しさん
2006/11/23(木) 01:49:47たぶん、このへんだよ!
useDigit[r-1] = 1;//使われた数値をチェックする
printf("%02 ",r);←/*ここに空白を入れる*/
0635デフォルトの名無しさん
2006/11/23(木) 01:55:31できました!!!
ありがとうございました
0636デフォルトの名無しさん
2006/11/23(木) 02:24:090637デフォルトの名無しさん
2006/11/23(木) 03:21:57google 辺りで上手くやればなんとかなるか?
0638デフォルトの名無しさん
2006/11/23(木) 03:23:130639デフォルトの名無しさん
2006/11/23(木) 03:30:34手に入れたいんですが、検索しても何も引っかからないもんで
0640627-628
2006/11/23(木) 05:17:27ここの所で二つほど疑問があるのでご助言戴けたら、幸いです。
先ず一つ目は、>>627->>628 特に>>628のソースで
//最後のマスなら終了
if((j == MTX) && (i == MTX)){break;}
do{
r = rand()%(CMTX[MTX]-1)+1;
}
while(useDigit[r-1] == 1);
board[j-1][i-1] = r;//ボードに代入する
useDigit[r-1] = 1;//使われた数値をチェックする
-1や+1が出てきて、今一よくわかりません
参考書に依れば、添え字で云々と難しく解説が
書かれています。
ですので簡単に解りやすく助言して戴きたいのと
もう一つは、
>>if((j == MTX) && (i == MTX)){break;}
で、MTXとは3でしょうか、もしくは9でしょうか?
ご返答、宜しくお願いします。
0641627-628
2006/11/23(木) 05:26:00マスが1〜9あって1〜8まで数値をマスの中に
振り当てるから、ー1になるのと
添え字でー1になる事です。
0642627-628
2006/11/23(木) 05:32:42配列の添え字は0から始まるので、rand関数で出た数値が
7の時は7−1でuseDigit[6]の位置に1を代入しておきます。
参考書依り抜粋
これが特にちんぷんかんぷんです。
0643デフォルトの名無しさん
2006/11/23(木) 06:56:3010個の箱があります。
それぞれに番号をつけることにしました。
0からつけはじめて9まで付けたら番号の付いてない箱がなくなりました。
1個目の箱の番号は0です。
10個目の箱の番号は9です。
次に、箱に順番に1から10までの数字を入れることにしました。
1個目の箱には1が入りました。
10個目の箱には10が入りました。
さて問題です。
7が入ってる箱の番号はいくつでしょう?
0644デフォルトの名無しさん
2006/11/23(木) 11:04:12[1] = 2
[2] = 3
[3] = 4
[4] = 5
[5] = 6
[6] = 7
[7] = 8
[8] = 9
[9] = 10
[10]= 11
0645ぴゅあ
2006/11/23(木) 13:50:35>for(j = 1; j <= MTX; j++){//縦方向繰り返し
>for(i = 1; i <= MTX; i++){//横方向の繰り返し
でのi,jが持つ値と
>board[j-1][i-1] = r;//ボードに代入する
での配列の添え字との関係
>r = rand()%(CMTX[MTX]-1)+1;
でrand()が返すだろう最小値,rが取る値と
>useDigit[r-1] = 1;//使われた数値をチェックする
での配列の添え字との関係
・扱う値としては1〜としたいけど …i,j,r等(r = rand() ...ではそのために"+1")
・配列の添え字は0〜だから"-1"
と読めるんではないでしょうか
>>>if((j == MTX) && (i == MTX)){break;}
>で、MTXとは3でしょうか、もしくは9でしょうか?
どのようにして3と思ってみたのか、もしくは9と思ってみたんでしょうか
思った"わけ"がある筈
(3か9か(或いは全く違うか)の答え(数字)を知るだけでなく、どう解釈した/或いは間違いに至った経緯は後々のためにも把握しておいた方がいいかも)
>#define MTX 3
ではないですか?
0646ぴゅあ
2006/11/23(木) 13:52:02>配列の添え字は0から始まるので、rand関数で出た数値が
>7の時は7−1でuseDigit[6]の位置に1を代入しておきます。
・配列の添え字は0から始まる
・rand関数で出た数値が → それらから求めた変数rに入れた値(1から始まる)
・7の時は7−1で → "1から始まる値"を"0から始まる値"に
・ということで、useDigit[6]の位置
>>645が解れば、解説不要だろうと思いますけど
0647デフォルトの名無しさん
2006/11/23(木) 14:17:56javaでいうところの配列変数.length、vbでいうところのubound(配列変数)です。
mainとかで配列の個数ももらっているから無いのでは?
0648デフォルトの名無しさん
2006/11/23(木) 14:20:55配列ならsizeof
配列の要素へのポインタなら無理
0649デフォルトの名無しさん
2006/11/23(木) 14:32:59ただsizeofだとバイト単位になってしまうので、
配列の個数を求めるには型のサイズで割らないといけませんね。
0650デフォルトの名無しさん
2006/11/23(木) 14:39:220651デフォルトの名無しさん
2006/11/23(木) 14:44:00インテリはみんな、アナルとスカトロ好きだろ?
0652ぴゅあ
2006/11/23(木) 14:46:25>javaでいうところの配列変数.length
はちょっと毛色が違うところ…と思うけど
>vbでいうところのubound(配列変数)
は元々BASICが添え字の0始まり/1始まりを選択できる(何時からできるようになったのかはもう忘れたけど)
というところからlbound/uboundが生まれたりしたんだろうと思うけど
Cでは定数にしたり>>647の言ってるsizeofとか利用しつつ自分で管理
>配列の要素へのポインタなら無理
も自前で対応
>配列の個数を求めるには型のサイズで割らないといけませんね。
もマクロで対応してみたりとかされてきています
>mainとかで配列の個数ももらっているから無いのでは?
は、"配列の個数ももらっている"のではなくて
「要素数を渡さないと判らない(定数(固定値)にならない)から
(mainを呼び出す側が)渡している」んです
と理解できればいいと思います
0653デフォルトの名無しさん
2006/11/23(木) 14:47:430654647
2006/11/23(木) 14:48:49ご回答ありがとうございます。
そうか、配列でとってるからsizeof(配列変数)/sizeof(型名)で逝けるんですね
よーく考えてみたら、やりたいことはmallocとかでとった領域のサイズをしりたいことでした。
ポインタだからムリなんですね。mallocとかってサイズ調整してるみたいだし。
関数とかにmallocで領域取った部分にunsigned charの配列をいれて、
関数内で処理しようとおもったら、関数呼ぶ側からサイズも渡してやらないといけないんですね。
文字列でなくてファイルからとったバイナリ値を操作する関数をつくってます。
lengthとかuboundとかがありがたく思えてきました。
関数にポインタ渡すときはサイズも渡すようにしようと思います。ありがとうございました。
0655647
2006/11/23(木) 14:51:33○やりたいことはmallocとかでとった領域に入ってるどこかで入れた内容のサイズをしりたいことでした。
0656ぴゅあ
2006/11/23(木) 15:03:28>mallocとかってサイズ調整してるみたいだし。
これはコード上より内部的な話なので、考えなくていいと思います
(>mallocとかでとった領域のサイズをしりたいことでした。
mallocの際に必ずサイズを渡している筈なので、それを渡せていればいい…ですね)
0657デフォルトの名無しさん
2006/11/23(木) 15:29:16ファイルからの読み出しで最大値、最小値を表示するプログラムなんですが、
数字以外が含まれるとループし続けてしまいます。
エラーを返すようにしたいのですが、どうすればいいでしょうか?
0658デフォルトの名無しさん
2006/11/23(木) 15:30:13scanf を使わず getcharを使う
0659デフォルトの名無しさん
2006/11/23(木) 15:34:400660647
2006/11/23(木) 15:42:34配列のサイズのとりかた
unsigned char hoge[255];
printf("length = %d\n", sizeof(hoge) / sizeof(unsigned char);
ですね。ありがとうございます。
0661ぴゅあ
2006/11/23(木) 15:49:55スルーっぽさを漂わせてるみたいだから別にいっか
0662ぴゅあ
2006/11/23(木) 16:36:32However, it is not a pure mind.
It is a question though is sudden.
Do you think that I am a person in question?
Or, the pretender?
Do you understand?
0663デフォルトの名無しさん
2006/11/23(木) 16:41:46sizeof(hoge) / sizeof(hoge[0])
hoge が構造体でもどんな型でもつかえる。
0664デフォルトの名無しさん
2006/11/23(木) 16:44:04my.name = pure;
it = my.
however(it!=pure.mind);
assert(it & (QUESTION | SUDDEN));
you = I == person[QUESTION] ? 1: I==PRETENDER ? 2: ~UNDERSTAND;
0666623
2006/11/23(木) 17:52:46(u)int_fast32_tはピッタリ32bitの事かと勘違いしてました
0667デフォルトの名無しさん
2006/11/23(木) 18:04:50数値の取得にfscanf()を使っているならfgets()+sscanf()にして戻り値をチェックしたまえ。
sscanf()の代わりに、strtol()/strtod()で変換終了点をチェックしてもいいけど。
0668デフォルトの名無しさん
2006/11/23(木) 19:46:58fscanf()のリターン値のチェックがEOFしかやってないじゃん。
1以外だったらループを抜けるって処理も入ってないと。
0669デフォルトの名無しさん
2006/11/23(木) 20:34:20C++では定数はconstで定義することが普通のようですが、Cではどうなんでしょうか?
色々なサイトを見てみると、#defineでやってるのが多いようですが。
なぜconstで定義しないのでしょうか?
もう一つ、ヘッダファイルにconstで定数を定義しようと考えたのですが、どちらが
一般的でしょうが?
1.ヘッダファイルにstatic constで定義する。
2.ヘッダファイルに対応する.cファイルに実体を定義し、ヘッダファイルでexternする。
0670デフォルトの名無しさん
2006/11/23(木) 21:16:38Cではconstで定義したものを、定数式が要求されるところ
(配列宣言時の要素数やcaseラベルなど)で使うことができない。
そんなCを見て、C++ではconstで定数を定義できるようになった。
だからCでヘッダにconstな変数宣言をおくのは、そもそも一般的ではない。
C++では、staticなしでconst使うが(少なくとも整数型ではそれで問題ないようになっている)。
0671デフォルトの名無しさん
2006/11/23(木) 21:25:300672デフォルトの名無しさん
2006/11/23(木) 21:50:06どうなるか俺は規格書を見ないとわからない。
0673デフォルトの名無しさん
2006/11/23(木) 22:10:48文字列とか,実数でなにかあるのかと思った.
0674669
2006/11/23(木) 23:26:18Cではconst変数と定数は区別しなくちゃいけないんですね。
で、定数と同じ使い勝手を保ちつつ定数に名前を付けるとしたら
#defineしかない、ということですか。
良く分かりました。有難うございました。
0675デフォルトの名無しさん
2006/11/24(金) 00:17:32どうやってやるんでしょう。
0676デフォルトの名無しさん
2006/11/24(金) 00:19:58カレントディレクトリのファイルと要領は同じ。開くファイル名を相対パス名にすればいいだけ。
■ このスレッドは過去ログ倉庫に格納されています