トップページ⇒tech
1001コメント330KB

スレを勃てるまでもないC/C++の質問はここで 4

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2008/09/17(水) 15:41:48
スレを勃てるまでもない低俗なC/C++の質問はここでお願いします。

過去ログ
スレを勃てるまでもないC/C++の質問はここで
http://pc11.2ch.net/test/read.cgi/tech/1167476845/
スレを勃てるまでもないC/C++の質問はここで 2
http://pc11.2ch.net/test/read.cgi/tech/1178503366/
スレを勃てるまでもないC/C++の質問はここで 3
http://pc11.2ch.net/test/read.cgi/tech/1187521676/
0647デフォルトの名無しさん2008/12/14(日) 19:48:30
>%llu
%lld
06486452008/12/14(日) 19:55:58
コンパイラを Visual C++ 2008 Express にしたところ
解決しました
06496452008/12/14(日) 20:00:42
>>647
VC++6.0 ではダメでした
0650デフォルトの名無しさん2008/12/14(日) 20:03:13
VC6はllに対応していない代わりに、%I64uってのが使えたはず。
0651デフォルトの名無しさん2008/12/14(日) 20:36:25
#include<stdio.h>

main(){
int c,i;
int n[2];
for(i=0; i<2; i++){
printf("%d",i+1);
while((c=getchar()) != '\n'){
if(c >= '0' && c <='9'){
c = c - '0';
n[i] = n[i] * 10 + c;
}else{
/* 終了 */
}
}
}
printf("%d + %d = %d",n[0],n[1],n[0] + n[1]);
return 0;
}

getchar関数を使った足し算を作成したのですが2つの数字を入れてみたところ、
n[1]の値だけ入力した値と異なった値(正の整数が負の整数に、値もめちゃくちゃ)がでてしましました。

どこを改善したらいいか分かりません。アドバイスお願いします。

また、コメントの終了部分に文字が入った場合その場で終了という感じでreturn0を入れたのですが、
1つめを入力したあと終了せずに2つめまで行ってしまいます。これについても終了できる関数かなにかを教えてください。

コンパイラはgccです。
0652デフォルトの名無しさん2008/12/14(日) 20:44:48
>>651
getchar()では一桁だけしか入力できないしエラー処理も厄介だから、
fgets()で1行入力してからじっくり解析する方がいいと思う。
が、それ以前に状況をもっと的確に説明できないもんかね。
0653デフォルトの名無しさん2008/12/14(日) 21:30:31
>>651
俺は初心者だが、最近fgetsを入力として使うのがリーズナブルだなと思った。
ただ、fgetsをキーボード入力として使うとバッファが残っちゃうのでそれを消す機能を付けた自作関数を使うといいと思う。
ttp://ja.wikipedia.org/wiki/fgets

char *fgetsStdin(char *s, int n){
char *temp = fgets(s, n, stdin);
if(temp == NULL){
/* エラー処理(初心者なのでわかりません) */
}
if(strchr(s,'\n') != NULL){
s[strlen(s)-1] = '\0';
}else{
while(getchar() != '\r');
}
return temp;
}
0654デフォルトの名無しさん2008/12/15(月) 04:40:37
#include<stdio.h>
#include<string.h>

typedef struct{
int a;
char name[100];
int b;
int c;
}stringx;

int main(void)
{
int i;
stringx str[5];

for(i = 0;i < 5;i++){
printf("a:");scanf("%d", str[i].a);
printf("name:");fgets(str[i].name, 100, stdin);
printf("b:");scanf("%d", str[i].b);
以下略

これでnameのところに空白も読み込める文字列を入力したいんですが

(実行例)
a:1
name:b:2

と、何故かnameの入力自体がスルーされてしまいます
ちなみにscanfに終了判定を付けたものやgetsでも同じようにスルーされます
何処がいけないのでしょう
コンパイラはgccです
0655デフォルトの名無しさん2008/12/15(月) 04:46:16
入力した文字:
'1'、'\n'
初回のscanf()の消費した文字:
'1'
入力に残った文字:
'\n'

fgets()は、この残っている改行文字を拾ってしまう。

結論:
scanf()とfgets()を混ぜるのは難しい。

対策:
・初回のscanf()のフォーマットを"%d "にする。
・初回のscanf()をfgets()とatoi()(或いはstrtol())に置き換える。
0656デフォルトの名無しさん2008/12/15(月) 12:08:11
>>642
たぶん2つのスレッドが交互に動くことを期待しているのだろうけど、そのような保証はまったくない
lock〜unlockはその範囲内が同時に実行されないことを保証するだけ
unlockから抜けてもすぐにスレッドが切り替わるわけではないし (通常はそのまま走り続ける)、
もう一方のスレッドがずっとlock待ちをしていたのだといても、次に中に入るのがどっちのスレッドになるかは運任せ
(今まで寝てた方のスレッドよりも走り続けてるスレッドの方が先に入る可能性が高いかもしれない)
2つのスレッドが交互に動いて欲しいなら、交互に動くよう確実にプログラムしなければならない
条件変数の使い方を覚えるといいよ
0657デフォルトの名無しさん2008/12/15(月) 22:52:00
>>654
#include<stdio.h>
#include<string.h>

typedef struct{
int a;
char name[100];
int b;
int c;
}stringx;

int main(void)
{
int i;
stringx str[5];
char buff[100];
char *p;

for(i = 0;i < 5;i++){
printf("a:");fgets(buff,100,stdin);sscanf(buff,"%d", &str[i].a);
printf("name:");fgets(buff, 100, stdin);
if(p = strchr(buff,'\n'))
*p = '\0';
strcpy(str[i].name,buff);
printf("b:");fgets(buff,100,stdin);sscanf(buff,"%d", &str[i].b);
printf("c:");fgets(buff,100,stdin);sscanf(buff,"%d", &str[i].c);
}
0658デフォルトの名無しさん2008/12/16(火) 01:06:02
char *cm_getMessage(msg_filename, msg_number)
  char *msg_filename; // メッセージ定義ファイル名
  int msg_number;   // メッセージ番号
{
int i;
}



2,3行目は何を表しているの?引数の型の定義?
0659デフォルトの名無しさん2008/12/16(火) 01:14:23
そそ、所謂オールドスタイル。全く持ってお勧めできないが。
0660デフォルトの名無しさん2008/12/16(火) 17:34:15
100000もある配列の中から配列の中身が「0」の物だけ抜き出して、さらにその抜き出した0の中からランダムに1つ配列を選ぶっていうのを作りたいんだけど

while(x!=0){
y=rand()%100000;
if(array[y]==0) x=0;
}

これだと配列の中身が0の物が1つしかなかったら特定に膨大な時間がかかるよね
何かいい方法ないですか?
0661デフォルトの名無しさん2008/12/16(火) 17:39:42
0が入ってるインデックスの配列作ってそこから抜き出しては?
0662デフォルトの名無しさん2008/12/16(火) 17:40:22
10万どころか100万くらいならシーケンシャルに全部舐めても一瞬で終わる
0663デフォルトの名無しさん2008/12/16(火) 17:41:34
>>660
そのコード、ランダムに1つ要素選んで、それが0でないか調べるとなっていて、
文章に書いてあることとやっていることの順番が違うぞ。
0664デフォルトの名無しさん2008/12/16(火) 17:53:29
>>661
こんなかんじ?
j=0
for(i=0;i<100000;i++){
if(array[i]==0)array2[j]=array[i];j++;
}

y=rand()% j;

array2[y]=〜〜〜〜;
0665デフォルトの名無しさん2008/12/17(水) 05:17:05
array2にはarray[i]じゃなくてiを入れておけば充分だろ。
0666デフォルトの名無しさん2008/12/17(水) 05:17:54
どうでもいいけどif文の使い方を間違えているな。
0667デフォルトの名無しさん2008/12/17(水) 08:20:09
>>664
array2 は全部0
0668デフォルトの名無しさん2008/12/17(水) 10:46:13
>>665-667
なるほど、ありがとうございました
0669デフォルトの名無しさん2008/12/18(木) 08:15:06

#include "stdafx.h"
#include <windows.h>
#include <locate.h>

int _tmain(int argc, _TCHAR* argv[])
{
    TCHAR   message[256];

    setlocale(LC_ALL, "japanese");

    lstrcpy( message, _TEXT("Hello world.\n") );

    printf_s( "%s\n", message );

    return 0;
}

として実行するのですが、printf_s では H しか表示されないのですが、
どうすれば Hello world. と表示されるのでしょうか?
コンパイラはVC++ 2008 Express です
06706692008/12/18(木) 08:27:38
解決しました
0671デフォルトの名無しさん2008/12/18(木) 08:31:03
>>669
_tprintf_s( _TEXT("%s\n"), message );
0672デフォルトの名無しさん2008/12/18(木) 14:38:06
C言語でstrcpy関数を使って文字のコピーをするプログラムを作ったのですが、
コピー後のバッファーにNULL文字が入りません。

どのようにしたら、NULL文字を入れることができるでしょうか?

0673デフォルトの名無しさん2008/12/18(木) 14:53:54
>>672
普通に書いたら0もコピーされる
お前がよっぽど変なプログラム書いたとしか思えない
0674デフォルトの名無しさん2008/12/18(木) 14:55:21
>>672
strcpyのかわりにmemcpy使え。 ちゃんと文字数も渡すんだぞ。
0675デフォルトの名無しさん2008/12/18(木) 16:41:23
なんか乱数のはずが同じ数字になるんだが…

簡略化した奴をちょっと書いてみるんだが
ランダムに配列から数字を引っこ抜く関数を二回呼び出してるんだけど、それが必ず同じ値を引っ張ってくる
なんでだ???

int array[50]={1,2,3,…,48,49,50};

int randomNumber(int x){
return array[(int)((rand() / ((double)RAND_MAX+1.0f)) * x)];
}

void main(void){
int a,b;
srand(time(NULL));
a=randomNumber(50);
b=randomNumber(50);
if(a==b){
printf("同じだよ");
}
}
0676デフォルトの名無しさん2008/12/18(木) 16:46:56
srand(time(NULL)); は乱数の発生順を、その内容によって初期化する、。
time(NULL)は1秒以内なら同じ数値を返すから1秒以内なら同じで当然。

そもそもsrandを毎回呼ぶ必要はない。
0677デフォルトの名無しさん2008/12/18(木) 16:49:11
って内容見ないで脊髄レスしてしまった。
数字表示させてみて。全部0じゃないのそれ?
0678デフォルトの名無しさん2008/12/18(木) 16:49:56
>>676
srand(time(NULL));を消してやってみたけど同じ値がでてくるよ!
0679デフォルトの名無しさん2008/12/18(木) 16:57:50
ごめん別のところで問題起こしてた、自己解決さーせんwww
0680デフォルトの名無しさん2008/12/18(木) 16:58:53
とりあえず、問題なかったわ。 +1.0fで50が返る可能性があるのがちとまずいだけだな
0681デフォルトの名無しさん2008/12/18(木) 17:08:43
>>680
50が返る可能性はないと思うが
0682デフォルトの名無しさん2008/12/18(木) 17:12:07
(rand() / ((double)RAND_MAX+1.0f)
この部分は 0 〜 1に満たない範囲で値になるので、1にならない以上
50にはならないから大丈夫。
0683デフォルトの名無しさん2008/12/18(木) 17:54:41
いや実際返ってきたけど
0684デフォルトの名無しさん2008/12/18(木) 17:57:34
ねーよ。配列内部の値と、添え字を勘違いしていないか?
0685デフォルトの名無しさん2008/12/18(木) 18:03:07
RAND_MAX : 65535 を +1.0の 65536.0 で割った値は、1には満たない、0.9999・・・
それに50を掛けても、50に近い値にはなるが、50には満たない。
その値の整数部分をとっているわけだし。
0686デフォルトの名無しさん2008/12/18(木) 18:08:47
return array[(int)((rand() / ((double)RAND_MAX+1.0f)) * x)];
      ↑
int array[50]={1,2,3,…,48,49,50};
0687デフォルトの名無しさん2008/12/18(木) 18:52:01
わろす
0688デフォルトの名無しさん2008/12/18(木) 19:00:21
クラスのある一つの大小関係でclass全体のスワップをしたいんだが如何すればいいですか?
クラスをベクタコンテナで宣言してvt.at(i).swap(vt.at(i+1))みたいなアルゴリズムを考えています。
0689デフォルトの名無しさん2008/12/18(木) 19:03:46
stlにすでにある件
0690デフォルトの名無しさん2008/12/18(木) 19:14:56
いやあるのはswapするとこだけね
06916882008/12/18(木) 19:28:45
>>689-690
どういう意味ですか?
vt1.swap(vt2)
で
temp=vt1,vt1=vt2,vt2=tempになるのは解るんですが
vt.at(i)とvt.at(k)のスワップ方法が解らないんです。
0692デフォルトの名無しさん2008/12/18(木) 19:37:20
#include <algorithm>
std::swap(vt.at(i), vt.at(k));
06936882008/12/18(木) 19:39:25
>>692
そんな簡単なのがあるんですね。
本には載っていなかったので助かりました。
ありがとうございます。
すいませんでした。
0694デフォルトの名無しさん2008/12/19(金) 00:21:53
マジで勉強しようと思っている者ですが
初心者にお勧めのサイトとか教えてください#
0695デフォルトの名無しさん2008/12/19(金) 00:24:24
http://www.bohyoh.com/
ぼうようはどうよう?
0696デフォルトの名無しさん2008/12/19(金) 00:32:24
>>694
初心者なら素直に本を一冊買った方がいいと思うなぁ…
0697デフォルトの名無しさん2008/12/19(金) 00:32:59
ふむふむ・・
0698デフォルトの名無しさん2008/12/19(金) 00:42:39
俺にできるかな?
0699デフォルトの名無しさん2008/12/19(金) 00:42:51
手法を学ぶのも重要だが、言語の使用や、標準ライブラリを逆引きできる本も欲しいね。
0700デフォルトの名無しさん2008/12/19(金) 00:50:20
翻訳の手順やプログラムの実行方法などは、処理系や実行環境によって異なりますから、....
つまり、・・・・どうすればいいのか.....
0701デフォルトの名無しさん2008/12/19(金) 00:52:04
ふむふむ・・・コンパイラが必要って訳ですね。
0702デフォルトの名無しさん2008/12/19(金) 01:05:32
>>694
http://www.geocities.jp/ky_webid/ProgrammingPlacePlus/c/000.html

最初は意味分からんことが多いと思うが、一つ一つ理解していけばいい。
ゆっくりしていってね。
0703デフォルトの名無しさん2008/12/19(金) 01:25:16
よし、早速自分なりに頑張ってみるよ
0704デフォルトの名無しさん2008/12/19(金) 02:51:30
main(void)
{
return 0;
}


エラーがでます。
0705デフォルトの名無しさん2008/12/19(金) 02:58:22
解の公式を加算減算だけで表すプログラムがわからぬ・・・
0706デフォルトの名無しさん2008/12/19(金) 02:58:31
そうですか。
0707デフォルトの名無しさん2008/12/19(金) 07:14:06
>704
プログラミングの質問に限らず、エラーが出て質問する時は
出たエラーメッセージを貼ろうね、しまじろうとのお約束だよ
0708デフォルトの名無しさん2008/12/19(金) 12:23:58
はい、わかりました。
0709デフォルトの名無しさん2008/12/19(金) 13:26:06
やっぱり、言語をノートに書いたりして覚えたりした?
0710デフォルトの名無しさん2008/12/19(金) 13:39:52
目の前の箱で試せる時代に、それはない。
0711デフォルトの名無しさん2008/12/19(金) 13:42:33
何回も繰り返してたら覚えれえるかな
0712デフォルトの名無しさん2008/12/19(金) 14:35:16
567という整数の10の位だけ(つまり6)を取り出して出力する

#include <stdio.h>

int main(void)
{
int num = 567;

num = num / 10;
num = num % 10;
printf( "%d\n", num );

return 0;
}

どうしてこれで6になるのかわかりやすく教えて!偉い人
0713デフォルトの名無しさん2008/12/19(金) 14:38:33
>>712
int num = 567;
num = num / 10; < num=56
num = num % 10; < num=6
0714デフォルトの名無しさん2008/12/19(金) 14:41:27
そ・・・そういうわけか!!
0715デフォルトの名無しさん2008/12/19(金) 15:20:26
中学校数学レベル
0716デフォルトの名無しさん2008/12/19(金) 15:59:21
残念、小学生レベル。あと、自分基準で〜レベルとか、ランクをつけなくて良いから。
時代によって違うから。
0717デフォルトの名無しさん2008/12/19(金) 16:15:53
 ( ⌒;::)
 |||
<#`Д´>=3
0718デフォルトの名無しさん2008/12/19(金) 16:28:41
>>717
なんで頭に●ンコが生えてんの?
0719デフォルトの名無しさん2008/12/19(金) 16:31:14
>>716
>残念、小学生レベル。
>自分基準で〜レベルとか、ランクをつけなくて良いから。
>残念、小学生レベル。
>自分基準で〜レベルとか、ランクをつけなくて良いから。
0720デフォルトの名無しさん2008/12/19(金) 16:49:48
>>719
いや、本当にそれは小学生レベルだろ?割り算、余りを求める算数を
あんたは中学で習ったのかい?w
0721デフォルトの名無しさん2008/12/19(金) 16:53:39
それじゃ聞くが、割り算、余りを求める算数を、中学校で習った時代を教えてくれ。
近代の義務教育でな。
0722デフォルトの名無しさん2008/12/19(金) 16:57:54
#include <stdio.h>

int main(void)
{
int no;

printf("数字を入力してください:");
scanf( "%d", &no);   /*数字を読み込む*/

printf("あなたは%dと入力しましたね\n", no);

return 0;
}

ビルドエラーが発生しました。続行して、最後に成功したビルドを表示しますか?

教えて!偉い人
0723デフォルトの名無しさん2008/12/19(金) 17:05:46
>>722
   /*数字を読み込む*/
^^^^^の全角空白かな
0724デフォルトの名無しさん2008/12/19(金) 17:09:33
ありがとう!!偉い人!!
0725デフォルトの名無しさん2008/12/21(日) 08:35:26
シューティングで当たり判定の高速化を図りたいんだけど
vector<obj>::iteraot p, q;

p = playerbullet.begin()
while ( p != playerbullet.end() ) {
  q = enemy.begin();
  while( q != enemy.end() ) {
    if( isHit(p,q) )
     // 当たってたときの処理
  }
}

のようにやってるんだけど
遅くて使い物にならない
何か高速化の方法ってありますか?
0726デフォルトの名無しさん2008/12/21(日) 10:24:52
>>725
敵を4分木に入れて、弾の直線と当たり判定を取るってのは?
弾をレイと捉えてレイトレースみたいなイメージ
0727デフォルトの名無しさん2008/12/21(日) 11:21:03
>>725
画面を数分割して敵弾の位置を大まかに分類しておいて、
明らかに無関係な領域にある敵弾は当たり判定自体をスキップする。

複雑な当たり判定を要する弾の場合は、
まずは判定の楽な円-円の判定で大まかに判定し、
明らかに離れているものは真面目に当たり判定を行わずスキップ。
0728デフォルトの名無しさん2008/12/21(日) 12:28:11
どう考えてもボトルネックはisHit()関数なのになんでそこを晒さないのか
0729デフォルトの名無しさん2008/12/21(日) 12:41:23
画面を4分割にするとして、境目にある場合は
どう処理すればいい?
0730デフォルトの名無しさん2008/12/21(日) 12:42:51
どっちかに所属させとけよw
0731デフォルトの名無しさん2008/12/21(日) 12:46:12
両方に属すると判断しとけばいいんじゃね
0732デフォルトの名無しさん2008/12/21(日) 12:46:37
>>725みたいな総当りは、シェーダとかGPGPUでやったら速そうだな
0733デフォルトの名無しさん2008/12/21(日) 12:50:34
>>731
つうか、例えば横512ドットだとして
左は、0 <= x < 256
右は、256 <= x < 512
とすれば、元から境目に存在はしない
0734デフォルトの名無しさん2008/12/21(日) 12:56:53
上下左右別々に扱うわけか。
0735デフォルトの名無しさん2008/12/21(日) 13:21:21
>>728
////////////////////////////////////////////////////////////////////////////////////////////////
//  指定された2つの RECT構造体が、重なっているか判定する
//  重なっていると true
//  かさなっていないと false を返す。
bool    RectLap( const RECT *a, const RECT *b )
{
    //  改良失敗
//  if( (a->top < b->bottom) && (a->bottom < b->top) && (a->left<b->right) && (a->right>b->left) )
//  {
//      return true;
//  }

    if( a->top < b->bottom )
        if( a->bottom > b->top )
            if( a->left < b->right )
                if( a->right > b->left )
                    return true;

    return false;
}
となります
改良の余地があればご指摘お願いします
0736デフォルトの名無しさん2008/12/21(日) 13:41:57
単純な□同士の判定なのか。
それで重いってことは、よほど沢山の弾があるのか?
0737デフォルトの名無しさん2008/12/21(日) 13:53:01
100発もないのですが、どうしても重くなるのです
別スレッドで処理しているのですが、
CPUが割り当てられなくて処理落ちしてるとかも
考えられますか?
0738デフォルトの名無しさん2008/12/21(日) 13:57:12
同期処理に時間がかかってんじゃね?
別スレッドにするメリットってあんの?
0739デフォルトの名無しさん2008/12/21(日) 14:00:43
Celeron 2.53GHz
重たいわけもないでして
昔作ったやつは100発でもいけたので
不思議なのです
変えたといえばコンパイラだけですが
VC++6.0 -> VC++ 2008 Express にしただけです
0740デフォルトの名無しさん2008/12/21(日) 14:02:09
>>738
スレッドを使った理由は技術的好奇心だけです
元の1スレッドに戻してみます
0741デフォルトの名無しさん2008/12/21(日) 14:08:59
VC++ 2008 Express
リリースモードでコンパイルしたら実用レベルになりました
スレ汚しすいません
0742デフォルトの名無しさん2008/12/21(日) 16:01:12
学校の講義でC言語を学ぶことになったので、
VC++ 2008 ExpressをPCに導入したのですが、
計算をさせて、結果を表示するプログラムを作って実行させたら
結果が出力される前にDOS窓が閉じてしまいます。

どうしてでしょうか?
0743デフォルトの名無しさん2008/12/21(日) 16:05:28
そういう仕様
デバッグしないでいいならCtrl-F5(デバッグしないで実行)で。
それ以外にもとめる方法はいくつかあるが。
0744デフォルトの名無しさん2008/12/21(日) 16:06:39
>>742
あきらめろ
0745デフォルトの名無しさん2008/12/21(日) 16:14:07
>>743
ご親切にありがとうございました!

出力結果を無事に見ることができましたmm
0746デフォルトの名無しさん2008/12/21(日) 16:22:20
最近のム板もひどいな
■ このスレッドは過去ログ倉庫に格納されています