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 я получаю массив одинаковых значений? Или нужно специально выделять память в куче?
> 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
_>Здесь buf локальная переменная, память под которую выделена в стеке. Передавая указатель на нее за пределы функции он перестает быть валидным, так как по завершении функции, buf была удалена. Лучше буэт buf = new char[xxx];
А что, нельзя из ф-ии передать переменную по значению, т.е. не по ссылке? Или обязательно использовать кучу или malloc? _>А вообще, зачем изобретать велосипед. Для этого все уже написано и не раз. CRT — strcat, STL — string, ATL — CString
strcat — конкатенация, а мне надо разломать строку на подстроки, расположенные м-у опр. символом.
Здравствуйте, _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, она делает то что тебе нужно
Здравствуйте, cencio, Вы писали:
_>>>А вообще, зачем изобретать велосипед. Для этого все уже написано и не раз. CRT — strcat, STL — string, ATL — CString __>>strcat — конкатенация, а мне надо разломать строку на подстроки, расположенные м-у опр. символом. C>посмотри библиотечную функцию strtok, она делает то что тебе нужно
Или взять что-нибудь более C++-ное. boost::tokenizer, к примеру.
__>Почему в функции 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() формируеться массив строк, в который и забрасываються слова. но все-равно это не самый лучший способ.
да и вообще тебе нужно почитать про указатели и работу с ними.
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. А где ее тогда освобождать?