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

  • Автор темы BigSerpent
  • Дата начала
Статус
Закрыто для дальнейших ответов.
B

BigSerpent

#1
Возникла потребность в написании программы на 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), Дельфи (включая ООп и создание собственных компонентов).
 
B

BigSerpent

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

bel_nikita

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

dex0r

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

Guest

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

bel_nikita

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

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

????

#7
dex0r
Ты не прав! Ведь компилятор не знает, что как и когда возвращает функция. И если длина строки уменьшится, во время выполнения цикла то ...
Вот простой пример на BCB иллюстрирующий, что ты не прав:
Код:
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 проводяться именно на стадии компиляции и от хода программы не зависят.
З.Ы. Только не надо флеймить, т.к. автор топика уже разобрался со своей проблемой, а наше обсуждение тему не затрагивает.
 
B

bel_nikita

#8
З.Ы. Только не надо флеймить, т.к. автор топика уже разобрался со своей проблемой, а наше обсуждение тему не затрагивает.
ну, как же не затрагивает. автору показывают/рекомендуют, что его код можно и нужно оптимизировать
 
B

BigSerpent

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

dex0r

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

bel_nikita

#12
BigSerpent
да причем здесь чайник? вам советуют, как лучше, а вы про чайники начинаете. да мне и дела нет, сколько вы программируете. вы спросили вам ответили.
dex0r
если в цикле не происходит изменение строки, то длина вычисляется один раз
докажи :(
Код:
 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:
Код:
; 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  :
Код:
 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:
Код:
; 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  :
Ну, че? Разницу чувствуешь?

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

Arush

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

Надо или

str3=str2[j];
i++;

или

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

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

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

Guest

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

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

Arush

#15
Вответ на :
Не совсем так. Была инициализация
str3[55]="";
То есть элемент после последнего символа в строке и так равен нулю.
Как раз нет: "" - это строка состоящая из одного символа - 0 (см опр. ASCIIZ)
Обычно обнуление массиво происходит только когда компилируешь в Debug. А при компиляции в Release все обнуления пробрасываются... Из-за чего, кстати, бывает приходится долго ловить незамеченные баги :rolleyes:
 
Статус
Закрыто для дальнейших ответов.