- добавление к (char *) в конец (char), bogerm, 20:46 , 15-Сен-03 (1)
>Что-то после паскаля у меня проблемы со строками в сях :) >Вообщем нужно к строке добавить символ, правильно ли я делаю? > >char* chrcat(char *str, char chr) >{ > char *res=strdup(str); > res=(char *)realloc(res,sizeof(str)+1); > res[strlen(str)]=chr; > return res; >} > >Или я опять велосипед изобретаю и уже что-то сущевствует для этого? :) > Идея верная, но есть два замечания 1) Функция strdup создает копию строки, поэтому chrcat нельзя будет использовать для изменения исходной строки. Например str = strcat( str, 'a' ); вызовет утечку памяти, т.к. указатель на исходный str будет утерян. 2) В C/C++ принято соглашение, что все строки оканчиватся нулем: res[strlen(str)+1] = 0;Я бы написал эту функцию так: char* chrcat( char* str, char chr ) { register char *tmp=str; int len = strlen( str )+1; if ((tmp=(char*)realloc(tmp, len + 1) == NULL) return NULL; tmp[len-1] = chr; tmp[len] = 0; return tmp; } > >Ещё вопрос, как из строки вытащить нужную подстроку с определённой позиции по >другую определённую позицию? Перебирать как массив?
Например так: char *substr = (char*)malloc( end - begin + 1 ); strncpy( substr, str+begin, end-begin+1 );
- добавление к (char *) в конец (char), XMan, 02:47 , 16-Сен-03 (2)
> char *substr = (char*)malloc( end - begin + 1 ); > strncpy( substr, str+begin, end-begin+1 );Доработка: substr[end - begin]=0; Ибо после "malloc" в буфере будет неизвестно что (она же не очищает буфер), а функция "strncpy" не добавляет в конец строки 0, если такового не встречалось в исходной строке. Вопрошающему - при работе со строками уделяй большое внимание выделяемому под них буферу. Связано с тем, что формат строки в Паскале и в Си отличатеся в принципе. Паскаль: [1 байт - длина][до 255 байт - данные...] Си: [сколько хочешь байт - данные][1 байт - ограничитель строки '\0'] Дабы не попадать в "чужую" память и не вызывать "Segmentation fault" или не ловить в программе уязвимости, основанные на переполнении буфера (подавляющее большинство), всегда выделяй буфер на 1 байт больше нужного и заполняй этот байт (а лучше всю строку, ибо можно глюки ловить на ровном месте, если хитро с ней работать) нулями. Например, если ты ожидаешь получить максимум 1024 байт, выдели буфер длиной 1025 байт. PS. Под выражением "чужая память" я подразумевал память, которую система тебе не выделяла. Это совсем не означает, что ты залезешь в память соседней программы :)
- добавление к (char *) в конец (char), NetKnight, 03:13 , 16-Сен-03 (4)
>Вопрошающему - при работе со строками уделяй большое внимание выделяемому под них >буферу. Связано с тем, что формат строки в Паскале и в >Си отличатеся в принципе. >Паскаль: [1 байт - длина][до 255 байт - данные...] >Си: [сколько хочешь байт - данные][1 байт - ограничитель строки '\0'] Уже понял, здесь наверно строка роднится с Дельфийским PChar. Там тоже надо выделять память и она кончается символом '\0'. Жаль, что на паскале не пишут под юникса, там простые вещи делаются просто. :) >Дабы не попадать в "чужую" память и не вызывать "Segmentation fault" или >не ловить в программе уязвимости, основанные на переполнении буфера (подавляющее большинство), >всегда выделяй буфер на 1 байт больше нужного и заполняй этот >байт (а лучше всю строку, ибо можно глюки ловить на ровном >месте, если хитро с ней работать) нулями. Учту это. Насколько помню теорию - строка кончается, когда встречается первый символ "\0", а остальное игнорируется. Так? А когда вызывается strlen() и sizeof() - это правило тоже действует?
- добавление к (char *) в конец (char), XMan, 05:56 , 16-Сен-03 (6)
> А когда вызывается strlen() и sizeof() - это правило тоже действует?Это правило действует для любой строковой функции. sizeof - это не совсем функция. Ей фиолетово, что подсовывать. Она заменяется на нужное значение на этапе компиляции.
- добавление к (char *) в конец (char), messer, 08:56 , 16-Сен-03 (7)
>Дабы не попадать в "чужую" память и не вызывать "Segmentation fault" или >не ловить в программе уязвимости, основанные на переполнении буфера (подавляющее большинство), >всегда выделяй буфер на 1 байт больше нужного и заполняй этот >байт (а лучше всю строку, ибо можно глюки ловить на ровном >месте, если хитро с ней работать) нулями. >Например, если ты ожидаешь получить максимум 1024 байт, выдели буфер длиной 1025 >байт. хех, если программа узявима к переполнению буфера то добавляй ты хоть один, хотя два байта - это тебя не спасет (просто увеличишь переполняемый буыер). тем более если ты захочешь статически выделить 1025 байт (char str[1025]) gcc выделит не 1025 байт, а число кратное 32, т.е. в этом случае 1056 байт.
- добавление к (char *) в конец (char), NetKnight, 03:04 , 16-Сен-03 (3)
> register char *tmp=str; А что в этой строке обозначает register? Никогда не встречал.Вообще странно, что такие функции не написаны в стандартных библиотеках как раз для того, чтоб избежать ошибок :(
- добавление к (char *) в конец (char), bogerm, 04:58 , 16-Сен-03 (5)
>> register char *tmp=str; >А что в этой строке обозначает register? Никогда не встречал. Дает указание компилятору по возможности размещать переменную в регистре. В принципе совсем не обязательно, так как современные компиляторы часто сами размещают локальные переменные в регистрах при включенной оптимизации. Я это указываю чисто машинально по привычке. > >Вообще странно, что такие функции не написаны в стандартных библиотеках как раз >для того, чтоб избежать ошибок :( Для C++ есть много замечательных библиотек, таких как STL или Qt. Писать программы с их помощью не сложнее чем на паскале или перле.
|