简体   繁体   English

将字符串迭代器传递给函数

[英]Passing string iterator to function

I have a function I want to use in other function which gets number from string. 我有一个要在其他函数中使用的函数,该函数从字符串获取数字。 In base funcion I create std::string::iterator and I want to pass it to other function that gets this number, skips spaces, and then outer function continues to search through string. 在基本函数中,我创建了std::string::iterator ,并将其传递给获取该数字的其他函数,跳过空格,然后外部函数继续在字符串中搜索。

When I am using iterator I do something like *strPtr to get value, and *++strPtr to get value and move to another character. 当我使用迭代器时,我会执行*strPtr来获取值,并执行*++strPtr来获取值并移至另一个字符。 When I pass pointer to that I need to use **strPtr to get value and I hove no idea how to get value and increment iterator. 当我传递指向该指针的指针时,我需要使用**strPtr来获取值,而我不知道如何获取值并递增迭代器。 :( :(

I did *++*strPtr and it kinda worked but it crashes when it quits internal function. 我做了*++*strPtr ,它有点用,但是退出内部函数时会崩溃。

double calculate( char* x ){
std::string formula = x;
ValueStack valueStack;
OperatorStack operatorStack;

std::string::iterator strPtr = formula.begin();

while( *strPtr == ' ' )
{
    strPtr++;
}

if( *strPtr == '-' )
{
    std::string temp;
    temp += *strPtr;

    while( *++strPtr == ' ' );

    while( ((*strPtr <= '9' ) && (*strPtr >= '0' )) || (*strPtr == '.') )
    {
        temp += *strPtr;
        while( *++strPtr == ' ' );
    }

    char** x;
    valueStack.push( strtod( temp.c_str(), x ) );
}

while( strPtr < formula.end() )
{

    if( *strPtr == ' ' )
    {
        while( *++strPtr == ' ' );
    }

    if( operatorStack.isOper( *strPtr ) )
    {   
        if( *strPtr == ')' )
        {
            evaluate( &valueStack, &operatorStack );
            strPtr++;
        }

        else if( *strPtr == '(' )
        {
            operatorStack.push( *strPtr );

            while( *++strPtr == ' ' );

            if( *strPtr == '-' )
            {
                std::string temp;
                temp += *strPtr;

                while( *++strPtr == ' ' );

                while( ((*strPtr <= '9' ) && (*strPtr >= '0' )) || (*strPtr == '.') )
                {
                    temp += *strPtr;
                    while( *++strPtr == ' ' );
                }

                char** x;
                valueStack.push( strtod( temp.c_str(), x ) );
            }
        }

        else if( operatorStack.prior( *strPtr ) <= operatorStack.prior( operatorStack.top() ) )
        {
            evaluate( &valueStack, &operatorStack );
            operatorStack.push( *strPtr++ );
        }

        else operatorStack.push( *strPtr++ );
    }

    else
    {
        std::string temp;
        temp += *strPtr;

        while( *++strPtr == ' ' );

        while( ((*strPtr <= '9' ) && (*strPtr >= '0' )) || (*strPtr == '.') )
        {
            temp += *strPtr;
            while( *++strPtr == ' ' );
        }

        char** x;
        valueStack.push( strtod( temp.c_str(), x ) );
    }
}

evaluate( &valueStack, &operatorStack );

double ret = valueStack.pop();
if( pow(ret, 2) < 0.000000001 ) return 0;
return ret; 
}

To clarify, I want make function like this, and use it above: 为了澄清起见,我想要使函数像这样,并在上面使用它:

void getValue( std::string::iterator strPtr, ValueStack* valueStack )
{
std::string temp;
    temp += *strPtr;

    while( *++strPtr == ' ' );

    while( ((*strPtr <= '9' ) && (*strPtr >= '0' )) || (*strPtr == '.') )
    {
        temp += *strPtr;
        while( *++strPtr == ' ' );
    }

    char** x;
    valueStack->push( strtod( temp.c_str(), x ) );
}

There are an easier way for iterating over a string you can, for instance: 有一种更简单的方法可以遍历一个string ,例如:

    string str("3+5-4   -  3 / 4");

    for (string::iterator it = str.begin(); it!=str.end();++it)
    {
        if (!(*it == ' ')) {  // Skip spaces.

           if(isdigit(*it))
           {
             // Do your thing with ValueStack.
           }
           else
           {
               // Handle operators here.
               switch(*it)
               {
                   case('-'): break;
                   case('+'): break;
                   case('/'): break;
                   case('*'): break;
               }
           }
        }
    }

On the other hand, I recommend you take a look at Boost.Spirit . 另一方面,我建议您看一下Boost.Spirit It will help you to achive what you're trying to do (evaluating mathematical expressions) in a more elegant way. 这将帮助您以一种更加优雅的方式实现您想要做的事情(评估数学表达式)。 Also in that link there are an example of a "calculator" just like you want but using spirit . 同样在该链接中,有一个您希望使用但使用spirit的“计算器”示例。

Your algorithm only supports one digit numbers. 您的算法仅支持一位数字。 And its very hard to get multi-digit numbers supported without using some external library (such as Boost.Spirit for instance ;) ). 而且,不使用某些外部库(例如Boost.Spirit例如;)就很难获得多位数字的支持。

One thing I see in your code is that you assume that std::string is null terminated. 我在您的代码中看到的一件事是,您假设std :: string是null终止的。 Most of your loops are not bounded properly. 您的大多数循环都没有正确限制。 For example: 例如:

while( *strPtr == ' ' )
{
    strPtr++;
}

What if the entire string is spaces? 如果整个字符串都是空格怎么办? What stops this loop from going into uncharted territory? 是什么阻止了该循环进入未知领域?

A std::string does not have to be null terminated, so there is no guarantee this loop will stop when it reaches the end of the string. std :: string不必以null结尾,因此无法保证此循环在到达字符串末尾时将停止。 You do the same sort of loop in other places in your code. 您在代码的其他位置执行相同的循环。

If you're going to loop this way, it would need to be written: 如果要以这种方式循环,则需要编写以下代码:

while( *strPtr == ' ' && strPtr != formula.end())
    strPtr++;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM