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/
0545デフォルトの名無しさん
2006/11/21(火) 22:12:56その前後のコードも晒してよ。
それだけじゃ特定できん。
0546デフォルトの名無しさん
2006/11/21(火) 22:16:02#include <string>
int main(void)
{
char s[] = "abcde/fghij";
char *p = strstr(s, "/");
*p = '\0';
printf("%s\n", s);
return 0;
}
0547デフォルトの名無しさん
2006/11/21(火) 22:23:24お前は何を言っているんだ。
0548535
2006/11/21(火) 22:25:08問題は別のところにありました。
strstrで検索したときに、検索文字列のひとつに
"/"がなくNULLを返していたのが原因でした。
ifとかを付けずに *s_point = '\0'; としてしまい、
そこでエラーを起こしていました。
お騒がせして申し訳ありませんでした。
0549デフォルトの名無しさん
2006/11/21(火) 22:28:05あんたは何を言ってるの?
0550デフォルトの名無しさん
2006/11/21(火) 22:28:09char b[] = {"abc"};
printf("%s\n%s\n", a, b);
0551ぴゅあ
2006/11/21(火) 22:32:29>>535
>エラーが出て
というのがエラーメッセージが出ているのなら
それを示した方が良かったかもですね
0552デフォルトの名無しさん
2006/11/21(火) 22:41:07質問者は
"ABCDE/FGHIJ"
これの/以降を削除したいと言っている
コンパイルの段階で分割してどうするね・・・
0553デフォルトの名無しさん
2006/11/21(火) 22:48:41ttp://www.konaken.com/blog/milco.jpg
0554ぴゅあ
2006/11/21(火) 22:51:42あぁ 構文ではなくて"abc"とされていたことを言っていたわけですか
(てか、それなら"ABCDE"とかだろうけど)
>"ABCDE/FGHIJ"
にならうなら
char a[] = {'A','B','C','C','D','E','/','F','G','H','I','J','\0'};
char b[] = "ABCDE/FGHIJ";
後者に括弧は要らんでしょう
char c[][] = {"ABC","DEF"};
とかなら。。。
0555ぴゅあ
2006/11/21(火) 22:53:27或いはchar *[]か
0556デフォルトの名無しさん
2006/11/21(火) 22:57:30いる。
0557デフォルトの名無しさん
2006/11/21(火) 22:59:260558デフォルトの名無しさん
2006/11/21(火) 23:01:20× char string[] = {"ABCDE/FGHIJ"};
○ char string[] = "ABCDE/FGHIJ";
何度もすみません。
543 :デフォルトの名無しさん :2006/11/21(火) 22:00:54
>>542
上のが正しいだろ。常識的に考えて。
544 :デフォルトの名無しさん :2006/11/21(火) 22:12:15
>>543
char a[] = {'a','b','c','\0'};
char b[] = "abc";
printf("%s\n%s\n", a, b);
0560ぴゅあ
2006/11/21(火) 23:05:55"ABC"はchar配列として扱うから
付けない方が一般的だと思いますよ
>キメー
の意味は判らないけど…
0561デフォルトの名無しさん
2006/11/21(火) 23:08:52客観的に考えて。
0563ぴゅあ
2006/11/21(火) 23:13:17>>542
上のが正しいだろ。常識的に考えて。
上のが正しいだろ。常識的に考えて。
上のが正しいだろ。常識的に考えて。
上のが正しいだろ。常識的に考えて。
ttp://www.konaken.com/blog/milco.jpg
0564ぴゅあ
2006/11/21(火) 23:13:40コンパイラが要素数1の配列として誤解しないか
ちょっと気になりました
(コード読む側も間違えないのかな?)
ついでがあったら確認してみよ。。。
0565デフォルトの名無しさん
2006/11/21(火) 23:44:51今授業で char を使い始めました。
さっそくこれを使って2〜16進数を4進数や8進数に直せというPを作れといわれたのですが、
char に自由な数値を入れるにはどうしたらいいのでしょうか?
int なら
int a;
scanf("%d",&a);
でいけますよね?
先生曰く char と int は1ビットと4ビットでサイズが違うのでscanfは使えないと言っていた気がするし、
実際scanfを使ったPを作ってもコンパイルできません。
どうか回答よろしくお願いします。
0566デフォルトの名無しさん
2006/11/21(火) 23:49:070567デフォルトの名無しさん
2006/11/21(火) 23:51:13char c, d, e;
c = 1;
d = 100;
e = 25;
0568デフォルトの名無しさん
2006/11/21(火) 23:51:490569デフォルトの名無しさん
2006/11/22(水) 00:56:35言いたいことはいろいろあるが、とりあえず。
Pとは何だ?
その先生とやらが教えてくれたのか、君が勝手に言い出したかは知らないが、
そんな言葉は一般的に通じない。
人に質問するときは相手に分かるように話せ。
0570デフォルトの名無しさん
2006/11/22(水) 00:57:38Num2 = 0,i = 1に初期化しています.
for (Num10 = 1; Num10 <= 10; Num10++)
{
while (Num10)
{
if (Num10 % 2 == 1)
Num2 += i;
i *= 10;
Num10 /= 2;
}
printf("%05d", Num2);
}
これで実行すると,意味不明な(-954437117)という数字が無限ループしてしまいます.
指摘してくださる方いましたらよろしくお願いします.
0571デフォルトの名無しさん
2006/11/22(水) 01:03:46ループ内でNum10を書き換えたらきちんとループできないだろ。
プログラムの是非は問わないことにする。
0572デフォルトの名無しさん
2006/11/22(水) 01:14:57for(NUM10=1; NUM10<=10; NUM10++) {
NUM2 = 0;
i = 1;
j = NUM10;
while(j) {
if(j%2) NUM2 += i;
i *= 10;
j /= 2;
}
printf("%d,%d\n",NUM10, NUM2);
}
こういうことがやりたいの?
0573デフォルトの名無しさん
2006/11/22(水) 01:15:34while開始前に,Num10の内容を別の変数aに代入し
プログラムを実行させたところ無限ループはなくなりました.
2進数変換は正しく出来ていなかったので考えてみることにします.
ありがとうございました.
0574デフォルトの名無しさん
2006/11/22(水) 01:19:32iとNum2をfor文の外で初期化していたため,10進数の2以上がおかしい値となっていました。
ありがとうございます.
0575ぴゅあ
2006/11/22(水) 01:34:05折角、できたということなので
後で改めて考えてみるとかでいいと思いますけど
2進や8進とかにするというのは文字/文字列にすることを
考えてみるのもいいかも
(8進,16進はわざわざロジックを組まなくてもできたりですけど)
若干コードは面倒臭くなるかもですけどね
8/10/16進も敢えてやってみておいてもいいかも
0576574
2006/11/22(水) 02:00:46文字/文字列とはどういうことでしょうか?
8,16進はprintf内で出来るので敬遠していました.
今は勉強を始めたばかりですので,敬遠せず色々とやってみたいと思います.
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
■ このスレッドは過去ログ倉庫に格納されています