Почему поведение string :: find отличается? - PullRequest
0 голосов
/ 09 июля 2019
bool check_tape(char* tape) {
    int test8; 
    cout << example <<" "<<example.size()<<" "<<alpha_sym<<" "<< endl;
    cin >> test8; //To pause the program, temporary 
    int err = 0;
    for (int i = 0; i < example.size(); i++) {
        if (alpha_sym.find(example[i]) >= 0 && alpha_sym.find(example[i]) < example.size()) {
            cout << alpha_sym.find(example[i]) << " " << endl;
            err += 0;
        }
        else {
            cout << example[i]<<" "<< i << " не содержится в алфавите" << endl;
            err++;
        }
    }
    if (err) {
        return 1; //Temporary I made here return 1, else program will crash 
        //get_acmd();
    }
    else return 1;
}

В одном случае find возвращает позицию первой записи, как и ожидалось, но в другом случае возвращает сам символ.
111 + 11 - строка, и символы из нее ищут в другой строке "1 + _"

То же самое с 1435 + 212 и 01234567 + _

Good case

Strange case

1 Ответ

1 голос
/ 09 июля 2019

Как уже отмечалось в комментарии к вопросу, в операторе if есть опечатка

if (alpha_sym.find(example[i]) >= 0 && alpha_sym.find(example[i]) < example.size())
                                                                    ^^^^^^^^^^^^^^

Вместо example.size() должно быть не менее alpha_sym.size()

Но в любом случае условие слишком сложное, и метод find обычно вызывается три раза.

Этот фрагмент кода

for (int i = 0; i < example.size(); i++) {
    if (alpha_sym.find(example[i]) >= 0 && alpha_sym.find(example[i]) < example.size()) {
        cout << alpha_sym.find(example[i]) << " " << endl;
        err += 0;
    }
    else {
        cout << example[i]<<" "<< i << " не содержится в алфавите" << endl;
        err++;
    }
}

можно переписать следующим образом

for ( std::string::size_type i = 0; i < example.size(); i++ )
{
    auto n = alpha_sym.find( example[i] );

    if ( n != std::string::npos )
    {
        std::cout << n << " " << std::endl;
    }
    else
    {
        std::cout << example[i] << " " << i << " не содержится в алфавите" << std::endl;
        ++err;        
    }
}

Если ваш компилятор поддерживает C ++ 17, тогда вы даже можете написать следующим образом

for ( std::string::size_type i = 0; i < example.size(); i++ )
{
    if ( auto n = alpha_sym.find( example[i] ); n != std::string::npos )
    {
        std::cout << n << " " << std::endl;
    }
    else
    {
        std::cout << example[i] << " " << i << " не содержится в алфавите" << std::endl;
        ++err;        
    }
}

Обратите внимание на то, что неиспользуемый параметр tape (я думаю, упрощенный) функции может быть объявлен как

bool check_tape( const char *tape )

при условии, что оно не изменено в функции. В этом случае вы сможете передавать строковые литералы в качестве аргументов функции.

Вот демонстрационная программа

#include <iostream>
#include <string>

int main()
{
    std::string example( "1435+212" );
    std::string alpha_sym( "01234567+_" );
    unsigned int err = 0;

    for ( std::string::size_type i = 0; i < example.size(); i++ )
    {
        auto n = alpha_sym.find( example[i] );

        if ( n != std::string::npos )
        {
            std::cout << n << " " << std::endl;
        }
        else
        {
            std::cout << example[i] << " " << i << " не содержится в алфавите" << std::endl;
            ++err;        
        }
    }
}

Его вывод

1 
4 
3 
5 
8 
2 
1 
2 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...