Передача указателя на строку из массива
От: _aptyp_  
Дата: 17.08.03 12:14
Оценка:
char** split(char* src,char spl_ch)
{
    char ch;
    char* strs[20];
    int strs_cnt=0;

    int src_l=(int)strlen(src);

    int lbound=0;

    for (int i=0;i<src_l;i++)
    {
        ch=src[i];
        if (ch==spl_ch)
        {
            substr(&strs[strs_cnt],src,lbound,i);
            strs_cnt+=sizeof(char);
            lbound=i+1;
        }
    }
    return strs;
}

void substr(char* result[],char* src,int st,int end)
{
    if (end-st<=0) return;
    char buf[100];//=new char[100];//[100]={""};//end-st];
    int buf_cnt=0;
    for (int i=st;i<end;i++)
    {
        buf[buf_cnt]=src[i];
        buf_cnt++;
    }
    buf[end-st]='\0';
    //delete buf;
    *result=buf;
}


Почему в функции substr переменная buf не копируется в result по значению, а копируется по ссылке, т.е. в результате выполнения ф-ии split я получаю массив одинаковых значений? Или нужно специально выделять память в куче?
Re: Передача указателя на строку из массива
От: size_t Россия  
Дата: 17.08.03 12:58
Оценка:
> void substr(char* result[],char* src,int st,int end)
> {
> if (end-st<=0) return;
> char buf[100];//=new char[100];//[100]={""};//end-st];
> int buf_cnt=0;
> for (int i=st;i<end;i++)
> {
> buf[buf_cnt]=src[i];
> buf_cnt++;
> }
> buf[end-st]='\0';
> //delete buf;
> *result=buf;
> }
> [/ccode]
>
Здесь buf локальная переменная, память под которую выделена в стеке. Передавая указатель на нее за пределы функции он перестает быть валидным, так как по завершении функции, buf была удалена. Лучше буэт buf = new char[xxx];
А вообще, зачем изобретать велосипед. Для этого все уже написано и не раз. CRT — strcat, STL — string, ATL — CString
Posted via RSDN NNTP Server 1.7 beta
----------------
Нужное вписать.
Re[2]: Передача указателя на строку из массива
От: _aptyp_  
Дата: 19.08.03 14:05
Оценка:
_>Здесь buf локальная переменная, память под которую выделена в стеке. Передавая указатель на нее за пределы функции он перестает быть валидным, так как по завершении функции, buf была удалена. Лучше буэт buf = new char[xxx];
А что, нельзя из ф-ии передать переменную по значению, т.е. не по ссылке? Или обязательно использовать кучу или malloc?
_>А вообще, зачем изобретать велосипед. Для этого все уже написано и не раз. CRT — strcat, STL — string, ATL — CString
strcat — конкатенация, а мне надо разломать строку на подстроки, расположенные м-у опр. символом.
Re[3]: Передача указателя на строку из массива
От: cencio Украина http://ua-coder.blogspot.com
Дата: 19.08.03 15:48
Оценка: 14 (1) +1
Здравствуйте, _aptyp_, Вы писали:

_>>Здесь buf локальная переменная, память под которую выделена в стеке. Передавая указатель на нее за пределы функции он перестает быть валидным, так как по завершении функции, buf была удалена. Лучше буэт buf = new char[xxx];

__>А что, нельзя из ф-ии передать переменную по значению, т.е. не по ссылке? Или обязательно использовать кучу или malloc?

В С масивы по значению не передаются, когда ты передаеш масив в функцию то получаеш адрес его начала(весь код который ты привел выше можно считать написаным на чистом С(и лучшее что с ним можно сделать, это сразу выкинуть — посмотри внимательнее что возвращается из функции split, и как ты работаеш с указателями), поэтому для начала желательно временно забыть про такое понятие как "ссылка", оно тебя только запутывает, и помнить только об указателях и масивах. Потом тебе ОБЯЗАТЕЛЬНО НАДО прочитать главу из класической книги Кернигана и Ричи про работу со строками в С(то что доктор прописал ). Без понимания что такое указатели и масивы на С лучше не писать. Мне кажется все проблемы у тебя со строчкой
void substr(char* result[],char* src,int st,int end)
первый параметер наверное задумывался как строка, а получился массив строк , фактически char* result[] еквивалентно char**. и тогда *result=buf; просто запишет один указатель в первую позицию этого масива.

Насчет того как возвращать такие данные из функции — есть 2 варианта:
1. Можно передавать в функцию буффер(и его размер) в который она сможет записать результат
2. Можно всередине функции выделять память под возвращаемые параметры, но тогда надо не забывать ее освобождать после вызова, при таком подходе гарантирован поиск memory leaks в программе

_>>А вообще, зачем изобретать велосипед. Для этого все уже написано и не раз. CRT — strcat, STL — string, ATL — CString

__>strcat — конкатенация, а мне надо разломать строку на подстроки, расположенные м-у опр. символом.
посмотри библиотечную функцию strtok, она делает то что тебе нужно
Re[4]: Передача указателя на строку из массива
От: m.a.g. Мальта http://dottedmag.net/
Дата: 20.08.03 05:00
Оценка:
Здравствуйте, cencio, Вы писали:

_>>>А вообще, зачем изобретать велосипед. Для этого все уже написано и не раз. CRT — strcat, STL — string, ATL — CString

__>>strcat — конкатенация, а мне надо разломать строку на подстроки, расположенные м-у опр. символом.
C>посмотри библиотечную функцию strtok, она делает то что тебе нужно

Или взять что-нибудь более C++-ное. boost::tokenizer, к примеру.
... << RSDN@Home 1.1 beta 1 >>
Re: Передача указателя на строку из массива
От: matros Украина http://www.palmorder.com
Дата: 20.08.03 06:52
Оценка:
Здравствуйте, _aptyp_, Вы писали:

__>
__>char** split(char* src,char spl_ch)
__>{
__>    char ch;
__>    char* strs[20];
__>    int strs_cnt=0;

__>    int src_l=(int)strlen(src);

__>    int lbound=0;

__>    for (int i=0;i<src_l;i++)
__>    {
__>        ch=src[i];
__>        if (ch==spl_ch)
__>        {
__>            substr(&strs[strs_cnt],src,lbound,i);
__>            strs_cnt+=sizeof(char);
__>            lbound=i+1;
__>        }
__>    }
__>    return strs;
__>}

__>void substr(char* result[],char* src,int st,int end)
__>{
__>    if (end-st<=0) return;
__>    char buf[100];//=new char[100];//[100]={""};//end-st];
__>    int buf_cnt=0;
__>    for (int i=st;i<end;i++)
__>    {
__>        buf[buf_cnt]=src[i];
__>        buf_cnt++;
__>    }
__>    buf[end-st]='\0';
__>    //delete buf;
__>    *result=buf;
__>}
__>


__>Почему в функции substr переменная buf не копируется в result по значению, а копируется по ссылке, т.е. в результате выполнения ф-ии split я получаю массив одинаковых значений? Или нужно специально выделять память в куче?


Во-первых char* result[] — это массив строк, а char buf[100] — строка,
А если делать, как ты то примерно так:


char** split(char* src,char spl_ch)
{
    char ch;
    char* strs[20];
    int strs_cnt=0;

    int src_l=(int)strlen(src);
    int lbound=0;

    for (int i=0;i<src_l;i++)
    {
        ch=src[i];
        if (ch==spl_ch)
        {
            strcpy(strs[strs_cnt], substr(src,lbound,i));
            strs_cnt++;
            lbound=i+1;
        }
    }
    return strs;
}

char *substr(char* src,int st,int end)
{
    if (end-st<=0) return;
    char buf = new char*;
    int buf_cnt=0;
    for (int i=st;i<end;i++)
    {
        buf[buf_cnt]=src[i];
        buf_cnt++;
    }
    buf[end-st]='\0';
return buf;
}

ну или как-то так , исключив ошибки.
разница в том, что теперь substr() возвращает слово(строку), а в split() формируеться массив строк, в который и забрасываються слова. но все-равно это не самый лучший способ.

да и вообще тебе нужно почитать про указатели и работу с ними.
Re[2]: Передача указателя на строку из массива
От: _aptyp_  
Дата: 20.08.03 09:19
Оценка:
M>char *substr(char* src,int st,int end)
M>{
M> if (end-st<=0) return;
M> char buf = new char*;
M> int buf_cnt=0;
M> for (int i=st;i<end;i++)
M> {
M> buf[buf_cnt]=src[i];
M> buf_cnt++;
M> }
M> buf[end-st]='\0';
M>return buf;
M>}
M>[/ccode]

Сначала я как раз и пробовал так, а vc++ выдавал предупреждение, что типа в ф-ии идет возврат адреса. Но самое главное, что результат (в ф-ии split) точно такой же! Т.е. тот массив заполняется одинаковыми значениями.
Ну в общем я понял, что надо в ф-ии substr специально выделять память для buf. А где ее тогда освобождать?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.