C言語なら俺に聞け(入門篇) Part 23
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2007/12/22(土) 12:49:22・C++言語はスレ違いです。
・分からない事をなるべく詳しく書いて下さい。
・ソースコードを晒すと答えやすくなるかもしれません。
・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。
前スレ
C言語なら俺に聞け(入門篇) Part 22
http://pc11.2ch.net/test/read.cgi/tech/1196489491/
教えて欲しいのではなく丸投げしたいならこちらへ
C/C++の宿題を片付けます 101
http://pc11.2ch.net/test/read.cgi/tech/1197132472/
0153デフォルトの名無しさん
2007/12/25(火) 14:17:04どう表示させたいのかわからない。
%3.1e とか?
0154デフォルトの名無しさん
2007/12/25(火) 14:26:40eを用いて表示させたいんですが、精度は小数点以下5桁ぐらいで、それいじょうはeの表示に反映させないようにしたいです
0155デフォルトの名無しさん
2007/12/25(火) 14:33:16if (fabs(x) < 0.00001) {
x = 0;
}
printf("%e", x);
0156デフォルトの名無しさん
2007/12/25(火) 14:36:210のときだけじゃなく、どんな数字にたいしても精度を切り捨てたいんです
0157デフォルトの名無しさん
2007/12/25(火) 15:50:41あんたら何作ってる?
俺はアドレス帳など作ってみたんだが他にやりがいのある物はないか?
0158デフォルトの名無しさん
2007/12/25(火) 15:58:250159デフォルトの名無しさん
2007/12/25(火) 16:06:06物体が動くようにしたり
0160デフォルトの名無しさん
2007/12/25(火) 16:17:08つ[%.5g]
0161デフォルトの名無しさん
2007/12/25(火) 17:05:39四捨五入で求めたいのですが、
どういう風に書けばいいでしょうか。
今は下記のようにしています。
int n,m,d
n = m / d;
if( (m % d) > (d >> 1) ) n ++;
0162デフォルトの名無しさん
2007/12/25(火) 17:20:570163デフォルトの名無しさん
2007/12/25(火) 17:26:470164デフォルトの名無しさん
2007/12/25(火) 17:30:17うまくいきません。6.111e-20とかでてきます。
0165デフォルトの名無しさん
2007/12/25(火) 17:30:43どう表示させたいのかわかんあいんだよ
0166デフォルトの名無しさん
2007/12/25(火) 17:36:17double型の変数の
小数点以下、例えば5桁だけを利用して表示したいんです。
0.000000002121なら0を表示したいです。
数がでかくなったらeを使ってすっきり表示したいです
0167デフォルトの名無しさん
2007/12/25(火) 17:42:13char pai[3][9] = { {'1','2','3','4','5','6','7','8','9'},
{'�@','�A','�B','�C','�D','�E','�F','�G','�H'},
{'一','二','三','四','伍','六','七','八','九'},
};
int main (void){
printf("%c",pai[0][2]);
return 0;
}
これで3という文字が表示されるはずなんですがうまくいきません。
どうなおせばいいのでしょうか。
0168デフォルトの名無しさん
2007/12/25(火) 17:43:44こうか?
if(fabs(x)>=1000){
printf("%e", x);
}else{
printf("%f", x);
}
0169デフォルトの名無しさん
2007/12/25(火) 17:46:20Warningいっぱい出なかった?
3はマルチバイト文字だから、'3' とやったら半分しか入らんぞ
0170デフォルトの名無しさん
2007/12/25(火) 17:48:37二度手間だけど、丸めと表示の二段階で行なう。
void print(double foo)
{
char buf[20];
sprintf(buf, "%.5g", 1 + foo);
printf("%.5g", atof(buf) - 1);
}
0171デフォルトの名無しさん
2007/12/25(火) 17:50:40自分の好きにフォーマットをコントロールしたいなら、
もうprintfのフォーマット機能に頼らず、
自分でフォーマットするプログラムを書いた方が早くないか?
いや、そんな気がする。どうだろう?
0172デフォルトの名無しさん
2007/12/25(火) 18:18:210173デフォルトの名無しさん
2007/12/25(火) 18:27:503をいれるのにはどうやればいいんですか?
0174デフォルトの名無しさん
2007/12/25(火) 18:35:19そりゃキミがどうしたいのかによって変わってくるが・・・
char pai2[3][9*2+1] = {
{"123456789"},
{"�@�A�B�C�D�E�F�G�H"},
{"一二三四伍六七八九"},
};
printf("%c%c",pai2[0][2*2],pai2[0][2*2+1]);
これでも一応出るんで、あとは考えて。
0175デフォルトの名無しさん
2007/12/25(火) 18:36:41●文字列にする方法
char pai ⇒ const char *pai
'3'など ⇒ "3"
printf() ⇒ printf("%s", ...
●ワイド文字にする方法
char pai ⇒ wchar_t pai
'3'など ⇒ L'3'
printf() ⇒ wprintf(L"%lc", ...
かなあ? いまいち自信なし。
0176デフォルトの名無しさん
2007/12/25(火) 19:18:52char pai[3][9] = { {'1','2','3','4','5','6','7','8','9'},
{'�@','�A','�B','�C','�D','�E','�F','�G','�H'},
{'一','二','三','四','伍','六','七','八','九'},
};
↑この時点でスタック壊してるな。
何が起こっても不思議ではない。
ワイド文字にしたほうがよい。
>●ワイド文字にする方法
>char pai ⇒ wchar_t pai
>'3'など ⇒ L'3'
>printf() ⇒ wprintf(L"%lc", ...
処理系がわからんが、VCなら L'3' じゃなくて_T('3')のほうがいい。
0177デフォルトの名無しさん
2007/12/25(火) 19:38:19n = (m+0.5)/d;
0178デフォルトの名無しさん
2007/12/25(火) 19:53:57ワイドじゃないとダメだから _T にしたらあかんがな。
0179デフォルトの名無しさん
2007/12/25(火) 23:07:29【問題】
文字列Aのm番目からn個分の文字列を配列Bにコピーする
サブルーチンを作れ。
ただし、m,nの値が文字列Aの範囲を超えるような値が入力
されたら1を返し、正常にコピーできたら0を返す。
こんなプログラム組みました。
問題中のm,n,文字列A,Bの各オブジェクト名,サブルーチンの返値は
勝手に解釈して組んでます。(正常時TRUE(1),異常時FALSE(0))
0180デフォルトの名無しさん
2007/12/25(火) 23:08:45#include <string.h>
#define STR_MAX 10
#define TRUE 1
#define FALSE 0
typedef unsigned short BOOL;
BOOL BlockCopy( unsigned char*, unsigned char*, short, short );
// メイン関数
int main( void )
{
unsigned char szSrcName[STR_MAX+1];
unsigned char szDstName[STR_MAX+1];
short nStartPos = 0;
short nCopyLen = 0;
printf( "Input Str : " ); scanf( "%10s", szSrcName );
printf( "Input StartPosition : " ); scanf( "%d", &nStartPos );
printf( "Input CopyLength : " ); scanf( "%d", &nCopyLen );
if( BlockCopy( szDstName, szSrcName, nStartPos, nCopyLen ) == FALSE )
{
puts( "Error!!" );
return 1;
}
printf( "入力文字列 : %s\n", szSrcName );
printf( "コピー文字列 : %s\n", szDstName );
return 0;
}
0181179,180
2007/12/25(火) 23:09:25BOOL BlockCopy( unsigned char* s1, unsigned char* s2, short m, short n )
{
int i;
short nLen = strlen( s2 );
if( nLen < m || nLen < (m+n) || nLen < n )
return FALSE;
memcpy( s1, s2+m, sizeof(char)*n );
return TRUE;
}
動作的には問題ないと思ってますがアドバイスお願いします。
また、この組み方はセンスないぞと思われる方は、よりよい
プログラムの組み方を教授して頂ければ幸甚です。
0182デフォルトの名無しさん
2007/12/25(火) 23:20:56その上でlibjpeg.soを使ったjpeg圧縮ライブラリを作りましたが、
jpeg_create_compress()を実行した時点で以下のメッセージが出て先に進みません。
JPEG parameter struct mismatch: library thinks size is 372, caller expects 376
構造体のサイズが合っていないと言ってるのはわかるのですが、
libjpeg.soとjpeglib.hのVerは合わせてありますし、
同じ名前のファイルが複数存在しない事も確認済みです。
どなたか解決方法を知らないでしょうか?
0183デフォルトの名無しさん
2007/12/25(火) 23:40:13・無闇とshortを使うのはよくない。
・sizeof(char)が1であることを前提としている関数を使うのにsizeof(char)を掛けるのはおかしい。
・「文字列をコピーする」関数なのだから、ナルターミネートは保証するべき。
ってことで、判定部を除くとこれでいい。
sprintf(s1, "%.*s", n, s2 + m);
0184デフォルトの名無しさん
2007/12/25(火) 23:55:05相手とファイルをやり取りするってプログラムを作りたいんだが。
どんな関数とか使うんだ?接続など
0185デフォルトの名無しさん
2007/12/25(火) 23:57:46環境と使うライブラリによって違う。
0186デフォルトの名無しさん
2007/12/26(水) 00:05:040187デフォルトの名無しさん
2007/12/26(水) 01:13:18その手の文字列処理関数は、コード見ないとどの引数が入力でどれが出力か分からないから、
プロトタイプ宣言だけで分かるようにconst付けたり仮引数名を工夫したりするといい
BOOL BlockCopy(unsigned char* dst, const unsigned char* src, short, short );
0188デフォルトの名無しさん
2007/12/26(水) 01:24:37.so と .h の不整合ではなくて、.so を作ったときのコンパイラ(構造体
のパディング)とそれを利用するプログラムのコンパイラ(構造体のパディ
ング)が違うんだろう。
0189デフォルトの名無しさん
2007/12/26(水) 08:30:05#pragma pack(push,4)
#include"jpeglib.h"
#pragma pack(pop)
もしくはコンパイルオプションで指定
0190182
2007/12/26(水) 10:42:05#pragma指定を追加する事で無事にプログラムが流れました。
gdbで構造体を確認しましたが壊れている様子もありませんでした。
どうもありがとうございました。
0191デフォルトの名無しさん
2007/12/26(水) 14:01:12の%.4sってどういう意味でしょうか?
0192デフォルトの名無しさん
2007/12/26(水) 14:08:20最小幅と最大幅の指定のうち、最小幅を省略したもの
0193デフォルトの名無しさん
2007/12/26(水) 14:45:17ありがとございました。
0194デフォルトの名無しさん
2007/12/26(水) 21:07:06#include <stdio.h>
int main(void)
{
printf("%d\n",10*2);
return 0;
}
この場合関数の型名ってあんまり意味ってないんですよね?
変数宣言などするときに意味があったりするんですか?
0195デフォルトの名無しさん
2007/12/26(水) 21:16:37関数ってどっちの関数?main?printf?
型名って何の型名?引数?戻り値?
0196デフォルトの名無しさん
2007/12/26(水) 21:21:20質問の意味がよくわかんね
printfは可変長引数
floatとか使いたいとき明示的に
接尾子のfを付けたりする
0197デフォルトの名無しさん
2007/12/26(水) 21:24:32それとも printf の戻り値を使ってないという事に関する疑問か。
0198デフォルトの名無しさん
2007/12/26(水) 21:43:080199デフォルトの名無しさん
2007/12/26(水) 21:48:270200デフォルトの名無しさん
2007/12/26(水) 21:51:30だって苦しむなんちゃらには
型名 関数名(引数){なんちゃら}
で関数って書いてあったんだもの><
>>199
そのとおりでございます
0201デフォルトの名無しさん
2007/12/26(水) 22:04:26やっぱりわかんね。
int temp = 10 * 2;
printf("%d\n",temp);
と
printf("%d\n",10*2);
は、最適化されて同じバイナリが吐かれるよね?、ということを聞いてる?
0202デフォルトの名無しさん
2007/12/26(水) 22:08:03そういうことじゃ?
0203デフォルトの名無しさん
2007/12/26(水) 22:09:55#include <stdio.h>
int main(void)
{
printf("%d\n",10*2);
return 0;
}
の場合intは文的には必要だが機能としてはまったく意味はない??が
#include <stdio.h>
int main(void)
{
printf("%d\n",(int)(1.05 * 360));
return 0;
}
のようにキャスト変換などするとintが使用されるっていうか
意味があるっていうか・・・・
そんな感じです
0204デフォルトの名無しさん
2007/12/26(水) 22:11:45そもそも関数の型の意味を理解していないな。
int mainのintは戻り値(OSに正常終了か否か)をreturn 0 か1かで必要だからint mainなんだよ。
0205デフォルトの名無しさん
2007/12/26(水) 22:13:56まだそこまでたどりついてません・・・
今苦しんでのキャスト変換のところなんで
もっと勉強すればわかることなんですね
0206デフォルトの名無しさん
2007/12/26(水) 22:17:41関数の戻り値が分かってない?
これは何をしているかわかる?
int unko(int x) {
int z = x*2;
return z;
}
int main()
{
int temp = unko(100);
return 0;
}
0207デフォルトの名無しさん
2007/12/26(水) 22:18:11int main(void)
{
〜〜〜
return 0;
}
は、関数の章で学ぶと思うから、
今は明示的に書かなければならないと思っておけばOK。
あまり先飛びすぎても混乱するだけだしね。
0208デフォルトの名無しさん
2007/12/26(水) 22:46:21整数リテラル 10 はそれ自体としてintという型を持っている。
整数リテラル 2 もintで、int*intの結果はint型になることになっている。
0209デフォルトの名無しさん
2007/12/26(水) 22:52:300210デフォルトの名無しさん
2007/12/26(水) 23:03:58とりあえず総じて何が聞きたいのか理解できん。
まずはここあたりを順に読んで、基本を覚えよ。
ttp://homepage1.nifty.com/toshio-k/prog/c/
0211デフォルトの名無しさん
2007/12/26(水) 23:29:52そのサイトは地雷原だから、他で勉強することを強くお勧めする。
0212デフォルトの名無しさん
2007/12/26(水) 23:31:17ここオヌヌメ
友達から教わったけど、ここだけでCの基礎はバッチリ・・・?覚えたよ
ていうかC言語でググると一番上に出てくる
0213デフォルトの名無しさん
2007/12/26(水) 23:43:51あー、間違いをそれと知らずに教わるにはいいかも。
0214デフォルトの名無しさん
2007/12/26(水) 23:44:320215デフォルトの名無しさん
2007/12/26(水) 23:46:46C++ の本でも最初のうちは C と似たようなもんだし、
その延長で C++ まで覚えてしまった方が絶対得だよ。
0216デフォルトの名無しさん
2007/12/26(水) 23:47:18C++はしょっぱなからクラス教えないっけ?
0217デフォルトの名無しさん
2007/12/26(水) 23:57:32まずCをやるんだけど、mallocとかFILE*とか、C++ではとって変わった部分を捨てて、
そのままC++のクラスなりnewなりをやれ、みたいなぁぁぁ
0218デフォルトの名無しさん
2007/12/26(水) 23:58:16間違いがあるってことだろ。間違いかどうかは微妙だけど、こういう書き方されるともにょる。
>つまり、書き換える必要のある文字列は、一旦文字型配列に格納してから処理をするのが無難だと言えます。
# 無難も何も、文字列リテラルを書き換えるのは論外なわけで……
0219デフォルトの名無しさん
2007/12/27(木) 00:08:39格納=コピーならいいけど、ポインタだけ格納してもね
0220デフォルトの名無しさん
2007/12/27(木) 03:29:34int main(void)
{
int i,d=97,c=65;
char ca;
scanf("%c",&ca);
for(i=65;i=<90;i++){
if(ca=c){
ca=d;
breke;
}
else{
i++,d++,c++;
}
}
printf("ca = %c ",ca);
return 0;
}
なんでこれがコンパイルできひんのじゃ!C言語死ねッ!!!!!
0221デフォルトの名無しさん
2007/12/27(木) 03:47:14比較じゃなく代入してる
0222デフォルトの名無しさん
2007/12/27(木) 03:49:14すまんかった・・・・・
0223デフォルトの名無しさん
2007/12/27(木) 03:49:59ついでにbreak。brekeなんてない。
0224デフォルトの名無しさん
2007/12/27(木) 03:50:300225デフォルトの名無しさん
2007/12/27(木) 03:51:48プロンプト読めない
0226デフォルトの名無しさん
2007/12/27(木) 03:53:10オヌヌメ
0227デフォルトの名無しさん
2007/12/27(木) 03:56:51お気に入り追加した
この恩は忘れるまで忘れない!
0228デフォルトの名無しさん
2007/12/27(木) 04:03:27コンパイラタン(AA略)「なんでよ私一生懸命やってるじゃん!なんでそんなこと言うの!・・・ヒドイヨ・・・・・」
0229デフォルトの名無しさん
2007/12/27(木) 04:09:300230デフォルトの名無しさん
2007/12/27(木) 04:37:370231デフォルトの名無しさん
2007/12/27(木) 04:43:190232デフォルトの名無しさん
2007/12/27(木) 07:24:49下記のソースでコンパイルは通るのですがIF文で条件外でも処理を実行してしまうようなのです。
どこが間違っているのか教えてください。お願いします。
#include <stdio.h>
#include <ctype.h>
main() {
int i;
int date[10];
for(i=0 ; i<10 ; i++) {
scan:
printf("%d個目のデータ:", i+1);
fflush(stdin);
scanf("%d", &date[i]);
if(isdigit(date[i]) == 0) {
printf("数値を入力してください。\n");
date[i] = 0;
goto scan;
}
}
printf("前から6個目のデータ:%d", date[5]);
return 0;
}
0233デフォルトの名無しさん
2007/12/27(木) 08:13:57既にここで入力を数値として変換してしてるので scanfの戻り値を調べるといいよ。
isdigitは文字が('0'〜'9')かどうか判定する関数。
それとこの状況でわざわざコードを読みにくくするgotoを使用する意味はない。
whileとbreakで代用したほうがいい。
0234232
2007/12/27(木) 08:27:31ああ、そっか。%dだから受け取った時にすでに数値になってるんだ。なるほど。
じゃあこの場合文字を入れさせないようにするにはどういう風にしたら良いのでしょうか?
>whileとbreakで代用したほうがいい。
たしかにその通りです。気をつけます。
0235デフォルトの名無しさん
2007/12/27(木) 08:27:50> main() {
> int i;
> int date[10];
>
> for(i=0 ; i<10 ; i++) {
> scan:
> printf("%d個目のデータ:", i+1);
> fflush(stdin);
入力ストリーム(stdin)のフラッシュは未定義
したこと無いけどたぶんフラッシュされない。
> scanf("%d", &date[i]);
> if(isdigit(date[i]) == 0) {
isdigitの引数は文字。'1'は文字。1は数値。ってな感じ。
> printf("数値を入力してください。\n");
> date[i] = 0;
> goto scan;
> }
> }
> printf("前から6個目のデータ:%d", date[5]);
> return 0;
> }
>
0236デフォルトの名無しさん
2007/12/27(木) 08:28:52まず、直接関係ないが、
goto scan;
↑これは止めれ。こういうときはwhile文を使うのがセオリーだ。
isdigit()は「文字が数字かどうか」を判定する関数だよ。
scanf()で変換すると「数値」(int型)になるので、
scanf("%d", &date[i]);
if(isdigit(date[i]) == 0) {
これだとisdigit()は常に0を返すはず。
それに、scanf("%d", &date[i]); の場合、数字の入力を期待しているので、
それ以外の文字は入力されてもdate[i]に入らない。
0237デフォルトの名無しさん
2007/12/27(木) 08:38:22main()
これでCマガジンに連載できるなんて…。・゚・(ノД`)・゚・。
休刊もやんぬるかな。
0238デフォルトの名無しさん
2007/12/27(木) 09:29:02省略した場合はintって決まりなかった?
だから一応正しいんじゃない?
0239デフォルトの名無しさん
2007/12/27(木) 09:31:09scanfの戻り値を利用する
scanfはスキャンに成功した数を返すから、
今回のケースで文字を入力されたら0が返る
0240デフォルトの名無しさん
2007/12/27(木) 09:35:56>scanf("%d", &date[i]);
0241デフォルトの名無しさん
2007/12/27(木) 09:43:47>>232
>scanf("%d", &date[i]);
こういう取り方は文字/数字チェックそのものに意味が無いのでやめ
普通はバッファの文字列変数を用意させて、そこに入力させる。
それをisdigit()に通してクリアしたら、その時点でdate[i]に代入するようにすればいい。
0242デフォルトの名無しさん
2007/12/27(木) 11:13:33結果がへんになる!!!
#include<stdio.h>
int main (void)
{
int a,c;
float b,d;
b=1,d=1;
scanf("%d",c);
for(a=1;a<=1000;a++){
b=b+d;
if(b*b==c){
break;
}
if(b*b<=c)
d=d*0.1;
}
printf(" %d の平方根は= %f ",c,b);
return 0;
}
0243デフォルトの名無しさん
2007/12/27(木) 11:21:530244デフォルトの名無しさん
2007/12/27(木) 11:27:040245デフォルトの名無しさん
2007/12/27(木) 11:30:23すいませんすいませんすいません!
もうしませんもうしませんもうしません!
0246デフォルトの名無しさん
2007/12/27(木) 14:22:54????のところ(該当しなかった場合)が思いつきません。
助けてくださいです…
char a[20];
char b[20];
int hi,lo,i;
略
hi=i;
i=i/2;
lo=0;
while(1){
if(strcmp(b,a) < 0){
hi=i;
i=i-(hi-lo)/2;
}else if(strcmp(b,a) > 0){
lo=i;
i=i+(hi-lo)/2;
}else if(strcmp(b,a) == 0){
printf("あった");
break;
}else if( ???? ){
printf("そんなものなかった");
break;
}
}
0247デフォルトの名無しさん
2007/12/27(木) 14:30:21そこは if (lo > hi) を入れたいんだと思うが、
突っ込みどころが多すぎるからもうちょっと練り直して来い。
0248デフォルトの名無しさん
2007/12/27(木) 14:34:430249デフォルトの名無しさん
2007/12/27(木) 14:45:05絶対通過しない、まあelse外せばいいけど。
で、1ループでstrcmpは1回呼べばいいべ。
あと文字列が終わったのをチェックしないとね。
略の部分を略さないでテスト用に値設定したやつさらしてみてね。
0250246と248
2007/12/27(木) 14:55:46ちょとまってください。
0251デフォルトの名無しさん
2007/12/27(木) 15:10:06int main(){
int i,j;
for(i=1;i<=9;++i)
printf("%2d ",i);
printf("\n--------------------------\n");
for(i=1;i<=9;++i){
for(j=1;j<=9;++j)
printf("%2d ",i*j);
printf("\n");
}
return 0;
for文の練習で書いた上の九九を表示するプログラムをwhile文だけで書けないかなぁと思って
0252デフォルトの名無しさん
2007/12/27(木) 15:10:38#include <stdio.h>
int main(){
int i=1;
while(i<=9){
printf("%2d ",i);
i++;
}
printf("\n--------------------------\n");
i=1;
int j=1;
while(i<=9){
while(j<=9){
printf("%2d ",i*j);
j++;
}
printf("\n");
i++;
}
return 0;
}
このように書いてみたのですが1の段以降改行だけでプログラムが終了してしまいます
どうやったら上手く動かせるでしょうか
■ このスレッドは過去ログ倉庫に格納されています