0

この投稿は、ここで与えられたソリューション、SO に関する投稿に基づいています。

次のような、特定のファイル拡張子 (文字列型) を取得する関数を作成します。

void GetFileExtension(string filename, char* extension)
{
    vector<string> rec;

    StrDelimit(filename, '.', rec);

    //cout << rec[rec.size()-2].c_str()[1] << endl;

    //extension = rec[rec.size()-2].c_str()[0];

    //extension = &rec[rec.size()-2].c_str()[0];

    string str = rec[rec.size()-2];

    // conversion from string to char*
    vector<char> writable(str.size() + 1);

    std::copy(str.begin(), str.end(), writable.begin());

    //cout << writable << endl;

    extension = &writable[0];
}

StrDelimit は、文字列を受け取り、指定された区切り文字で部分文字列のベクトルに区切ります。

示されているように、「//string から char* への変換」を使用して、呼び出し元のメイン プログラムに結果を返します。

コンパイル エラーはありませんが、結果は無意味な文字列になります。何が問題なの?

どんな助けでも大歓迎です!

ありがとうございました!

4

4 に答える 4

1

char *extension は、文字列のアドレスの一時的なコピーです。実際に新しいデータを入れるには、保持しているアドレスにデータをコピーする必要があります。

これは役に立ちますか?

#include <stdio.h>
#include <string.h>

void getStringInoExistingBufer(char* existingBufferOut)
{
    strcpy(existingBufferOut, "someData");
}

void getStringIntoNonExistingBuffer(char **newBufferOut)
{
    *newBufferOut = strdup("someOtherData");
}

int main()
{
    char buffer1[100] = {};
    char *buffer2 = NULL;

    printf("buffer1 (before): '%s'\n", buffer1);
    getStringInoExistingBufer(buffer1);
    printf("buffer1 (after): '%s'\n", buffer1);

    printf("\n\n");
    printf("buffer2 (before): '%s'\n", buffer2);
    getStringIntoNonExistingBuffer(&buffer2);
    printf("buffer2 (after): '%s'\n", buffer2);
}

出力:

buffer1 (before): ''
buffer1 (after): 'someData'


buffer2 (before): '(null)'
buffer2 (after): 'someOtherData'
于 2013-02-24T07:58:02.853 に答える
0

あなたの問題はwritable、スタック上にデータメンバーを作成し、それを指すことextensionですが、書き込み可能なスコープは、関数が返されたときにwritableクリアされ、extension何も指していないことを意味する関数です。

char* に動的バッファーを割り当てることができますが、それは C++ よりも C のアプローチです。可能であれば、関数の型を文字列またはベクトルを返すように変更することをお勧めします。これにより、はるかに簡単になります。これらの型は、必要に応じて char* に変更できます。

于 2013-02-24T07:47:42.903 に答える
0

拡張子を として返さないのはなぜstd::stringですか?

例えば:

std::string GetFileExtension(std::string filename)
{
    std::vector<string> rec;

    StrDelimit(filename, '.', rec);

    std::string extension = rec[rec.size() - 2];
    return extension;
}
于 2013-02-24T07:48:27.343 に答える
0

まず、実際には何も返していません。

void GetFileExtension(string filename, char* extension)
{
    ...
    extension = &writable[0];  // Assignment to local variable
}

に渡された char* を更新する場合はextension、それを として渡す必要がありますchar**(つまり、 へのポインタchar*)。

第二に、それを修正したとしても、ローカル変数のデータへのポインターを返そうとしています。

void GetFileExtension(string filename, char* extension)
{
    ...
    vector<char> writable(str.size() + 1);   // Local variable
    ...
    extension = &writable[0];       // writable disappears after this line
                                    // and extension will point to invalid memory
}

を返すだけでstd::string、コードがかなり簡素化されます。

于 2013-02-24T07:49:13.990 に答える