The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"добавление к (char *) в конец (char)"
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"добавление к (char *) в конец (char)"
Сообщение от NetKnight emailИскать по авторуВ закладки on 15-Сен-03, 17:10  (MSK)
Что-то после паскаля у меня проблемы со строками в сях :)
Вообщем нужно к строке добавить символ, правильно ли я делаю?

char* chrcat(char *str, char chr)
{
char *res=strdup(str);
res=(char *)realloc(res,sizeof(str)+1);
res[strlen(str)]=chr;
return res;
}

Или я опять велосипед изобретаю и уже что-то сущевствует для этого? :)

Ещё вопрос, как из строки вытащить нужную подстроку с определённой позиции по другую определённую позицию? Перебирать как массив?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "добавление к (char *) в конец (char)"
Сообщение от bogerm emailИскать по авторуВ закладки on 15-Сен-03, 20:46  (MSK)
>Что-то после паскаля у меня проблемы со строками в сях :)
>Вообщем нужно к строке добавить символ, правильно ли я делаю?
>
>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 );

  Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "добавление к (char *) в конец (char)"
Сообщение от XMan Искать по авторуВ закладки on 16-Сен-03, 02:47  (MSK)
> 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. Под выражением "чужая память" я подразумевал память, которую система тебе не выделяла. Это совсем не означает, что ты залезешь в память соседней программы :)

  Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "добавление к (char *) в конец (char)"
Сообщение от NetKnight emailИскать по авторуВ закладки on 16-Сен-03, 03:13  (MSK)
>Вопрошающему - при работе со строками уделяй большое внимание выделяемому под них
>буферу. Связано с тем, что формат строки в Паскале и в
>Си отличатеся в принципе.
>Паскаль: [1 байт - длина][до 255 байт - данные...]
>Си: [сколько хочешь байт - данные][1 байт - ограничитель строки '\0']

Уже понял, здесь наверно строка роднится с Дельфийским PChar. Там тоже надо выделять память и она кончается символом '\0'. Жаль, что на паскале не пишут под юникса, там простые вещи делаются просто. :)

>Дабы не попадать в "чужую" память и не вызывать "Segmentation fault" или
>не ловить в программе уязвимости, основанные на переполнении буфера (подавляющее большинство),
>всегда выделяй буфер на 1 байт больше нужного и заполняй этот
>байт (а лучше всю строку, ибо можно глюки ловить на ровном
>месте, если хитро с ней работать) нулями.

Учту это. Насколько помню теорию - строка кончается, когда встречается первый символ "\0", а остальное игнорируется. Так? А когда вызывается strlen() и sizeof() - это правило тоже действует?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "добавление к (char *) в конец (char)"
Сообщение от XMan Искать по авторуВ закладки on 16-Сен-03, 05:56  (MSK)
> А когда вызывается strlen() и sizeof() - это правило тоже действует?

Это правило действует для любой строковой функции.

sizeof - это не совсем функция. Ей фиолетово, что подсовывать. Она заменяется на нужное значение на этапе компиляции.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

7. "добавление к (char *) в конец (char)"
Сообщение от messer Искать по авторуВ закладки on 16-Сен-03, 08:56  (MSK)
>Дабы не попадать в "чужую" память и не вызывать "Segmentation fault" или
>не ловить в программе уязвимости, основанные на переполнении буфера (подавляющее большинство),
>всегда выделяй буфер на 1 байт больше нужного и заполняй этот
>байт (а лучше всю строку, ибо можно глюки ловить на ровном
>месте, если хитро с ней работать) нулями.
>Например, если ты ожидаешь получить максимум 1024 байт, выдели буфер длиной 1025
>байт.

хех, если программа узявима к переполнению буфера то добавляй ты хоть один, хотя два байта - это тебя не спасет (просто увеличишь переполняемый буыер). тем более если ты захочешь статически выделить 1025 байт (char str[1025]) gcc выделит не 1025 байт, а число кратное 32, т.е. в этом случае 1056 байт.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "добавление к (char *) в конец (char)"
Сообщение от NetKnight emailИскать по авторуВ закладки on 16-Сен-03, 03:04  (MSK)
>  register char *tmp=str;
А что в этой строке обозначает register? Никогда не встречал.

Вообще странно, что такие функции не написаны в стандартных библиотеках как раз для того, чтоб избежать ошибок :(

  Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "добавление к (char *) в конец (char)"
Сообщение от bogerm emailИскать по авторуВ закладки on 16-Сен-03, 04:58  (MSK)
>>  register char *tmp=str;
>А что в этой строке обозначает register? Никогда не встречал.

Дает указание компилятору по возможности размещать переменную в регистре.
В принципе совсем не обязательно, так как современные компиляторы часто сами размещают локальные переменные в регистрах при включенной оптимизации. Я это указываю чисто машинально по привычке.

>
>Вообще странно, что такие функции не написаны в стандартных библиотеках как раз
>для того, чтоб избежать ошибок :(

Для C++ есть много замечательных библиотек, таких как STL или Qt. Писать программы с их помощью не сложнее чем на паскале или перле.

  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру