0

ある関数から次の関数にchar配列である変数を渡すことに関して質問があります。

関連するコードのサンプルは次のとおりです。

int main( int argc, char** argv )
{

int value = 0;

int nCounter = 0;
FILE* fIn = NULL;
char * sLine = new char[MAX_FILENAME_SIZE];
char * sFileName = new char [MAX_FILENAME_SIZE];
char * s = new char [MAX_FILENAME_SIZE];



if ((fIn = fopen(ImgListFileName,"rt"))==NULL)

{
    printf("Failed to open file: %s\n",ImgListFileName);
    return nCounter;
}



while(!feof(fIn)){

//set the variables to 0
memset(sLine,0,MAX_FILENAME_SIZE*sizeof(char));
memset(sFileName,0,MAX_FILENAME_SIZE*sizeof(char));
memset(s,0,MAX_FILENAME_SIZE*sizeof(char));
//read one line (one image filename)
//sLine will contain one line from the text file
fgets(sLine,MAX_FILENAME_SIZE,fIn);
//copy the filename into variable s
strncpy(s, sLine, strlen(sLine)-1);
//put a \0 character at the end of the filename
strcat(sLine,"\0");
//create the filename
strcat(sFileName,s);

nCounter++;


fclose(fIn);
delete sLine;
delete sFileName;
delete s;
    const int size = 60;
    char path[size] = "path";
    strcat(path,sFileName);

    printf (path);
IplImage *img = cvLoadImage(path);
detect_and_draw(img);
cvWaitKey();
cvReleaseImage(&img);
cvDestroyWindow("result");

void detect_and_draw( IplImage* img )
{


More code that isn't involved....


cvSaveImage(sFileName, img);

今、私は以下を試しました:

void getFilename(char * sFileName)
{
    printf("The filename is %s\n", sFileName);
    return;
}

そして、

char * S ="string"
getFilename(S);
cvSaveImage(S,img);

ただし、「string」は「The filename is:string」に配置されます。

cvSaveImage(sFileName、img)でchar配列であるsFileNameを使用できるようにするにはどうすればよいですか?

よろしくお願いします。さらに詳しい説明が必要な場合は、お問い合わせください。

4

2 に答える 2

2

未定義の動作、不要な動的割り当てなどを無視すると、達成しようとしているように見えることは、この一般的な順序で要約されます。

std::string path;

while (std::getline(fIn, path)) {
    std::cout << "path: " << path;

    IplImage *img = cvLoadImage(path.c_str());

    detect_and_draw(img, path);
    cvWaitKey();
    cvReleaseImage(&img);

    cvDestroyWindow("result");    
}

void detect_and_draw(IpImage *img, std::string const &path) { 
// ...
    cvSaveImage(path.c_str(), img);
}

私はそれとは少し違うことをするだろうと思います-おそらくImageクラスから始めて、次のようなものです:

class Image { 
    IpImage *img;
    std::string path;

public:
    Image(std::string const &name) : 
        img(cvLoadImage(name.c_str()), path(name) 
    { }

    ~Image() { cvReleaseImage(&img); }

    void detect_and_draw() { 
         // ...
         cvSaveImage(path);
    }
};

これを使用すると、コードは次のようになります。

while (std::getline(fIn, path)) {
    Image img(path);
    img.detect_and_draw();
    cvWaitKey();
    cvDestroyWindow("result");
}

完全には明確ではありませんがcvDestroyWindow、実際にはデストラクタに属するもののように聞こえますが、これらの要素がどのように組み合わされて、どのデストラクタ(おそらくは別のもの)であるかを確認するのに十分な確信がありImageません。

detect_and_draw「このコードは単一責任の原則を無視している」と事実上叫んでいることに注意してください。名前には2つの責任が記載されており、少なくとも3分の1(ファイルの保存)もあるようです。

于 2012-07-24T20:30:56.333 に答える
1

私が正しく理解しているなら、あなたが持っているのはスコーピングの問題です。あなたは本質的に持っています:

int main(/* */)
{ char sFileName[MAX_FILENAME_SIZE];

  /* code to initialize sFileName to contain a value */

  detect_and_draw(img);
}

void detect_and_draw(IplImage *img)
{ cvSaveImage(sFileName, img);
}

問題は、sFileNameにローカルでmain()あり、ではアクセスできないことdetect_and_draw()です。detect_and_draw()2番目の引数を取るように変更することができます。

int main()
{ /* stuff */
  detect_and_draw(img, sFileName);
}
void detect_and_draw(IplImage *img, const char* fn)
{ cvSaveImage(fn, img);
}

または、sFileNameを-の範囲外で宣言/定義されたグローバル変数にします。main()ただし、これは劣ったソリューションと見なされることがよくあります。

于 2012-07-24T20:21:33.457 に答える