The OpenNET Project / Index page

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




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
добавление к (char *) в конец (char), !*! NetKnight, 15-Сен-03, 17:10  [смотреть все]
Что-то после паскаля у меня проблемы со строками в сях :)
Вообщем нужно к строке добавить символ, правильно ли я делаю?

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

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

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

  • добавление к (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. Писать программы с их помощью не сложнее чем на паскале или перле.




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

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