LINUX.ORG.RU

Ответ на: комментарий от anonymous

> таки НЕ работает :^( сегфолтитцца

:(

Из man strcat:

... The strings  may not overlap,...

Глупость какая! Не ожидал...

Тогда только так:

(char*)memmove(str+firstchar,str+firstchar+count)-firstchar

Самому проще налабать:

char *delete(char *str, int firstchar, int count)
{
char *tmp=str+firstchar;
   while(*tmp=*(tmp+count))tmp++;
   return str;
}

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

> strcat(str+firstchar, str+firstcahr+count);

так нельзя хотя бы потому что у strcat аргументы декларированы restrict

ну и вместо strcat что-то вроде strcpy должно стоять, но там тоже restrict.

dilmah ★★★★★
()
Ответ на: комментарий от Die-Hard

>Из man strcat: >... The strings may not overlap,... >Глупость какая! Не ожидал...

На таких глупостях держится мир ;).

Смешно наблюдать, как неофиты ходят по тем же граблям, что и 15 лет назад ;)

anonymous
()

А вообще, если можно использовать С++, то используй класс std::string. Там реализовано все необходиоме дляработы со строками.

ilich
()
Ответ на: комментарий от Die-Hard

> char *delete(char *str, int firstchar, int count)

>{

>char *tmp=str+firstchar;

> while(*tmp=*(tmp+count))tmp++;

> return str;

>}

за такие функции увольнять надо. она совершенно небезопасная

anonymous
()
Ответ на: комментарий от anonymous

anonymous (*) (12.05.2005 1:36:53):

> за такие функции увольнять надо. она совершенно небезопасная

Сейчас 37 год?

Все больше пионэров все тщательнее следят за безопасностью...

Безопасный вариант (памяти КГБ посвящается):

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>


static void panic(const char *msg)
{
   fputs("Panic! ",stderr);
   fputs(msg,stderr);
   fputs("\nSerious security problem!\n",stderr);
   fputs("Immediately call to the nearest police station!\n",stderr);
   exit(255);
}

#define READPROTECTED 1
#define WRITEPROTECTED 2
static int currentError=0;
static void onSegV (int i)
{
   switch(currentError){
      case READPROTECTED:
         panic("Function 'delete': cannot read from string!");
      case WRITEPROTECTED:
         panic("Function 'delete': readonly string!");
      default:
         panic("Function 'delete':  segmentation violation!");
   }
}
char *delete(char *str, int firstchar, int count)
{
int length;
int maxint=0;
  /*Check arguments validity:*/
   if(str==NULL)
      panic("Function 'delete': NULL string!");
   if(firstchar<0)
      panic("Function 'delete': index of a first character <0!");
   if(count<0)
      panic("Function 'delete':  count <0!");

   /*Determine the string length:*/
   signal(SIGSEGV,&onSegV);
   currentError = READPROTECTED;
   /*Find maximal signed integer:*/
   if(maxint==0){
      for(maxint=1; maxint>0; maxint<<=1);
      maxint--;
   }
   for(length=0;str[length]!='\0';length++)
      if(length==maxint)
         panic("Function 'delete':  too long string!");

   /*Check space available:*/
   if( (firstchar+count<0)||(firstchar+count > length) )
      panic("Function 'delete':  firstchar+count > length!");

   /*Ok, perform copying:*/
   currentError  = WRITEPROTECTED;
   {
      char *tmp=str+firstchar;
      while( (*tmp=*(tmp+count))!='\0' )tmp++;
   }
   signal(SIGSEGV,SIG_DFL);
   return str;
}

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

супер безопасный код


1.c: (in function panic)
1.c:8:4: Return value (type int) ignored: fputs("Panic! ",...
Result returned by function call is not used. If this is intended, can cast
result to (void) to eliminate message. (Use -retvalint to inhibit warning)
1.c:9:4: Return value (type int) ignored: fputs(msg, stderr)
1.c:10:4: Return value (type int) ignored: fputs("\nSerious...
1.c:11:4: Return value (type int) ignored: fputs("Immediate...
1.c:12:9: Argument to exit has implementation defined behavior: 255
The argument to exit should be 0, EXIT_SUCCESS or EXIT_FAILURE (Use -exitarg
to inhibit warning)
1.c: (in function onSegV)
1.c:23:12: Fall through case (no preceding break)
Execution falls through from the previous case. (Use -casebreak to inhibit
warning)
1.c:25:15: Fall through case (no preceding break)
1.c:18:25: Parameter i not used
A function parameter is not used in the body of the function. If the argument
is needed for type compatibility or future plans, use /*@unused@*/ in the
argument declaration. (Use -paramuse to inhibit warning)
1.c: (in function delete)
1.c:42:4: Return value (type [function (int) returns void]) ignored:
signal(SIGSEGV, ...
Result returned by function call is not used. If this is intended, can cast
result to (void) to eliminate message. (Use -retvalother to inhibit warning)
1.c:46:31: Left operand of <<= may be negative (int): maxint <<= 1
The left operand to a shift operator may be negative (behavior is
implementation-defined). (Use -shiftimplementation to inhibit warning)
1.c:49:17: Index of possibly null pointer str: str
A possibly null pointer is dereferenced. Value is either the result of a
function which may return null (in which case, code should check it is not
null), or a global, parameter or structure field declared with the null
qualifier. (Use -nullderef to inhibit warning)
1.c:63:4: Return value (type [function (int) returns void]) ignored:
signal(SIGSEGV, ...
1.c:64:11: Implicitly temp storage str returned as implicitly only: str
Temp storage (associated with a formal parameter) is transferred to a
non-temporary reference. The storage may be released or new aliases created.
(Use -temptrans to inhibit warning)

anonymous
()
Ответ на: супер безопасный код от anonymous

2anonymous (*) (13.05.2005 15:08:10):

Ты прикидывашься?

Ты привел результат прогона на предмет поиска мест, где чисто синтаксически возможны неоднозначности. Какой конкретно из приведенных тобой варнингов (кроме специально идиотски сделанной функции panic) тебя беспокоит?

Перехвачено все; не только нулевые указатели, (что, BTW, вообще было совершенно лишнее), но и даже возможность mprotectнутости региона.

Проверялка, кстати, довольно тупа. Например,

> 1.c:64:11: Implicitly temp storage str returned as implicitly only: str Temp storage (associated with a formal parameter) is transferred to a non-temporary reference.

Очевидная чушь, ибо возвращается в точности тот же storage класс, что и прилетел; никаких манипуляций с указателем сделано не было.

Возможность нулевого значения str на строке 49 почему-то указана (несмотря на предшествующую проверку!), а возможность выхода за границы памяти и перполнения целого в той же строке игнорируется.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

никто не идеален, но

- незачем возвращать 255, используя для exit() stdlib.h в которой кроме EXIT_FAILURE и EXIT_SUCCES ничего нет

- незачем функциям тип int, если он нигде не используется.

anonymous
()
Ответ на: комментарий от anonymous

>- незачем возвращать 255, используя для exit() stdlib.h в 
>которой кроме EXIT_FAILURE и EXIT_SUCCES ничего нет 

В POSIXе есть. И в подавляющем большинстве прочих систем есть.
EXIT_FAILURE и EXIT_SUCCES определены в stdlib.h только для 
совместимости с некоторыми экзотическими системами.

$cat ququ.c
#include <stdlib.h>
int main(void)
{
exit(255);
}

$cc -o ququ ququ.c
$./ququ ; echo $?
255

(BTW, такое идиотское значение задавалось специально; надо 
было вообще -1 влепить -- догадаешься, что будет?)

> - незачем функциям тип int, если он нигде не используется. 
А где ты увидел в моем примере возвращаемый тип int?

Если рассматривать ЮНИХ системы, то в примере только одна натяжка:
тип сигнального хандлера на некоторых системах не void a int.

А сам пример, если кто в танке, был призван продемонстрировать
дебилизм борьбы пионеров за безопасность (в безопасных программах
не может возникнуть необходимости в функции delete()).

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

имхо писать приложения надо так чтобы в них было только _необходимое_, и все что передается от пользователя, возвращается от функций и статусы возврата тоже - изначально считались потенциально опасными

я стараюсь думать по шаблону
s/А что в этом опасного/Зачем это здесь необходимо/

P.S. c уважением

anonymous
()
Ответ на: комментарий от Die-Hard

> А где ты увидел в моем примере возвращаемый тип int?

вообще-то fputs имеет тип int, man fputs

-----8><-------------------------------

int fputs(const char *s, FILE *stream);

-------------------------------><8-----

anonymous
()
Ответ на: комментарий от anonymous

anonymous (*) (14.05.2005 10:33:48)

>> А где ты увидел в моем примере возвращаемый тип int?

>вообще-то fputs имеет тип int, man fputs

fputs не я писАл. Это стандартная функция.

Может, ты не в курсе ;), любой стандарт Це позволяет игнорировать возвращаемый тип.

Честно говоря, спорить с упертыми утомляет.

Если чего не понял, извиняй.

Die-Hard ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.