2013-02-24 4 views
0

этот пост основы на решение данной here, пост на 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 отлично работает уже который принимает строку и разграничивает вектор подстрок по заданному разделителю

я использую «// преобразование из строки на символ *», как показано, чтобы вернуть результат вызова основной программы

Ошибка компиляции, но результат представляет собой строку бессмысленных символов. В чем проблема?

любая помощь будет оценена!

Спасибо!

ответ

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' 
+0

спасибо за полный ответ :) –

0

вашей проблемы вы создание элемента writable данных в стек, а затем указать на него с extension НО объемом записываемой функция означает, что, когда функция возвращает writable будет очищен не оставляя extension указывая ничего.

вы можете выделить динамический буфер для символа char *, но это более подход C, чем C++. Если возможно, я бы рекомендовал изменить тип функции, чтобы вернуть строку или вектор, который сделает ее намного проще, и вы можете изменить эти типы на char * при необходимости.

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; 
} 
+0

спасибо! это было то, что я на самом деле сделал после сообщения –

0

Во-первых, вы на самом деле не возвращающей ничего;

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

Если вы собираетесь обновить символ *, переданный в 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 бы упростить код совсем немного.

Смежные вопросы