1

I have a little problem with a few simple lines of code.
Following lines I used to call my method:

char** paras = new char*;
inputLength = charUtils::readParameterFromConsole(paras, paraCount, stringBeginningIndex);

The method looks like following:

int charUtils::readParameterFromConsole(char** &inputs, int &paraCount, int &stringBeginningIndex) {
    char input[BUFFER_STRING_LENGTH];

    cin.getline(input, BUFFER_STRING_LENGTH);

    if(strlen(input) > 0)
    {
        bool stringBeginning = false;
        char* part = "";
        string partString = "";

        for(int i = 0; i < paraCount; i++)
        {
            if (i == 0)
                part = strtok(input, " ");
            else
                part = strtok(NULL, " ");

            inputs[i] = part;
        }
    } else
    {
        cout << "Error! No Input!" << endl;
    }

    cout << &inputs[0] << endl;
    cout << inputs[0] << endl;

    return strlen(input);
}

In the method readParameterFromConsole are the values correct, but in the calling method they aren't correcy any longer. I am facing that problem since I refactored the code and make an new class.

Can anyone give me an advice please?

6
  • Does readParameterFromConsole(...) change the values? Commented Feb 9, 2011 at 21:40
  • Yes and at the end of the method I use a simple output to check the values. There is all correct, but the calling method loose all values. Paras has some values I can't explain. Commented Feb 9, 2011 at 21:54
  • Is it just paras that has incorrect values? Or the other parameters too? Can you post code to show how readParameterFromConsole() modifies the parameters and how you output the values? Commented Feb 9, 2011 at 22:01
  • We need more to give you an answer. The code you posted looks correct. Although I'm curious to know why are you using a char** & Commented Feb 9, 2011 at 22:04
  • All other values are correct. Only paras is wrong. You can see above the small version. ;) @otibom: Because I want to give a reference to the other method, which isn't part of the same class. Commented Feb 9, 2011 at 22:05

2 Answers 2

3

You are passing back pointers into a stack allocated variable, input when you say inputs[i] = part, because part is a pointer into input handed back by strtok.

http://www.cplusplus.com/reference/clibrary/cstring/strtok/

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the advice, but I can't handle it.
@H3llGhost: do you mean you need further explanation?
Yes please, because I can't get why it works local in the same class, but doesn't in a different class.
@H3llGhost: Sorry, had to leave yesterday before I could explain further. Hope Alf's answer was satisfactory. :)
0

Your code as I'm writing this:

int charUtils::readParameterFromConsole(char** &inputs, int &paraCount, int &stringBeginningIndex) {
    char input[BUFFER_STRING_LENGTH];

    cin.getline(input, BUFFER_STRING_LENGTH);

    if(strlen(input) > 0)
    {
        bool stringBeginning = false;
        char* part = "";
        string partString = "";

        for(int i = 0; i < paraCount; i++)
        {
            if (i == 0)
                part = strtok(input, " ");
            else
                part = strtok(NULL, " ");

            inputs[i] = part;
        }
    } else
    {
        cout << "Error! No Input!" << endl;
    }

    cout << &inputs[0] << endl;
    cout << inputs[0] << endl;

    return strlen(input);
}

A main problem is that you're setting inputs[i] = pointer into local array. That array doesn't exist anymore when the function returns. Undefined behavior if you use any of those pointers.

As I understand it you want an array of "words" as a result.

That's easy to arrange (note: code untouched by compiler's hands):

#include <vector>
#include <string>
#include <sstream>
#include <stdexcept>

bool throwX( char const s[] ) { throw std::runtime_error( s ); }

typedef std::vector<std::string>  StringVector;

std::string lineFromUser()
{
    std::string line;
    std::getline( cin, line )
        || throwX( "lineFromUser failed: std::getline failed" );
    return line;
}

void getWordsOf( std::string const& s, StringVector& result )
{
    std::istringstream stream( s );
    std::string        word;
    StringVector       v;

    while( stream >> word )
    {
        v.push_back( word );
    }
    result.swap( v );
}

StringVector wordsOf( std::string const& s )
{
    StringVector result;
    getWordsOf( s, result );
    return result;
}

// Some call, like
StringVector const words = wordsOf( lineFromUser() );

Again, this is off the cuff code, please just correct any syntax erors.

Cheers & hth.,

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.