【無料配信♪】Renta !全タテコミ作品第1話

VC++2005で開発しています。

typedef struct {
char test1[10];
char test2[5];
・・・
char test10[5];
}Sample;

Sample sample;

char *x[] = {"あ", "い",・・・, "こ"};

strcpy(sample.test1, x[0]);
strcpy(sample.test2 = x[2]);
・・・
strcpy(sample.tet10, x[9]);

このstrcpyの部分をループ文でまわしたいのですが、
何か良い方法はありませんか?

よろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

できますけど、あまり意味の無いような気がします。



int offset[] = {
offsetof(Sample,test1),
offsetof(Sample,test2),
offsetof(Sample,test3)
};

int i;
for(i=0; i<sizeof x/sizeof(char*); i++){
strcpy((char*)&sample+offset[i],x[i]);
}
    • good
    • 1
この回答へのお礼

ご回答ありがとうございます。

今回はポインタ配列を使用することにしました。
(データ型がすべてcharなので)

お礼日時:2011/08/19 21:49

C言語の場合。


例えば
int test1,test2,test3 ;
とかの変数をループで回すことってできませんよね?構造体のメンバも同様です。

typedef struct {
char test[10][10];
}Sample;
等と二次元配列にするとか、

何度も出てくるなら
structSampleCopy( Sample *dst, char **src )
みたいな関数にするとか、

指定した数値に対応するメンバのアドレスを返すmemberAddressみたいな関数を用意して
strcpy( memberAddress(&sample,i ) ,X[i] ) ;
みたいに各メンバの先頭アドレスに直接アクセスするか
でしょうか。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

今回はポインタ配列を使用することにしました。
(データ型がすべてcharなので)

お礼日時:2011/08/19 21:49

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q構造体のメンバをfor文で回したい

次のようなソースで

typedef struct test{
int a;
int b;
int c;
}TEST;

TEST xx;
xx.a=xx.a+3;
xx.b=xx.b+3;
xx.c=xx.c+3;

printf("%d %d %d\n",xx.a,xx.b,xx.c);

のようなことをしたいんですが、
xx.a=xx.a+3;
xx.b=xx.b+3;
xx.c=xx.c+3;
の処理の部分をfor文で回せるようにしたいです。
構造体の宣言のところで配列をつかって
struct test{
int abc[3];
}
とすれば簡単にいくのは分かるんですが、a,b,cそれぞれに分かりやすい名前をつけたいので、配列で確保したくないです。
何かいい方法はないでしょうか?

実際計算に使うんですが、メンバはすべてdouble型で30個程度になると思います。

Aベストアンサー

軽くなったので続きをば

共用体は、なるべくメンバのアドレスを共有するように動作します。だから、共用体の宣言を変えない限り確保されるパターンが変わることはありません。
だから、安心して使っても大丈夫です。
特に今回のように、配列と名前アクセスを行いたいのであれば、moca12980さんが先の補足にあげられたようにやればまったく問題ありません。

--テストプログラムここから

typedef union test{
struct{double a,b,c,d[17];};
double temp[20];
}uABC;

uABC abc;

int main()
{
int i;
for(i=0; i<20; i++) abc.temp[i]=i;

printf("a=%.2f,\tb=%.2f,\tc=%.2f\n", abc.a, abc.b, abc.c);
for(i=0; i<17; i++) printf("d[%02d]=%.2f,\t", i, abc.d[i]);
printf("\n");
return 0;
}

--テストプログラムここまで


実は、変数の個数が少なければ、defineでもかわせます。個数が増えると見通しがいい分共用体の方が楽なんですけど。

--テストプログラムここから
double temp[20];

#define U_a(A) A[0]
#define U_b(A) A[1]
#define U_c(A) A[2]
#define U_d(A,X) A[(X) + 3]

int main()
{
int i;
for(i=0; i<20; i++) temp[i]=i;

printf("a=%.2f,\tb=%.2f,\tc=%.2f\n", U_a(temp), U_b(temp), U_c(temp));
for(i=0; i<17; i++) printf("d[%02d]=%.2f,\t", i, U_d(temp, i));
printf("\n");
return 0;
}

--テストプログラムここまで

軽くなったので続きをば

共用体は、なるべくメンバのアドレスを共有するように動作します。だから、共用体の宣言を変えない限り確保されるパターンが変わることはありません。
だから、安心して使っても大丈夫です。
特に今回のように、配列と名前アクセスを行いたいのであれば、moca12980さんが先の補足にあげられたようにやればまったく問題ありません。

--テストプログラムここから

typedef union test{
struct{double a,b,c,d[17];};
double temp[20];
}uABC;

uABC abc;

int main()
{
...続きを読む

QC言語で構造体のメンバを簡単に出力する方法ありますか?

いつもお世話になっています。

C言語の質問です。
単体テストログを取るために、
“関数Aをコールする前後で、関数Aに引数として渡す構造体のメンバをすべて”printf(もしくはfprintf)で出力して比較確認しなければならないのですが、

構造体のメンバが250とか、150とかあり、メンバ名もxxx_01,xxx_02などのようにエクセルなどで簡単に加工して作れるものではないので、いちいちメンバ名を指定しなければならないのでとても大変です。

オブジェクト指向言語なら、for each文とかでオブジェクトのメンバを簡単に取り出せるのでしょうが(間違っているかもしれません・・・)、C言語で構造体のメンバを、for文などのループを使って簡単に出力できる方法はないでしょうか?

メンバの型は、一定ではなく、char、int、double、別の構造体のポインタ型(これは出力しなくて良い)と混在しています。メンバが全て同一の型ならポインタで構造体の先頭アドレスからsizeof(メンバの型)の分インクリメントしていけば出力できそうな気もしますが、メモリ上に連続して確保されるのかも私にはわからないので困っています。

enumで列挙して・・・というのも調べてみましたが、応用は出来ないようでした。

どなたか、地道にメンバ名を書いて出力する以外の方法をご存知の方、いらっしゃいましたらお知恵をお貸しください。
よろしくお願いいたします。
※説明不足の点がありましたら補足いたします。

いつもお世話になっています。

C言語の質問です。
単体テストログを取るために、
“関数Aをコールする前後で、関数Aに引数として渡す構造体のメンバをすべて”printf(もしくはfprintf)で出力して比較確認しなければならないのですが、

構造体のメンバが250とか、150とかあり、メンバ名もxxx_01,xxx_02などのようにエクセルなどで簡単に加工して作れるものではないので、いちいちメンバ名を指定しなければならないのでとても大変です。

オブジェクト指向言語なら、for each文とかでオブジェクトのメンバを...続きを読む

Aベストアンサー

コードを書かないという方向性の提案を一つ。
デバッガに構造体の内容を出力させるというのはどうでしょうか。

struct {
int a;
char *b;
double c;
}
という型を持つ変数xがあったとして、gdbでは下記のような出力が得られます。
(gdb) print x
$1 = {
a = 123,
b = 0x2fd0 "ABC",
c = -9876.5
}

Q構造体のメンバへのアクセスについて

お世話になります。
構造体testがあり
そのメンバにchar a1[10],a2[20]・・・a100[20]まであるとします。
(配列サイズは不定)
このときtest.an (nは任意の数値)にアクセスしたいのですが
どう記述したらいいでしょうか?
どなたかご指南お願いします。

Aベストアンサー

ちょっと長くなりますが、いいですか?
まず、配列の定義を構造体のメンバではなく、
実体定義にします。
そして、配列のポインタと、そのデータ長(要素数)をメンバにもつ構造体Aを作成します。
そして、Aを100個の配列にしたメンバを持つ構造体Bを作成します。
そうするとForループでアクセス可能になります。
相当わかりにくいと思うので、
以下にサンプルコードを書きます。
ちなみにこのデータ構造はコードメンテナンスを楽にする手法で、配列の中身や大きさが変更になっても、ロジックは変更せずに、データ定義だけの変更ですみます。

#define A1_SIZE (10) // A1の配列数
#define A100_SIZE (20) // A100の配列数
#define An_MAX_NUM (100) // データ数

/* 配列そのものの定義 */
chara1[A1_SIZE] ;// a1データ
/* 中略 */
chara100[A100_SIZE] ;// a100データ

/* データ定義構造体 */
typedef struct
{
char *data; // データのアドレス
int datalen ; // データ長
} tDATA_DEF ;


/* データ管理構造体 */
typedef struct
{
tDATA_DEF data_def[An_MAX_NUM];
} tDATA ;

/* データと管理構造体のリンク */
const tDATA tData =
{
/* A1データ */
{ a1, // データのアドレス
A1_SIZE // データ長
},

/* 中略 */

/* A100データ */
{ a100, // データのアドレス
A100_SIZE // データ長
},

}

void
main()
{
int i ;

/* 可変長のデータを0クリアする */
for( i=0; i<An_MAX_NUM; i++ )
{
memset( tData.data_def[i].data, 0, tData.data_def[i].datalen );
}
}

ちょっと長くなりますが、いいですか?
まず、配列の定義を構造体のメンバではなく、
実体定義にします。
そして、配列のポインタと、そのデータ長(要素数)をメンバにもつ構造体Aを作成します。
そして、Aを100個の配列にしたメンバを持つ構造体Bを作成します。
そうするとForループでアクセス可能になります。
相当わかりにくいと思うので、
以下にサンプルコードを書きます。
ちなみにこのデータ構造はコードメンテナンスを楽にする手法で、配列の中身や大きさが変更になっても、ロジックは変更せ...続きを読む

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

QC++言語で、構造体のコピーは可能(しても良い)のでしょうか?

C++言語で、構造体のコピーは可能(しても良い)のでしょうか?
問題がある場合は、なぜだめなのか知りたいです。
構造体は可変長ではありません。

typedef struct kumi {
char namae[10];
int ten;
}Kumi;

Kumi a, b;

strcpy(a.namae, "AAA");
a.ten = 50;

b = a;

Aベストアンサー

「C++」では何の問題もありません.
「C」だと, ふる~い時代の遺跡級のコンパイラが文句を言うかもしれません. ま, その手の遺跡級のコンパイラだと
・void がない (void * は char * で代用する)
・プロトタイプが存在しない
・const や volatile がない
・ひょっとすると単項の + もない
など, 今の視点からするといいたいことは山ほどあります (さすがに a -= b; ではなく a =- b; とするコンパイラを使うことはないだろう).
そのような時代には構造体のコピーを memcpy でやっていましたが, C++ では逆に危険です.

Q構造体を指すポインタからその中のポインタ変数が指す要素の参照

構造体を指しているポインタから、
その構造体内にあるポインタ変数の指している要素に値を代入する方法が、どうしてもわかりませんでした。
どなたか助けてください、お願いします。


struct Kouzou
{
int* p;
};

int main()
{
Kouzou kou;
Kouzou* k_p;

k_p = &kou;

k_p -> *p = 10; //エラー
}

Aベストアンサー

*k_p->p = 10;

ですけど、pが指す先を定義しておかないと
エラーになりますよ。

QDWORDの実際の型は何でしょうか

VC++.NETの環境です。
DOWRD dw1 = 1;
int i = 2; と定義し
ここで
if ( i > dw1 ){
何かの処理;
}
とコーディングすると
warning C4018: '>' : signed と unsigned の数値を比較しようとしました。
のワーニングがでます。
これは、DWORDがint型でなくunsigned int型のようにも見えます。
ある本によれば(VC++.V.NET逆引き大全500の極意)
DWORD はint型であると記述されています。
もし、int型ならこのワーニングはでないはずなのですが、
なぜでるのでしょうか。又、DWORDの実際の型は何なのでしょうか。ご存じのかたおりましたら、教えていただけませんでしょうか。

Aベストアンサー

型定義が知りたいのならば、宣言ファイルを見れば疑問を挟む余地もありません。
DWORD型はwindef.hで
"typedef unsigned long DWORD;"
と宣言されています。

Visual Studioを使っているのならば、知りたい型の上にマウスポインタを置いて右クリック、ポップアップメニューの「定義へ移動」または「宣言へ移動」で簡単に知ることが出来ます。

Q構造体のメンバが配列の場合の扱い

typedef struct _info_t{
int xxx;
int yyy;
int zzz;
} info_t;

typedef struct _gData{
int aaa;
 int bbb;
info_t infoData[100];
} gData_t;

gData_t gMainData;

質問1
C言語で上記のようなグローバルのデータを作成しようとしています。
gMainDataの中身を初期化するにはどうするのがベストでしょうか?
(特にinfoData[100]の初期化)

質問2
gMainData.infoData[XXX]には info_t型のtmpDataを代入しようとしていますが
gMainData.infoData[XXX] = tmpData;
データがはいっているかどうかはどう判定するべきでしょうか?


質問3
以下のようにポインタを使うのは間違いでしょうか?
typedef struct _gData{
int aaa;
 int bbb;
info_t *infoData[100];
} gData_t;


初期化
memset(gMainData.infoData,NULL, 100);

データの代入
*gMainData.infoData[XXX] = tmpData;

データの有無判定
if( gMainData.infoData[XXX] == NULL){

}

typedef struct _info_t{
int xxx;
int yyy;
int zzz;
} info_t;

typedef struct _gData{
int aaa;
 int bbb;
info_t infoData[100];
} gData_t;

gData_t gMainData;

質問1
C言語で上記のようなグローバルのデータを作成しようとしています。
gMainDataの中身を初期化するにはどうするのがベストでしょうか?
(特にinfoData[100]の初期化)

質問2
gMainData.infoData[XXX]には info_t型のtmpDataを代入しようとしていますが
gMainData.infoData[XXX] = tmpData;
データがはいっているかどう...続きを読む

Aベストアンサー

1.初期化
ループでもmemsetでもよいと思います。どれがベストかはケース・バイ・ケースでしょう。

ただしmemsetの第2引数はint型、第3引数はバイト数なので、次のようにするべきです。
memset(gMainData.infoData, 0, 100 * sizeof(info_t));

また、C言語の規格により static 変数を明示的に初期化しなければ全て 0 になるので
static gData_t iniData;
gData_t data;
と定義しておいて
data = iniData;
のように初期化する方法も(一応)あります。


2.データの代入

info_t *infoData[100] は構造体の配列ではなく、ポインタの配列です。
infoData をポインタにするなら、構造体を下のようにすれば

typedef struct _gData {
 int aaa;
 int bbb;
 info_t *infoData[100];
 info_t _infoData[100];
} gData_t;

次のように代入することができます。

data._infoData[XXX] = tmpData;
data.infoData[XXX] = &(data._infoData[XXX]);


3.データの有無判定

前述の2のようにすれば
if( gMainData.infoData[XXX] == NULL){
}
でデータを代入済みかどうか判定できます。
もちろんデータを代入していないポインタがNULLであることが前提ですが。


・余談ですが、構造体のタグ名とtypedefする型名は同じでも大丈夫です。例えば

typedef struct info_t{
...
} info_t;

のように。

1.初期化
ループでもmemsetでもよいと思います。どれがベストかはケース・バイ・ケースでしょう。

ただしmemsetの第2引数はint型、第3引数はバイト数なので、次のようにするべきです。
memset(gMainData.infoData, 0, 100 * sizeof(info_t));

また、C言語の規格により static 変数を明示的に初期化しなければ全て 0 になるので
static gData_t iniData;
gData_t data;
と定義しておいて
data = iniData;
のように初期化する方法も(一応)あります。


2.データの代入

info_t *infoData[100] は構造体の配...続きを読む

QC++ 構造体の一括初期化 {0}

構造体変数に {0} を代入すると、CString は空文字、 intは0に一括で初期化されるようです。
なんでこんなことが出来るのでしょう?
{0}は何?
仕組みを教えて下さい!!

Aベストアンサー

> 一括初期化関数でも作るしかなさそうですね
static変数を初期化用に用意しておくのはいかが?
http://oshiete.goo.ne.jp/qa/2658268.htmlより
>静的記憶域期間をもつオブジェクトを明示的に初期化しない場合、
>次の規定に従う。
>a) そのオブジェクトの型がポインタ型の場合、空ポインタに初期化する。
>b) そのオブジェクトの型が算術型の場合、(正または符号なしの)0に初期化する。
>c) そのオブジェクトが集成体の場合、各メンバにa)~d)の規定を(再帰的に)
>適用し初期化する。
>d) そのオブジェクトが共用体の場合、最初の名前つきメンバにa)~d)の規定を
>(再帰的に)適用し初期化する。

なので、zero初期化されていることが、規格で保証されます。

typedef struct hoge_struct
{
 int a;
 int b;
} hoge_struct;

static hoge_struct initializer; //初期化用変数。値は変えない。

int main(void)
{
 hoge_struct hoge;
 hoge = initializer;
 return 0;
}
真っ白に何度も初期化したいなら、こんな感じでどうでしょう?
関数を用意して初期化すると、構造体のメンバが増えると関数も修正しないといけない
ですが、これだと関数を変更しなくてすむし。

> 一括初期化関数でも作るしかなさそうですね
static変数を初期化用に用意しておくのはいかが?
http://oshiete.goo.ne.jp/qa/2658268.htmlより
>静的記憶域期間をもつオブジェクトを明示的に初期化しない場合、
>次の規定に従う。
>a) そのオブジェクトの型がポインタ型の場合、空ポインタに初期化する。
>b) そのオブジェクトの型が算術型の場合、(正または符号なしの)0に初期化する。
>c) そのオブジェクトが集成体の場合、各メンバにa)~d)の規定を(再帰的に)
>適用し初期化する。
>d) そのオブジェクトが共用...続きを読む

Q戻り値で構造体を返すことは可能でしょうか?

perlでは以下のように2つの戻り値が可能ですが、C言語では
それができるのでしょうか?
my (ret1, ret2) = test1();

よくやるのは、引数にポインタを渡して、内容を書き換える手を使っていますが、戻り値を複数返せたら、直感的にわかりやすいかなと思いまして・・・

Aベストアンサー

C言語から遠く離れた者ですが、

>>> よくやるのは、引数にポインタを渡して、内容を書き換える手を使っています

これが常識でしょう。これが直感的に理解できるようにC言語を身に付ける必要があるのではないでしょうか。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング