大谷紀子さん著書の人工蜂コロニー(ABCアルゴリズム)の項目のソースコードを書き写しコンパイルしているのですがエラーが大量に出ています.誤字脱字は直しました
発生している問題・エラーメッセージ
g++ -o bee sample04.cpp sample04.cpp:10:25: warning: conversion from string literal to 'char *' is deprecated [-Wc++11-compat-deprecated-writable-strings] fSet = new FlowerSet("sampledata.csv"); ^ sample04.cpp:16:17: warning: illegal character encoding in string literal [-Winvalid-source-encoding] printf("%d<89><F1><96>ځF<8D>ŗǕ]<89><BF><92>l%f\n", i, fSet->bestValue); ^~~~~~~~~~~~ ~~~~ ~~~~~~~~~~~~ sample04.cpp:16:7: error: use of undeclared identifier 'printf' printf("%d<89><F1><96>ځF<8D>ŗǕ]<89><BF><92>l%f\n", i, fSet->bestValue); ^ 2 warnings and 1 error generated.
該当のソースコード
FlowerSet
1#include "FlowerSet.h" 2#pragma once 3#define filename data.txt 4//コントラスタ 5// filename: データセットのファイル名 6FlowerSet::Flower(char *filename){ 7 int i,best; 8 9 dataset=new Dataset(filename); 10 flower=new Flower* [EBEE_NUM]; 11 best=0; 12 13 for(i=0;i<EBEE_NUM;i++){ 14 flower[i]=new Flower(this); 15 if(flower[best]->value>flower[i]->value){ 16 best=i; 17 } 18 } 19 bestPos=new double[dataset->exVarNum]; 20 for(i=0;i<dataset->exVarNum;i++){ 21 bestPos[i]=flower[best]->pos[i]; 22 } 23 bestValue=flower[best]->value; 24 newFlower=new Flower(this); 25 trValue=new double[EBEE_NUM]; 26} 27 28//デストラクタ 29FlowerSet::~FlowerSet(){ 30 int i; 31 32 for(i=0;i<EBEE_NUM;i++){ 33 delete flower[i]; 34 } 35 delete [] flower; 36 delete [] bestPos; 37 delete newFlower; 38 delete [] trValue; 39 delete dataset; 40 41 //収穫蜂フェーズを実行する 42 void FlowerSet::employedBeePhase() 43 { 44 int i; 45 Flower *tmp; 46 47 for(i=0;i<EBEE_NUM;i++){ 48 newFlower->change(i); 49 if(flower[i]-> value > newFlower -> value){ 50 tmp=newFlower; 51 newFlower=flower[i]; 52 flower[i]=tmp; 53 } 54 flower[i]->visitNum++; 55 } 56 } 57 //追従蜂フェーズを実行する 58 void FlowerSet::onlookerBeePhase() 59 { 60 int i,j; 61 Flower *tmp; 62 double max,min,denom,prob,r; 63 64 for(j=0;j<OBEE_NUM;j++){ 65 //評価値を変換する 66 max=DBL_MIN; 67 min=DBL_MAX; 68 for(i=0;i<EBEE_NUM;i++){ 69 if(max<flower[i]->value){ 70 max=flower[i]->value; 71 } 72 if(min<flower[i]->value){ 73 min=flower[i]->value; 74 } 75 } 76 denom=0.0; 77 for(i=0;i<EBEE_NUM;i++){ 78 trValue[i]=(max-flower[i]->value)/(max-min); 79 denom+=trValue[i]; 80 } 81 82 //収穫蜂を選択する 83 r=RAND_01; 84 for(i=0;i<EBEE_NUM-1;i++){ 85 prob=trValue[i]/denom; 86 if(r<=prob){ 87 break; 88 } 89 r -=prob; 90 } 91 92 //収穫蜂フェーズと同様に処理する 93 newFlower->change(i); 94 if(flower[i]->value>newFlower->value){ 95 tmp=newFlower; 96 newFlower=flower[i]; 97 flower[i]=tmp; 98 } 99 flower[i]->visitNum++; 100 } 101 } 102 103 //偵察蜂フェーズを実行する 104 void FlowerSet::scoutBeePhase() 105 { 106 int i; 107 for (i=0;i<EBEE_NUM;i++){ 108 if(VISIT_MAX<=flower[i]->visitNum){ 109 flower[i]->renew(); 110 } 111 } 112 } 113 114 //最良食糧源を記録する 115 void FlowerSet::saveBestPos() 116 { 117 int i,best; 118 119 best= -1; 120 for(i=0;i<EBEE_NUM;i++){ 121 if(bestValue>flower[i]->value){ 122 best=i; 123 } 124 } 125 if(best!=-1){ 126 for(i=0;i<dataset->exVarNum;i++){ 127 bestPos[i]=flower[best]->value; 128 } 129 bestValue=flower[best]->value; 130 } 131 } 132 //結果を表示する 133 void FlowerSet::printResult() 134 { 135 dataset->setCoef(bestPos); 136 dataset->printEquation(); 137 } 138 139 140
Flower
1//Flower.h 2#ifndef INCLUDED_FLOWER 3#define INCLUDED_FLOWER 4#include "DataSet.h" 5#include "FlowerSet.h" 6#pragma once 7class FlowerSet; 8 9//定数の定義 10#define REPEAT_NUM 1000 //繰り返し数 11#define EBEE_NUM 100 //収穫蜂の数 12#define OBEE_NUM 10 //追従蜂の数 13#define VISIT_MAX 10 //蜜の採取可能回数 14#define COEF_MIN -1 //標準偏回帰係数の最小値 15#define COEF_MAX 1 //標準偏回帰係数の最大値 16 17//0以上1以下の実数乱数 18#define RAND_01 ((double)rand() / RAND_MAX) 19 20class Flower{ 21public: 22 Flower(FlowerSet *argFSet); 23 ~Flower(); 24 void change(int base); //近くの食糧源に変更する 25 void renew();//新しい食糧源に変更する. 26 27 FlowerSet *fSet; //属している食糧源集合 28 double *pos; //位置 29 double value;//評価値 30 int visitNum;//蜜の採取回数 31 32private: 33 void evaluate();//評価値を算出する 34}; 35#endif
Flower
1//Flower.cpp 2#include "Flower.h" 3#pragma once 4 5//コントラスた 6//argFSet:属している食糧源集合 7 8Flower::Flower(FlowerSet *argFSet){ 9 int i; 10 11 fSet=argFSet; 12 pos=new double[fSet->dataset->exVarNum]; 13 for(i=0;i<fSet->dataset->exVarNum;i++){ 14 pos[i]=COEF_MIN+(COEF_MAX-COEF_MIN)*RAND_01; 15 } 16 visitNum=0; 17 evaluate(); 18} 19 20//デストラクタ 21Flower::~Flower(){ 22 delete[]pos; 23} 24//baseの近くの食糧源に変更する 25//base:元にする食糧源の添字 26void Flower::change(int base){ 27 int i,j; 28 29 for(i=0;i<fSet->dataset->exVarNum;i++){ 30 pos[i]=fSet->flower[base]->pos[i]; 31 } 32 i=rand() % fSet->dataset->exVarNum; 33 j=(base+(rand() % (EBEE_NUM-1)+1)) % EBEE_NUM; 34 pos[i]=pos[i]+(rand() / (RAND_MAX/2.0)-1)*(pos[i]-fSet->flower[j]->pos[i]); 35 visitNum=0; 36 evaluate(); 37} 38 39//新しい食糧源に変更する 40void Flower::renew(){ 41 int i; 42 for(i=0;i<fSet->dataset->exVarNum;i++){ 43 pos[i]=COEF_MIN+(COEF_MAX - COEF_MIN)*RAND_01; 44 } 45 visitNum=0; 46 evaluate(); 47} 48 49//評価値を算出する 50void Flower::evaluate(){ 51 int i,j; 52 double diff; 53 54 value=0.0; 55 for(i=0;i<fSet->dataset->dataNum;i++){ 56 diff=fSet->dataset->resSData[i]; 57 for(j=0;j<fSet->dataset->exSData[i][j];j++){ 58 diff -= pos[j]*fSet->dataset->exSData[i][j]; 59 } 60 value += pow(diff,2.0); 61 } 62} 63
FlowerSet
1//FlowerSet.h 2#ifndef INCLUDED_FLOWERSET 3#define INCLUDE_FLOWERSET 4#include "Flower.h" 5#pragma once 6class Flower; 7 8class FlowerSet 9{ 10public: 11 FlowerSet(char *filename); 12 ~FlowerSet(); 13 void employedBeePhase(); //収穫蜂フェーズを実行する 14 void onlockerBeePhase();//追従蜂フェーズを実行する 15 void scoutBeePhase();//偵察蜂フェーズを実行する. 16 void saveBestPos();//最良食糧源を記録する. 17 void printResult();//結果を表示する. 18 19 Dataset *dataset;//データセット 20 Flower **flower;//食糧源の集合のメンバ 21 double *bestPos;//最良食糧源の位置 22 double bestValue;//最良食糧源の評価値 23 24private: 25 Flower *newFlower; //新しい食糧源 26 double *trValue; //格食糧源の変換後の評価値 27}; 28 29#endif 30 31
試したこと
著書には載っていませんでしたがインクルードガードなどは行いました
補足情報(FW/ツールのバージョンなど)
環境は
macbook pro macOS BigSur ver.11.4
コンパイラ環境はEmacsです
ヘッダ: FlowerSet.h も見せておくれ
#ifndef INCLUDED_FLOWERSET
#define INCLUDE_FLOWERSET
#include "Flower.h"
#pragma once
class Flower;
class FlowerSet
{
public:
FlowerSet(char *filename);
~FlowerSet();
void employedBeePhase(); //収穫蜂フェーズを実行する
void onlockerBeePhase();//追従蜂フェーズを実行する
void scoutBeePhase();//偵察蜂フェーズを実行する.
void saveBestPos();//最良食糧源を記録する.
void printResult();//結果を表示する.
Dataset *dataset;//データセット
Flower **flower;//食糧源の集合のメンバ
double *bestPos;//最良食糧源の位置
double bestValue;//最良食糧源の評価値
private:
Flower *newFlower; //新しい食糧源
double *trValue; //格食糧源の変換後の評価値
};
#endif
お願いします
ダメでしょコレ。
Flower.h に class Flower が定義されてるはず。にもかかわらず class Flower; してるから多重定義。
> 著書には載っていませんでしたがインクルードガードなどは行いました
#pragma once がインクルード・ガードだからやんなくていい。
あと
> //コントラスタ
> // filename: データセットのファイル名
> FlowerSet::Flower(char *filename){
いきなりマチガイ。コンストラクタなら FlowerSet::FlowerSet(...
#ifndef INCLUDED_FLOWER
#define INCLUDED_FLOWER
#include "DataSet.h"
#include "FlowerSet.h"
#pragma once
class FlowerSet;
//定数の定義
#define REPEAT_NUM 1000 //繰り返し数
#define EBEE_NUM 100 //収穫蜂の数
#define OBEE_NUM 10 //追従蜂の数
#define VISIT_MAX 10 //蜜の採取可能回数
#define COEF_MIN -1 //標準偏回帰係数の最小値
#define COEF_MAX 1 //標準偏回帰係数の最大値
//0以上1以下の実数乱数
#define RAND_01 ((double)rand() / RAND_MAX)
class Flower{
public:
Flower(FlowerSet *argFSet);
~Flower();
void change(int base); //近くの食糧源に変更する
void renew();//新しい食糧源に変更する.
FlowerSet *fSet; //属している食糧源集合
double *pos; //位置
double value;//評価値
int visitNum;//蜜の採取回数
private:
void evaluate();//評価値を算出する
};
#endif
flower.hです.確かに20行目で定義されていると思います.どうすればいいでしょうか.
だからそいつは質問に追記して。質問は編集できるから。
> どうすればいいでしょうか.
FlowerSet.h 内の class Flower; が余分なのでは?
今追記しました.
5行目のclass Flower;を消すということで大丈夫ですか?
やってみたらわかる。いちいち許可をもらわんでよろし。
> ソースコードを書き写し
https://www.ohmsha.co.jp/book/9784274222382/#tab3
からダウンロードしてます?
書籍に記載のコードを、こんなに載せちゃってもいいの?
それは知りませんでした.
ありがとうございました.
g++ -o bee sample04.cpp
sample04.cpp:10:25: warning: conversion from string literal to 'char *' is deprecated [-Wc++11-compat-deprecated-writable-strings]
fSet = new FlowerSet("sampledata.csv");
^
sample04.cpp:16:17: warning: illegal character encoding in string literal [-Winvalid-source-encoding]
printf("%d<89><F1><96>ځF<8D>ŗǕ]<89><BF><92>l%f\n", i, fSet->bestValue);
^~~~~~~~~~~~ ~~~~ ~~~~~~~~~~~~
sample04.cpp:16:7: error: use of undeclared identifier 'printf'
printf("%d<89><F1><96>ځF<8D>ŗǕ]<89><BF><92>l%f\n", i, fSet->bestValue);
^
2 warnings and 1 error generated.
こんなエラーが発生しています.
元質問も変えます.
https://www.ohmsha.co.jp/book/9784274222382/#tab3
からダウンロードしたソースファイルはシフトJISのファイルなので、Macでコンパイルする場合は、もしかしたらUTF-8とかに変換しないとダメかもしれない (よく知らない)
参考
https://qiita.com/mm_sys/items/7b8b415a54d1cd0caa5e
https://social.msdn.microsoft.com/Forums/ja-JP/62164982-9795-4f5a-bd7c-85ec121f9126/mac
DataSet.cpp と sample04.cpp に #include <cstdio> を追加。
clang: error: no input files
というエラーが出ます
> clang: error: no input files
何をしたのでしょうか?
ソースコードファイルに「#include...」を追記したり、ソースコードファイルの文字コード(シフトJISとか)を変換して保存し直したりしただけでは、上記のようにはならないはず
下記のようなことをしてませんか?
・ソースコードファイルが置いてある場所ではない場所がカレントディレクトリになってる状態でコンパイルしようとした
・コンパイル時に指定したソースコードファイルの名前が違う
・ソースコードファイルを指定せずにコンパイラのコマンドだけ実行した
g++ -o sample04.cpp
このように実行しています
僕とこ(Win10/Visual C++)ではコンパイル/実行できました。
sampledata.csvがないのであっけなく停止するけど。
> g++ -o sample04.cpp
それじゃダメ。
g++ -o sample4 *.cpp
コマンドを実行したところsample4という実行ファイルができました.
./sample4とターミナルで打ち込みましたがzsh: segmentation fault ./sample4が出てしまいました.
コマンドが違いますか?
"sampledata.csvが開けません"で終了しませんか? 僕とこと挙動が異なるな...
> zsh: segmentation fault ./sample4
当方のMacで、ダウンロードしたソースに
> DataSet.cpp と sample04.cpp に #include <cstdio> を追加。
を行い、文字コードの変換はしないで、
g++ -o sample4 *.cpp
を実行して、できた「sample4」を
./sample4
で実行したら、「sampledata.csv???J???܂???D」と表示されました
ソースコードの文字コードがシフトJISだからですね
そこで、
./sample4 | nkf -w
と、結果表示をUTF-8に変換したら、「sampledata.csvが開けません.」と表示されました
【追記】 ただし、当方のMacのxcodeは古いです (OSが古いので)
gcc -v
...
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
utf-8に変換した後,g++ -o sample4 *.cppを実行し./sample4を実行しました.
文字化けに関する警告は無くなりました.しかし,zsh: segmentation fault ./sample4も残っています.
当方のMacで、ダウンロードしたソースに
> DataSet.cpp と sample04.cpp に #include <cstdio> を追加。
を行い、全ファイルの文字コードを「nkf -w 」でUTF-8に変換し、
g++ -o sample4 *.cpp
を実行して、できた「sample4」を
./sample4
で実行したら、「sampledata.csvが開けません.」と表示されました
「segmentation fault」にはなりません
違いは何でしょうね?
たとえば、
https://qiita.com/monhan/items/ea7e642b91392bfce8a6
や
https://perogram.hateblo.jp/entry/visual_studio_code_mac
に載ってるような簡単なコードをコンパイルして実行したら、正常に実行できるのですよね?
> 以下の警告が残っていました
それはこちらでも出ます (ソースコードファイルの文字コードに関係なく)
参考
https://teratail.com/questions/9652
もし「sampledata.csv」を用意して実行していたら、そのファイルが無い状態で実行してみてください
sampledata.csvが原因のようです.sampledata.csvを同じフォルダに入れておかなければ開けませんと出ます.しかし同じフォルダに入れておくとsegmentation faultが出ます
質問に使用しているファイルのスクショを貼りました.これは.txtファイルですが実際は.csvを使ってます.
現在発生している警告文です.
sample04.cpp:11:25: warning: conversion from string literal to 'char *' is deprecated [-Wc++11-compat-deprecated-writable-strings]
fSet = new FlowerSet("sampledata.csv");
^
↑ コンストラクタ引数にconstつけて FlowerSet::FlowerSet(const char* ... としろ、ってことやろね。
CSVの最後の行も改行してください
最後の行だけ改行してないのでは?
> 現在発生している警告文です.
いやだから、それは上のコメントに書いたように、「segmentation fault」とは関係ないですって
参考に挙げたteratailの過去質問の回答を読んでください
元質問に.csvのスクショを追加しました.
作り直しましたがだめでした.
当方では、CSVの最後の行を改行してない状態では、「Segmentation fault」になりました
最後の行も改行したら、「Segmentation fault」にならず、計算されました
最後の行も改行する、というのは、テキストエディットでCSVファイルを開いたら、数字が記入されてる最後の行の一つ下の一番左にカーソルがある状態になる、ということです
質問に挙げた画像の場合なら、「5.36」の下の一番左にカーソルを持ってこれる、という状態です
ちなみに、CSVファイルの最後の改行はたくさんあっても大丈夫なので、数字が記入されてる最後の行の下に、何回か改行のみ追加してみてください
できました!
お二方とも詳しくありがとうございました!
回答3件
あなたの回答
tips
プレビュー

