strlen и строка как массив

Тема в разделе "C и С++ FAQ", создана пользователем BigSerpent, 10 окт 2004.

Статус темы:
Закрыта.
  1. BigSerpent

    BigSerpent Гость

    Возникла потребность в написании программы на C. Есть задача - нужно удалить из строки определенные символы. Попытка:

    char str2[55]="'djkkci9df odf dfiodfi fdgi dfi'", str3[55]="";

    int i,j;

    for (j=0,i=0; j<strlen(str2); j++)
    {
    if (str1[j]!='\'')
    {
    i++;
    str3=str2[j];
    }
    }

    Массив str3 превосходно изменяется. Но при попытке нахождения
    strlen(str3) результат = 0.
    Попытка
    char * str1;
    str1=&str3;
    printf("%d",strlen(str1));
    тоже ничего не дает.

    Я представляю, что str3[55]=""; инициализирует строку длиной 55 символов символом '\0'. То есть после изменения первых символов строки str3 в ней оставшиеся равны '\0'. Почему функция вычисления длины строки возвращает 0 ?

    И вообще, как можно получить "нормальную строку" в C?


    P.S. В C новичок. В программировании не новичок - хорошо знаю Pascal (c 1992), Дельфи (включая ООп и создание собственных компонентов).
     
  2. BigSerpent

    BigSerpent Гость

    Всем спасибо, уже ответили :). Не обратил внимание, что индекс массива начинается с 0 и нужно было писать i++ после операции с элементами массива.
     
  3. bel_nikita

    bel_nikita Гость

    BigSerpent
    советую вынести из цикла метод strlen(). очень, знаетели, долгая операция каждый раз вычислать длинну строки
    Код (Text):
    int iLen=strlen(str2);
    for (j=0,i=0; j<iLen; j++)
     
  4. dex0r

    dex0r Гость

    bel_nikita, ты видно си вообще не знаешь! :) Длина вычисляется один раз!! (скомпил прогу, а потом постмотри как все это выглядит на АСМе ;) можно написать хоть:
    for ( int j=0, int i=0; j<strlen(str2); j++) и это совсем не означает, что i и j будет каждый раз "определяться"
     
  5. Guest

    Guest Гость

    dex0r
    ;) :p ;)
    М-да, блин. ;)
    Рассмешили вы меня :D
    Ну, так возьми скомпили и посмоти! Что напишет компилер в случае:
    Код (Text):
    for ( int j=0, int i=0; j<strlen(str2); j++)
    и случае:
    Код (Text):
    int iLen=strlen(str2); for ( int j=0, int i=0; j<iLen; j++)
    И сравни количество сгенерируемых строчек в этих обоих случаях!
     
  6. bel_nikita

    bel_nikita Гость

    Млин, залогиниться забыл :(
    В общем это я был.

    До меня дошло. Наш "крутой" программер спутал strlen с sizeof
     
  7. ????

    ???? Гость

    dex0r
    Ты не прав! Ведь компилятор не знает, что как и когда возвращает функция. И если длина строки уменьшится, во время выполнения цикла то ...
    Вот простой пример на BCB иллюстрирующий, что ты не прав:
    Код (Text):
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
       char str2[] = "123\0";
       int iLen;
       for (int j=0, i=0; j<StrLen(str2); j++, i++)
       {
           iLen = StrLen(str2);
           ShowMessage(iLen);
           str2[2] = '\0';
       };
    }
    Сколько раз выполнится тело цикла?
    А присвоение значений i и j проводяться именно на стадии компиляции и от хода программы не зависят.
    З.Ы. Только не надо флеймить, т.к. автор топика уже разобрался со своей проблемой, а наше обсуждение тему не затрагивает.
     
  8. bel_nikita

    bel_nikita Гость

    ну, как же не затрагивает. автору показывают/рекомендуют, что его код можно и нужно оптимизировать
     
  9. BigSerpent

    BigSerpent Гость

    Спасибо, я чайник в С, но не в программировании вообще ;). Я всегда оптимизирую код для однократного вычисления переменных. Просто тут стоял вопрос про работу кода вообще :(.
     
  10. dex0r

    dex0r Гость

    ????, если в цикле не происходит изменение строки, то длина вычисляется один раз :(
     
  11. BigSerpent

    BigSerpent Гость

    dex0r
    Компилятор такой умный? Серьезно.
     
  12. bel_nikita

    bel_nikita Гость

    BigSerpent
    да причем здесь чайник? вам советуют, как лучше, а вы про чайники начинаете. да мне и дела нет, сколько вы программируете. вы спросили вам ответили.
    dex0r
    докажи :(
    Код (Text):
     char str2[55]="'djkkci9df odf dfiodfi fdgi dfi'";

    int i,j,temp;

    int iLen=strlen(str2);

    for (j=0,i=0; j<iLen; j++)
    {
     temp=i+j;
    }
    ASM:
    Код (Text):
    ; 15  :
    ; 16  :  int i,j,temp;
    ; 17  :
    ; 18  :  int iLen=strlen(str2);

    lea edi, DWORD PTR _str2$[esp+72]
    mov DWORD PTR _str2$[esp+109], eax
    or  ecx, -1
    mov DWORD PTR _str2$[esp+113], eax
    add esp, 4
    mov DWORD PTR _str2$[esp+113], eax
    mov DWORD PTR _str2$[esp+117], eax
    mov WORD PTR _str2$[esp+121], ax
    repne scasb
    not ecx
    dec ecx
    pop edi
    mov DWORD PTR _iLen$[esp+64], ecx
    pop esi

    ; 19  :
    ; 20  :  for (j=0,i=0; j<iLen; j++)
    ; 21  :  {
    ; 22  :   temp=i+j;
    ; 23  :  }
    ; 24  :
    Код (Text):
     char str2[55]="'djkkci9df odf dfiodfi fdgi dfi'";

    int i,j,temp;

    for (j=0,i=0; j<strlen(str2); j++)
    {
     temp=i+j;
    }
    ASM:
    Код (Text):
    ; 15  :
    ; 16  :  int i,j,temp;
    ; 17  :
    ; 18  :  for (j=0,i=0; j<strlen(str2); j++)

    lea edi, DWORD PTR _str2$[esp+68]
    mov DWORD PTR _str2$[esp+105], eax
    or  ecx, -1
    mov DWORD PTR _str2$[esp+109], eax
    add esp, 4
    mov DWORD PTR _str2$[esp+109], eax
    xor edx, edx
    mov DWORD PTR _str2$[esp+113], eax
    mov WORD PTR _str2$[esp+117], ax
    repne scasb
    not ecx
    dec ecx
    je  SHORT $L861
    $L850:
    lea edi, DWORD PTR _str2$[esp+64]
    or  ecx, -1
    xor eax, eax
    inc edx
    repne scasb
    not ecx
    dec ecx
    cmp edx, ecx
    jb  SHORT $L850
    $L861:
    pop edi

    ; 19  :  {
    ; 20  :   temp=i+j;
    ; 21  :  }
    ; 22  :
    Ну, че? Разницу чувствуешь?

    Да-а, млин. И впрям "крутые" поограммеры собрались ;)
     
  13. Arush

    Arush Гость

    А программа не работала из-за этого:

    Надо или

    str3=str2[j];
    i++;

    или

    str3[i++]=str2[j];

    Иначе str3[0] не изменяется и равно 0.

    После цикла надо сделать str3=0; чтобы завершить строку иначе работать будет неправильно.
     
  14. Guest

    Guest Гость


    Не совсем так. Была инициализация
    str3[55]="";
    То есть элемент после последнего символа в строке и так равен нулю.
     
  15. Arush

    Arush Гость

    Вответ на :
    Как раз нет: "" - это строка состоящая из одного символа - 0 (см опр. ASCIIZ)
    Обычно обнуление массиво происходит только когда компилируешь в Debug. А при компиляции в Release все обнуления пробрасываются... Из-за чего, кстати, бывает приходится долго ловить незамеченные баги :rolleyes:
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей