エラーが出て困っています。
エラーが出て困っています。
初、投稿のルートです。以後よろしくお願いします。
只今、ノベル風の文字表示のプログラムを作っているのですが(当サイトのサンプルプログラム参考)、エラーが出て困っています。どなたかわかるかたお願いします。
メインプログラム↓
ーーーーーーーーーーー
#include "DxLib.h"
#include "style1.h"
int i=0,j,ch_i=0,counter=0,White;
char Key[256],oldKey[256]={},disp[80]="",ch[5][80];
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1;
SetDrawScreen( DX_SCREEN_BACK ) ;
White=GetColor(255,255,255);
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
style1_up();
for(j=0;j<256;j++){
if(oldKey[j]==0 && Key[j]==1)
Key[j]=2;
oldKey[j]=Key[j];
}
if(Key[KEY_INPUT_RETURN]==2){ // 前回押されてなくて、今回押されていたら
i=0; // iを初期値に戻し
ch_i++; // 表示する配列を1つずらす
if(ch_i==5) // これ以上表示する配列がなくなったらbreak;
break;
}
// 配列の終端-2以下で、今回コピーするiまでの配列要素のi番目が\0じゃなくカウンターが5の倍数なら
if(i<=80-2 && ch[ch_i]!='\0' && counter%5==0){
i+=2; // 全角文字なので配列要素2つずつカウントアップ
strncpy_s(disp,ch[ch_i],i);// iバイトまでの配列要素をdisp配列にコピー
disp='\0'; // 終端記号を代入
}
DrawFormatString(10,420,White,"%s",disp);//disp配列の文字データを表示
counter++;
ScreenFlip() ;
}
DxLib_End() ;
return 0 ;
}
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
//style1.h↓
#ifndef DEF_style1_h //二重include防止
#define DEF_style1_h
void style1_up();
#endif
ーーーーーーーーーーーーーーーーーーーー
//style1.cpp
#include "DxLib.h"
char ch[5][80];
void style1_up()
{
ch[5][80]=(
"プログラムを習得するには、実際に自分で書いてみることが大事。",
"参考書を読むことも重要だが、数学のように演習を通して、",
"体に身につけるようにしよう。",
"きっと、よりはっきりと、関数の使い方、",
"プログラムの書き方がわかるだろう。"
);
}
style1.cppの部分で文を書いて、メインのほうに表示したいのですが・・・・
以下のようなエラーが出ます。
・c:\users\ユーザ名\documents\visual studio 2010\projects\samplex\style1.cpp(12): error C2440: '=' : 'const char *' から 'char' に変換できません。
1> この変換が可能なコンテキストはありません。
開発環境はVisual Studio Professionalを使用しています。
只今、ノベル風の文字表示のプログラムを作っているのですが(当サイトのサンプルプログラム参考)、エラーが出て困っています。どなたかわかるかたお願いします。
メインプログラム↓
ーーーーーーーーーーー
#include "DxLib.h"
#include "style1.h"
int i=0,j,ch_i=0,counter=0,White;
char Key[256],oldKey[256]={},disp[80]="",ch[5][80];
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1;
SetDrawScreen( DX_SCREEN_BACK ) ;
White=GetColor(255,255,255);
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
style1_up();
for(j=0;j<256;j++){
if(oldKey[j]==0 && Key[j]==1)
Key[j]=2;
oldKey[j]=Key[j];
}
if(Key[KEY_INPUT_RETURN]==2){ // 前回押されてなくて、今回押されていたら
i=0; // iを初期値に戻し
ch_i++; // 表示する配列を1つずらす
if(ch_i==5) // これ以上表示する配列がなくなったらbreak;
break;
}
// 配列の終端-2以下で、今回コピーするiまでの配列要素のi番目が\0じゃなくカウンターが5の倍数なら
if(i<=80-2 && ch[ch_i]!='\0' && counter%5==0){
i+=2; // 全角文字なので配列要素2つずつカウントアップ
strncpy_s(disp,ch[ch_i],i);// iバイトまでの配列要素をdisp配列にコピー
disp='\0'; // 終端記号を代入
}
DrawFormatString(10,420,White,"%s",disp);//disp配列の文字データを表示
counter++;
ScreenFlip() ;
}
DxLib_End() ;
return 0 ;
}
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
//style1.h↓
#ifndef DEF_style1_h //二重include防止
#define DEF_style1_h
void style1_up();
#endif
ーーーーーーーーーーーーーーーーーーーー
//style1.cpp
#include "DxLib.h"
char ch[5][80];
void style1_up()
{
ch[5][80]=(
"プログラムを習得するには、実際に自分で書いてみることが大事。",
"参考書を読むことも重要だが、数学のように演習を通して、",
"体に身につけるようにしよう。",
"きっと、よりはっきりと、関数の使い方、",
"プログラムの書き方がわかるだろう。"
);
}
style1.cppの部分で文を書いて、メインのほうに表示したいのですが・・・・
以下のようなエラーが出ます。
・c:\users\ユーザ名\documents\visual studio 2010\projects\samplex\style1.cpp(12): error C2440: '=' : 'const char *' から 'char' に変換できません。
1> この変換が可能なコンテキストはありません。
開発環境はVisual Studio Professionalを使用しています。
Re: エラーが出て困っています。
ソースコードはcodeタグで囲みましょう。
2次元配列chはstyle1.cppの2行目で定義されていますので、初期化はそこでやらねばなりません。
どうしてもstyle1_up関数内部で文字列を代入したいなら、strcpy関数を使ったり、1文字ずつ代入したりしなければなりません。
2次元配列chはstyle1.cppの2行目で定義されていますので、初期化はそこでやらねばなりません。
どうしてもstyle1_up関数内部で文字列を代入したいなら、strcpy関数を使ったり、1文字ずつ代入したりしなければなりません。
Re: エラーが出て困っています。
とりあえず整形したソースを貼ります。本来ならルートさんがやるべき作業です。
main.cpp
//style1.h
//style1.cpp
main.cpp
#include "DxLib.h"
#include "style1.h"
int i=0,j,ch_i=0,counter=0,White;
char Key[256],oldKey[256]={},disp[80]="",ch[5][80];
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1;
SetDrawScreen( DX_SCREEN_BACK ) ;
White=GetColor(255,255,255);
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
style1_up();
for(j=0;j<256;j++){
if(oldKey[j]==0 && Key[j]==1)
Key[j]=2;
oldKey[j]=Key[j];
}
if(Key[KEY_INPUT_RETURN]==2){ // 前回押されてなくて、今回押されていたら
i=0; // iを初期値に戻し
ch_i++; // 表示する配列を1つずらす
if(ch_i==5) // これ以上表示する配列がなくなったらbreak;
break;
}
// 配列の終端-2以下で、今回コピーするiまでの配列要素のi番目が\0じゃなくカウンターが5の倍数なら
if(i<=80-2 && ch[ch_i][i]!='\0' && counter%5==0){
i+=2; // 全角文字なので配列要素2つずつカウントアップ
strncpy_s(disp,ch[ch_i],i);// iバイトまでの配列要素をdisp配列にコピー
disp[i]='\0'; // 終端記号を代入
}
DrawFormatString(10,420,White,"%s",disp);//disp配列の文字データを表示
counter++;
ScreenFlip() ;
}
DxLib_End() ;
return 0 ;
}
Re: エラーが出て困っています。
ここのch[5][80]と
ここのch[5][80]とは、どういう使い分けをしたいのですか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
Re: エラーが出て困っています。
ch変数に関することでいくつか問題点がありますので指摘します。
まず、ch変数はグローバル変数になっているのに、2つの.cppファイルに定義されていることです。
グローバル変数を複数の場所で定義するのはダメです。
次に、配列の扱いに関する根本的な理解不足です。
例えば と定義された変数aが有った場合、この配列の5番目の要素に書きこむには とします。決して とは書けません。
これは2次元配列でもまったく同じで、添え字が1つ増えるだけです。
ルートさんは
と書いていますが、これはC++の文法的に誤りです。配列にまとめて値を入れるときは、配列を定義した時点で「初期値」として指定するしかありません。
この場合は、文字列5つを「初期値」として与えているため、C++の文法的に正しいです。
まず、ch変数はグローバル変数になっているのに、2つの.cppファイルに定義されていることです。
グローバル変数を複数の場所で定義するのはダメです。
次に、配列の扱いに関する根本的な理解不足です。
例えば と定義された変数aが有った場合、この配列の5番目の要素に書きこむには とします。決して とは書けません。
これは2次元配列でもまったく同じで、添え字が1つ増えるだけです。
ルートさんは
ch[5][80]=(
"プログラムを習得するには、実際に自分で書いてみることが大事。",
"参考書を読むことも重要だが、数学のように演習を通して、",
"体に身につけるようにしよう。",
"きっと、よりはっきりと、関数の使い方、",
"プログラムの書き方がわかるだろう。"
);
Re: エラーが出て困っています。
style1_upによる文章の格納はできたのですが、
style1_up関数をそのまま、メインのとこに記述しただけでは、文は表示されないのでしょうか?
やはり、strcpy関数とかで、コピーして表示させるのでしょうか・・・・
style1_up関数をそのまま、メインのとこに記述しただけでは、文は表示されないのでしょうか?
やはり、strcpy関数とかで、コピーして表示させるのでしょうか・・・・
Re: エラーが出て困っています。
恐らく、No.5のboxさんの質問に答えれば、分かってくるでしょう。ルート さんが書きました:style1_upによる文章の格納はできたのですが、
style1_up関数をそのまま、メインのとこに記述しただけでは、文は表示されないのでしょうか?
やはり、strcpy関数とかで、コピーして表示させるのでしょうか・・・・
Re: エラーが出て困っています。
その、完成したソースコードを貼って下さい。後の人の参考になるように。お願いします。
これはフォーラムルールでもありますから、義務です。
これはフォーラムルールでもありますから、義務です。
また、解決した時は、「解決しました」とだけ言って去らず、ソースコードや解決した方法を明記して下さい。
同じ事で困っている人の為に過去ログに有用な情報を残すようお願いします。
Re: エラーが出て困っています。
boxさんが言ってたことは、こういうのとは、また別のことですよね・・・
ーーーーーーメインプログラムだけ載せました↓ーーーーーーーー
#include "DxLib.h"
#include "style1.h"
int i=0,j,ch_i=0,counter=0,White;
char Key[256],oldKey[256]={},disp[80]="", style1_up();
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1;
SetDrawScreen( DX_SCREEN_BACK ) ;
White=GetColor(255,255,255);
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
for(j=0;j<256;j++){
if(oldKey[j]==0 && Key[j]==1)
Key[j]=2;
oldKey[j]=Key[j];
}
if(Key[KEY_INPUT_RETURN]==2){ // 前回押されてなくて、今回押されていたら
i=0; // iを初期値に戻し
ch_i++; // 表示する配列を1つずらす
if(ch_i==5) // これ以上表示する配列がなくなったらbreak;
break;
}
// 配列の終端-2以下で、今回コピーするiまでの配列要素のi番目が\0じゃなくカウンターが5の倍数なら
if(i<=80-2 && ch[ch_i]!='\0' && counter%5==0){
i+=2; // 全角文字なので配列要素2つずつカウントアップ
strncpy_s(disp,ch[ch_i],i);// iバイトまでの配列要素をdisp配列にコピー
disp='\0'; // 終端記号を代入
}
DrawFormatString(10,420,White,"%s",disp);//disp配列の文字データを表示
counter++;
ScreenFlip() ;
}
DxLib_End() ;
return 0 ;
}
ーーーーーーーーーーーーーーーーーーーーーー
ーーーーーーメインプログラムだけ載せました↓ーーーーーーーー
#include "DxLib.h"
#include "style1.h"
int i=0,j,ch_i=0,counter=0,White;
char Key[256],oldKey[256]={},disp[80]="", style1_up();
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1;
SetDrawScreen( DX_SCREEN_BACK ) ;
White=GetColor(255,255,255);
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
for(j=0;j<256;j++){
if(oldKey[j]==0 && Key[j]==1)
Key[j]=2;
oldKey[j]=Key[j];
}
if(Key[KEY_INPUT_RETURN]==2){ // 前回押されてなくて、今回押されていたら
i=0; // iを初期値に戻し
ch_i++; // 表示する配列を1つずらす
if(ch_i==5) // これ以上表示する配列がなくなったらbreak;
break;
}
// 配列の終端-2以下で、今回コピーするiまでの配列要素のi番目が\0じゃなくカウンターが5の倍数なら
if(i<=80-2 && ch[ch_i]!='\0' && counter%5==0){
i+=2; // 全角文字なので配列要素2つずつカウントアップ
strncpy_s(disp,ch[ch_i],i);// iバイトまでの配列要素をdisp配列にコピー
disp='\0'; // 終端記号を代入
}
DrawFormatString(10,420,White,"%s",disp);//disp配列の文字データを表示
counter++;
ScreenFlip() ;
}
DxLib_End() ;
return 0 ;
}
ーーーーーーーーーーーーーーーーーーーーーー
Re: エラーが出て困っています。
boxさんの質問は、2つのch変数について、「どういう使い分けをしたいのか」ですから、日本語で答えたらいいと思います。
- bitter_fox
- 記事: 607
- 登録日時: 13年前
- 住所: 大阪府
Re: エラーが出て困っています。
最初に、ソースコードを載せる場合はcodeタグを使ってください。
http://dixq.net/board/board.html#k10
このことは既にbeatleさんからも指摘されていますが、codeタグの使い方が分からないのでしょうか?
もしそうであれば使い方を説明しますのでおっしゃってください。
A地区(ファイルA)にch君がいて、B地区(ファイルB)に同姓同名のch君がいると考えてください。
B地区に居るstyle1_upさんがch君に荷物S(文字列)を預けました。このch君はB地区にいるch君です。
そのあとA地区のWinMainさんがch君から荷物S(文字列)を受け取ろうとします。この時のch君はA地区のch君です。
・・・荷物SはB地区のch君が持っていて、A地区のch君は持っていないのでWinMainさんが行った行動は失敗します。
boxさんの言いたいことはおそらく、A地区のch君とB地区のch君は本当は同じ人であってほしいのではないですか?という事だと思います。
ちなみにこの状況だとリンクに失敗します。
もしstyle1.cppが次のようになっていたら事態はより複雑です。
この場合だと、B地区にいるch君に加え、style1_upさんお抱えの秘書のch君が居るというような感じです。
そしてstyle1_upさんが預けた荷物S(文字列)を持っているのはお抱えの秘書のch君です。
この問題の解決にはexternを使ってchを一つにまとめてください。
http://7ujm.net/C++/extern.html
http://www.geocities.jp/ky_webid/c/032.html
あと、グローバル変数を乱用するのは好ましくないので、グローバル変数を乱用しない書き方をしたほうが良いようにも思います。
[hr][追記]
擬似コードを用いると
の様になります。
WinMainからはfile style1のchは見えません、また同様にstyle1_upからはfile Mainのchは見えません。
http://dixq.net/board/board.html#k10
このことは既にbeatleさんからも指摘されていますが、codeタグの使い方が分からないのでしょうか?
もしそうであれば使い方を説明しますのでおっしゃってください。
最初のプログラムの問題を簡潔に説明すると、ルート さんが書きました:boxさんが言いたいのは、グローバル関数を二回も定義しなくてもいい。
みたいなことでしょうか・・・・(確証がなく・・・)
A地区(ファイルA)にch君がいて、B地区(ファイルB)に同姓同名のch君がいると考えてください。
B地区に居るstyle1_upさんがch君に荷物S(文字列)を預けました。このch君はB地区にいるch君です。
そのあとA地区のWinMainさんがch君から荷物S(文字列)を受け取ろうとします。この時のch君はA地区のch君です。
・・・荷物SはB地区のch君が持っていて、A地区のch君は持っていないのでWinMainさんが行った行動は失敗します。
boxさんの言いたいことはおそらく、A地区のch君とB地区のch君は本当は同じ人であってほしいのではないですか?という事だと思います。
ちなみにこの状況だとリンクに失敗します。
もしstyle1.cppが次のようになっていたら事態はより複雑です。
#include "DxLib.h"
char ch[5][80];
void style1_up()
{
char ch[5][80] = {
"プログラムを習得するには、実際に自分で書いてみることが大事。",
"参考書を読むことも重要だが、数学のように演習を通して、",
"体に身につけるようにしよう。",
"きっと、よりはっきりと、関数の使い方、",
"プログラムの書き方がわかるだろう。"
};
}
そしてstyle1_upさんが預けた荷物S(文字列)を持っているのはお抱えの秘書のch君です。
この問題の解決にはexternを使ってchを一つにまとめてください。
http://7ujm.net/C++/extern.html
http://www.geocities.jp/ky_webid/c/032.html
あと、グローバル変数を乱用するのは好ましくないので、グローバル変数を乱用しない書き方をしたほうが良いようにも思います。
[hr][追記]
擬似コードを用いると
file Main
{
include header DxLib
include header style1
char ch[5][80]
function WinMain
}
file style1
{
char ch[5][80]
function style1_up
}
WinMainからはfile style1のchは見えません、また同様にstyle1_upからはfile Mainのchは見えません。
Re: エラーが出て困っています。
//style1.cpp
#include "DxLib.h"
void style1_up()
{
char ch[5][80]={
"プログラムを習得するには、実際に自分で書いてみることが大事。",
"参考書を読むことも重要だが、数学のように演習を通して、",
"体に身につけるようにしよう。",
"きっと、よりはっきりと、関数の使い方、",
"プログラムの書き方がわかるだろう。"
};
}
//samplex
#include "DxLib.h"
#include "style1.h"
int i=0,j,ch_i=0,counter=0,White;
char Key[256],oldKey[256]={},disp[80]="",ch[5][80];
int WINAPI WinMain( HINSTANCE , HINSTANCE , LPSTR , int )
{
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1;
SetDrawScreen( DX_SCREEN_BACK ) ;
White=GetColor(255,255,255);
style1_up();
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
for(j=0;j<256;j++){
if(oldKey[j]==0 && Key[j]==1)
Key[j]=2;
oldKey[j]=Key[j];
}
if(Key[KEY_INPUT_RETURN]==2){ // 前回押されてなくて、今回押されていたら
i=0; // iを初期値に戻し
ch_i++; // 表示する配列を1つずらす
if(ch_i==5) // これ以上表示する配列がなくなったらbreak;
break;
}
// 配列の終端-2以下で、今回コピーするiまでの配列要素のi番目が\0じゃなくカウンターが5の倍数なら
if(i<=80-2 && ch[ch_i][i]!='\0' && counter%5==0){
i+=2; // 全角文字なので配列要素2つずつカウントアップ
strncpy_s(disp,ch[ch_i],i);// iバイトまでの配列要素をdisp配列にコピー
disp[i]='\0'; // 終端記号を代入
}
DrawFormatString(10,420,White,"%s",disp);//disp配列の文字データを表示
counter++;
ScreenFlip() ;
}
DxLib_End() ;
return 0 ;
}
肝心の文章が表示されません。
Re: エラーが出て困っています。
A地区のch君、B地区のch君、style1_upさんお抱えの秘書chさん
の3人のうち、いなくなったのはB地区のch君だけです。
残る2人のうち、荷物S(文字列)を持っているのは
の3人のうち、いなくなったのはB地区のch君だけです。
残る2人のうち、荷物S(文字列)を持っているのは
- A地区のch君
- style1_upさんお抱えの秘書chさん
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: エラーが出て困っています。
マルチポストされているのでリンクします。
フォーラムルールに従って相互リンクをお願いします。
http://detail.chiebukuro.yahoo.co.jp/qa ... 1175937056
http://detail.chiebukuro.yahoo.co.jp/qa ... 1275938002
回答者の皆さんの意図が伝わっていない様ですね・・・。
フォーラムルールに従って相互リンクをお願いします。
http://detail.chiebukuro.yahoo.co.jp/qa ... 1175937056
http://detail.chiebukuro.yahoo.co.jp/qa ... 1275938002
回答者の皆さんの意図が伝わっていない様ですね・・・。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: エラーが出て困っています。
関数の外で宣言された変数は「グローバル変数」といって関数の中に入っても使えます。
しかし、関数の中で宣言された変数は「ローカル変数」といってその関数の中でしか使えないという制限があります。
しかし、関数の中で宣言された変数は「ローカル変数」といってその関数の中でしか使えないという制限があります。
Re: サウンドノベル風の文表示プログラム
サウンドノベル風の文表示プログラムを作っているのですが、
文章だけ、違うソースに書いて、それを読み込んで、表示したいと考えているのですが、
なかなかうまくいきません。
何か方法は、ないでしょうか・・・
文章だけ、違うソースに書いて、それを読み込んで、表示したいと考えているのですが、
なかなかうまくいきません。
何か方法は、ないでしょうか・・・
Re: エラーが出て困っています。
ファイル分割した場合の基本的なやり方がよく分かっていらっしゃらないようですので、単純な例を示します。
main.cppにあるmain関数から、message.cppにあるmsg変数を利用する、という場面を考えます。
ルートさんはC++でソースコードを書いているみたいですので、僕もC++で書きました。C++のヘッダファイルは.hppにすることがあります。
ここでのポイントは、グローバル変数msgをextern付きで宣言していることです。externを付けることによって、
「変数msgは、どこか他の場所で実体が定義されていますよー」ということになります。
externで宣言した場所には実体が生成されず、「実体はどこかにある」、という情報だけを表します。
変数msgの実体を定義しているのがmessage.cppです。extern無しでグローバル変数を宣言(これを定義といいます)すると、
実際にその場所に変数の実体が生成されます。
message.cppでは、#includeでmessage.hppを読み込んでいるため、実際には と書いたことと同じになります。
extern付きの宣言とextern無しの宣言が同じファイルに入っていた場合はextern無しの宣言が優先され
実体が生成されることになっていますので、心配要りません。
main.cppからmessage.cppにあるSetMessage関数とmsg変数を使っています。
message.hppを#includeすることによって、main.cppファイルに という宣言が取り込まれ、msg変数の実体がどこかにあるんだな、ということが分かるため、msg変数を利用することができるのです。
以上をまとめると
main.cppにあるmain関数から、message.cppにあるmsg変数を利用する、という場面を考えます。
// message.hpp
#ifndef MESSAGE_HPP_
#define MESSAGE_HPP_
extern char msg[];
void SetMessage(int message_id);
#endif // MESSAGE_HPP_
ここでのポイントは、グローバル変数msgをextern付きで宣言していることです。externを付けることによって、
「変数msgは、どこか他の場所で実体が定義されていますよー」ということになります。
externで宣言した場所には実体が生成されず、「実体はどこかにある」、という情報だけを表します。
// message.cpp
#include "message.hpp"
#include <cstring>
char msg[128];
void SetMessage(int message_id)
{
switch (message_id)
{
case 0: strcpy(msg, "msg0: hello"); break;
case 1: strcpy(msg, "msg1: world"); break;
}
}
実際にその場所に変数の実体が生成されます。
message.cppでは、#includeでmessage.hppを読み込んでいるため、実際には と書いたことと同じになります。
extern付きの宣言とextern無しの宣言が同じファイルに入っていた場合はextern無しの宣言が優先され
実体が生成されることになっていますので、心配要りません。
// main.cpp
#include "message.hpp"
#include <cstdio>
int main()
{
SetMessage(0);
puts(msg);
SetMessage(1);
puts(msg);
}
message.hppを#includeすることによって、main.cppファイルに という宣言が取り込まれ、msg変数の実体がどこかにあるんだな、ということが分かるため、msg変数を利用することができるのです。
以上をまとめると
- あるグローバル変数の実体を置くファイルは、どれか1つの.cppファイルにする。今回の例ではmain.cpp
- そのグローバル変数を、ヘッダファイルでextern宣言する。
- そのグローバル変数を使うすべての.cppファイルで、extern宣言が入ったヘッダファイルを#includeする。
Re: サウンドノベル風の文表示プログラム
この掲示板の下の方にある検索ボックスに「サウンドノベル風」と入力して検索すると幸せになれるかもしれません。ルート さんが書きました: サウンドノベル風の文表示プログラムを作っているのですが、
文章だけ、違うソースに書いて、それを読み込んで、表示したいと考えているのですが、
なかなかうまくいきません。
何か方法は、ないでしょうか・・・
Re: エラーが出て困っています。
ルートさんはC++でソースコードを書いているみたいですので、僕もC++で書きました。
自分はCの方はまだわかりますが、C++の方は勉強してないので全然です・・・・
自分はCの方はまだわかりますが、C++の方は勉強してないので全然です・・・・