Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Функция два раза подряд не....


Автор: apook 6.8.2006, 10:25
Ни как не врублюсь. Есть функция возврашающая -1 в случае ошибки
Так вот если запустить ее один раз с параметро заведомо  возращающими
 > -1  все отлично а если сразу запустить ее же с теми же параметрами то
она возвращает -1 (ну или правильно >0  как будет настроение) Тенденцию
при каких случаях она все же нормально сробатывает я так и не уловил
Понял одно : ECЛИ после первого запуска написать printf (" ");  или
 cout << " "; то второй раз срабатывает правильно.

Автор: vinter 6.8.2006, 10:31
Давай текст ф-ии.. smile 

Автор: apook 6.8.2006, 10:58
?? Название естественно не принципиально
Код

int strccmp(const char *sstr, const char *samplestring, int flg)
{
int n, i, a, wn, x, ex, ret;
i = strlen(sstr); //длина основной строки

ret = -1;
x = ret;
a = 0;
n = 0; //счетчик

for (n=0; n < i; n++)
    {
     if (strlen(samplestring) > i) break; //если длина подстроки больше длины основной строки выход из цикла 
     wn = n; //счетчик для основной строки равен общему счетчику

     while(wn < i)//проверка продолжается пока счетчик для подстроки меньше длины основной строки
         {
          if (sstr[wn] == samplestring[a])
              { //если символ из основной строки совпал с символом подстроки
               if (ret < 0) ret = wn; //удачно(совпал один символ(первое вхождение))
               if (a == (strlen(samplestring) - 1))
                    {
                     ex = 1; //удачно(совпали все символы)
                     break;
                         }
               a++; //счетчик верных вхождений (от него и все символы за ним должны совпасть)
               wn++;
                   }
           else
               {//неудачно
                ret = -1;
                a = 0; //если один из символов не совпал, счетчик верных вхождений обнуляется  
                break; 
                    }

              }
          if (ex == 1) break; //получен код 1(удачно)пора прекращать сравнение
         }
if ((flg == 'L' || flg == 'l') && ret > -1) x = ret;
else if ((flg == 'R' || flg == 'r') && ret > -1) x = wn;
return x;
   }
/*конец функции strccmp*/

Автор: ptr 6.8.2006, 12:02
Да что-то ты намудрил. Покажи как вызываешь функцию. И ещё поясни что она делает, например, зачем нужен flg.

Автор: vinter 6.8.2006, 12:13
У меня вот так работает без проблем...Всегда инициализируй переменные когда их определяешь, т.к может быть исп. неинициализированная переменная из за чего могут быть "глюки". Как раз из за неинициализации у меня тоже ошибочно выводило..
Код

#include<iostream>
#include <string.h>
using namespace std;
int str(const char *sstr, const char *samplestring, int flg);
int main()
{
    int v = 0;
    char s[] = "asd";
         char s1[] = "asd";
    char s2[] = "ghy";
    char s3[] = "ghyt";
    v = str(s, s1, 'L');
    v = str(s, s1, 'L');
    v = str(s2, s1, 'L');
    v = str(s, s1, 'L');
    v = str(s1, s3, 'L');
    return 1;
}



int str(const char *sstr, const char *samplestring, int flg)    
{    
int n = 0, i = 0, a = 0, wn = 0, x = 0, ex = 0, ret = -1;    
i = strlen(sstr); //длина основной строки    
ret = -1;    
for (n=0; n < i; n++)    
    {    
     if (strlen(samplestring) > i) break; //если длина подстроки больше длины основной строки выход из цикла    
     wn = n; //счетчик для основной строки равен общему счетчику    
     while(wn < i)//проверка продолжается пока счетчик для подстроки меньше длины основной строки    
         {    
          if (sstr[wn] == samplestring[a])    
              { //если символ из основной строки совпал с символом подстроки    
               if (ret < 0) ret = wn; //удачно(совпал один символ(первое вхождение))    
               if (a == (strlen(samplestring) - 1))    
                    {    
                     ex = 1; //удачно(совпали все символы)    
                     break;    
                         }    
               a++; //счетчик верных вхождений (от него и все символы за ним должны совпасть)    
               wn++;    
                   }    
           else    
               {//неудачно    
                ret = -1;    
                a = 0; //если один из символов не совпал, счетчик верных вхождений обнуляется    
                break;    
                    }    
              }    
          if (ex == 1) break; //получен код 1(удачно)пора прекращать сравнение    
         }    
if ((flg == 'L' || flg == 'l') && ret > -1) x = ret;    
else if ((flg == 'R' || flg == 'r') && ret > -1) x = wn;    
return x;    
   }    
/*конец функции strccmp*/    

Цитата

 ECЛИ после первого запуска написать printf (" ");  или
 cout << " "; то второй раз срабатывает правильно.

Совпадение smile  
Цитата

зачем нужен flg.

Тоже кстати не понял smile поставил просто 'L'

Автор: apook 6.8.2006, 13:21
Цитата

Покажи как вызываешь функцию


Вызывал в целях тестирования по разному, во всех случаях имеется тенденция к этому глюку Например:


x = strccmp(buf, argv[1], 'L');
тут-же
y = strccmp(buf, argv[1], 'L');
cout << x << "  " << y << endl;
Получим 15  -1
и т.д Я уже не говорю о включении в оператор if если к примеру надо зделать так: if ((strccmp(......,'R') > -1) && (strccmp(.....,'L') < 20))
Цитата

зачем нужен flg

вообще это поиск подстроки в строке(стандартные одолели своей ограниченностью) flg по замыслу типа флаг Параметер L - left R-right т.е слева или справа Надо понимать вернуть первое вхождение или последнее
Цитата

Совпадение

Совпадение не совпадение а всегда сробатывает Но конечно не серьезно
использовать такой "прием"
Цитата

Всегда инициализируй переменные 

Ща испытаю эту фишку



Автор: apook 6.8.2006, 14:00
Цитата

Всегда инициализируй переменные 

Совет и впрямь оказался полезным

А тогда почему бы компилятору так не делать или в целях экономии времени
Ну в общем причины могут быть (например экономия времениuser posted image)

Автор: vinter 6.8.2006, 14:14
Цитата

А тогда почему бы компилятору так не делать или в целях экономии времени

так он инициализирует только произвольными значениями...

Автор: Mayk 6.8.2006, 14:27
Цитата(apook @  6.8.2006,  18:00 Найти цитируемый пост)

А тогда почему бы компилятору так не делать или в целях экономии времени

Потому что это затратит нехилое CPU-шное время. Особенно в циклах.
Код

while(sth){
  char a_lot_of_memory[1024*1024];
  readFromFileTo(a_lot_of_memory);
}

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

Автор: Oleg_Ci 6.8.2006, 14:55
Мой велосипед smile 
Код

#include<iostream>
#include<cstdlib>
#include <cstring>
using namespace std; 

int strccmp(const char *str, const char *control, int flg);

void main()    
{    
    char *s = "asdfghjkl";
    char *c = "gh";
    cout << s << endl << c << endl;
    cout << strccmp( s, c, 'l' ) << endl;
    system("pause");
}
////////////////////////////////////////////////////////////////

int strccmp(const char *str, const char *control, int flg)
{
    const char *s = str;
    const char *c = control;
    while ( *s )
    {
        if ( *s == *c )
        {
            if(!*(++c))  break; 
        } else c = control;
        s++;
    }
    if ( !*s ) return -1;
    if (flg == 'L' || flg == 'l') return s - str - strlen( control ) + 1;
    else if (flg == 'R' || flg == 'r') return (int)strlen(s) -2 + c - control;
    return -1;
}

Автор: BreakPointMAN 6.8.2006, 15:01
Цитата(Mayk @  6.8.2006,  15:27 Найти цитируемый пост)
Ну и зачем здесь инициализировать мегабайт памяти? 

Это уже гигабайт получается... ;)

Автор: Mayk 6.8.2006, 15:24
Цитата(BreakPointMAN @  6.8.2006,  19:01 Найти цитируемый пост)

Это уже гигабайт получается... ;)

 fixed  smile  


Автор: apook 6.8.2006, 16:08
Цитата

Мой велосипед

Конечно с флагом R перестарался можно просто к первому вхождению
прибавить стрлен он строки dest .Но ниче пригодится . Короче в следующих великах.... 

Цитата

так он инициализирует только произвольными значениями...

Аааа !! понял !! (почти) но не важно

Автор: ManiaK 9.8.2006, 15:06
Цитата(apook @  6.8.2006,  16:08 Найти цитируемый пост)
так он инициализирует только произвольными значениями...

Шо, rand для каждого байтика что ли запускает? smile  smile  smile 
Не инициализирует он их.

Кстати, шестая студия в Debug-сборке забивает всю выделяемую раму определёнными значениями (по-моему нулями), а в Release - нет. Поэтому иногда в Debug программы, где не инициализируются переменные нормально работают, а хочешь релизнуть - хоть вешайся... smile 

Автор: vinter 9.8.2006, 17:52
Цитата

Не инициализирует он их.

Да ну?? то есть создал переменную и все, там ничего нет??Какое либо значение в ней все равно содержится!
И как это не назови инициализация или нет все равно у переменной есть какое-то значение!
Цитата

Шо, rand для каждого байтика что ли запускает?

Нет просто берет мусор из памяти

Автор: Mayk 9.8.2006, 18:03
Цитата(vinter @  9.8.2006,  21:52 Найти цитируемый пост)

Да ну?? то есть создал переменную и все, там ничего нет??Какое либо значение в ней все равно содержится!

Ну да. Содержится. Только "содержать" вообще не значит "инициализировать".


Цитата(answers.com/initialization)

in·i·tial·ize (ĭ-nĭsh'ə-līz') pronunciation
tr.v. Computer Science., -ized, -iz·ing, -iz·es.

   1. To set (a starting value of a variable).

Разве компилятор делает это? Нет. Он НЕ присваивет значение. Он использует имеющийся мусор.
А раз он  не присваивает значение, то ни о какой инициализации речи нет. a = b; <- вот присвоение. 
mov [ebp+var], 4 - вот присвоение. А использование мусора - это использование мусора. И не больше.

Автор: vinter 9.8.2006, 19:29
Код

mov [var] , ax

не почистили ax вначале..и вот у нас в var содержится мусор(например адрес сегмента данных), и мы им начинаем пользоваться..
так а чем компилер хуже?? 
Цитата

Только "содержать" вообще не значит "инициализировать".


Тогда назовите мне пожалуйста слово которым можно охарактеризовать действия компилятора, если вам так не нравится слово инициализация..

Автор: Mayk 9.8.2006, 19:37
Цитата(vinter @  9.8.2006,  23:29 Найти цитируемый пост)


Тогда назовите мне пожалуйста слово которым можно охарактеризовать действия компилятора, если вам так не нравится слово инициализация..

Отведение памяти. Именно это и делает компилятор.

Код

int f(){
    int c;
    int b;
    f();
    return b+c;
}

Цитата

f:
   pushl   %ebp
    movl    %esp, %ebp
     subl    $8, %esp 
    call    f
    movl    -4(%ebp), %eax
    addl    -8(%ebp), %eax
    leave
    ret

Автор: ManiaK 10.8.2006, 12:25
Mayk, респект smile 

Автор: MoZy 10.8.2006, 18:59
Цитата

нравится слово инициализация

слово хорошее, но не к месту  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)