pointer to a pointer problems

Discussion in 'C++' started by Christopher, Aug 15, 2011.

  1. Christopher

    Christopher Guest

    An open book test I am taking, tasked me to write a function with the
    following prototype. Yea, its a test, so don't give me the
    implementation. But it is open book, so maybe I can at least get a few
    questions answered.

    // returns the next token in a string found seperated by the
    delimeter. upon return updates str to point to the next token in
    // the string after the one returned
    const char * nextToken(const char ** str, const char delimeter);

    When I look at this, it looks very c-style to me. I think it is
    unsafe.

    1) I don't see a way to return a different string without allocating
    it in the function body and leaving it to the caller to clean the new
    string up.

    2) Why we have a pointer to a pointer as a parameter isn't clear to
    me. Even after all these years with the Windows API, I don't see the
    purpose here. Why not just use a const char *?

    These attempts failed with compiler errors, when trying to update the
    str param
    str = str + indexOnePastDelimeter; // If it was a const
    char *, this is what I'd do
    str = &(*str + indexOnePastDelimeter); // I don't see why the
    compiler complains about this one
    str = &((*str)[indexOnePastDelimeter]);


    I am going to submit a more c++ implementation (below) with a
    different prototype, because I failed at updating the str parameter in
    all my attempts and the c-style implementation came out very ugly.
    However, if anyone can address those 2 issues for me, I'd like to know
    what the thinking was.


    #include <string>
    #include <iostream>

    //--------------------------------------------------------------------------------------
    /// \brief Tokenizes a string
    /// \detail Gets a substring from a string, from a given start
    position to the position
    /// of a given delimeter. If the delimiter is not found,
    everything from the start
    /// position to the end of the given string is returned
    /// \param str The string to tokenize
    /// \param delimiter Characterer that seperates one token from the
    next
    /// \param start_pos [IN,OUT] position of the string to start looking
    for the next token.
    /// When a token is found, this parameter is updated
    to the start position
    /// of the next token in the string. If no next token
    has been found
    /// before reaching the end of the string, this
    parameter will be set to
    /// std::string::npos.
    /// \return std::string The next token found in the string from the
    given start position.
    /// If the str param is empty or the start_pos
    param is past the end of
    /// the string, then an empty string will be
    returned.
    std::string nextToken(const std::string & str, const char delimiter,
    std::string::size_type & start_pos)
    {
    // Check for valid params
    if( str.empty() || start_pos >= str.size() )
    {
    start_pos = std::string::npos;
    return "";
    }

    std::string::size_type orig_start_pos = start_pos;
    std::string::size_type delim_pos = str.find(delimiter,
    start_pos);

    // Check if the delimiter was not found
    if( delim_pos == std::string::npos )
    {
    start_pos = std::string::npos;
    return str.substr(orig_start_pos, std::string::npos);
    }

    // Update the start position
    if( delim_pos + 1 < str.size() )
    {
    start_pos = delim_pos + 1;
    }
    else
    {
    start_pos = std::string::npos;
    }

    // Return a substring that is from the start position to right
    before the delimeter
    return str.substr(orig_start_pos, delim_pos - orig_start_pos);
    }

    //--------------------------------------------------------------------------------------
    int main()
    {
    // Test 1
    const std::string testString1 = "Mary,Autumn,Susie,Sally";

    std::string::size_type start_pos = 0;
    while( start_pos != std::string::npos )
    {
    std::cout << nextToken(testString1, ',', start_pos) <<
    std::endl;
    }

    system("Pause");

    // Test 2
    const std::string testString2 = "C:\\Windows\\System32\\Drivers\
    \Etc\\";

    start_pos = 0;
    while( start_pos != std::string::npos )
    {
    std::cout << nextToken(testString2, '\\', start_pos) <<
    std::endl;
    }

    system("Pause");

    // Test 3
    const std::string testString3 = "";

    start_pos = 0;
    while( start_pos != std::string::npos )
    {
    std::cout << nextToken(testString3, ',', start_pos) <<
    std::endl;
    }

    system("Pause");

    // Test 4
    const std::string testString4 = ",";

    start_pos = 0;
    while( start_pos != std::string::npos )
    {
    std::cout << nextToken(testString4, ',', start_pos) <<
    std::endl;
    }

    system("Pause");

    // Done
    return 0;
    }
    Christopher, Aug 15, 2011
    #1
    1. Advertising

  2. On 8/15/2011 2:16 PM, Christopher wrote:
    > An open book test I am taking, tasked me to write a function with the
    > following prototype. Yea, its a test, so don't give me the
    > implementation. But it is open book, so maybe I can at least get a few
    > questions answered.
    >
    > // returns the next token in a string found seperated by the
    > delimeter. upon return updates str to point to the next token in
    > // the string after the one returned
    > const char * nextToken(const char ** str, const char delimeter);
    >
    > When I look at this, it looks very c-style to me. I think it is
    > unsafe.


    In what sense is it unsafe? You're writing that function. You can
    impose any requirements on the data the function receives and introduce
    all checks necessary...

    > 1) I don't see a way to return a different string without allocating
    > it in the function body and leaving it to the caller to clean the new
    > string up.


    What you get is a pointer to char [by means of its address], right?
    Supposedly it points to a sequence of characters. Each character in
    that sequence has an address, yes? One of the characters actually
    starts the "token" you need to find. The address of that character you
    will need to return.

    > 2) Why we have a pointer to a pointer as a parameter isn't clear to
    > me. Even after all these years with the Windows API, I don't see the
    > purpose here. Why not just use a const char *?


    The function has the side effect - it needs to change something in
    addition to returning a value. That change can only be made if you pass
    the location of the object that needs to change. If outside it's a
    pointer to const char that is expected to change (i.e. to start pointing
    to another const char), you have to pass that pointer either by
    reference or by its address.

    > These attempts failed with compiler errors, when trying to update the
    > str param
    > str = str + indexOnePastDelimeter; // If it was a const
    > char *, this is what I'd do
    > str =&(*str + indexOnePastDelimeter); // I don't see why the
    > compiler complains about this one
    > str =&((*str)[indexOnePastDelimeter]);
    >
    >
    > I am going to submit a more c++ implementation (below) with a
    > different prototype, because I failed at updating the str parameter in
    > all my attempts and the c-style implementation came out very ugly.
    > However, if anyone can address those 2 issues for me, I'd like to know
    > what the thinking was.


    I am not sure what you'd like to get as an answer, perhaps you want to
    ask more questions, so do.

    >[.. a solution to a problem with different requirements ..]

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Aug 15, 2011
    #2
    1. Advertising

  3. Christopher

    Christopher Guest

    On Aug 15, 2:40 pm, Victor Bazarov <> wrote:
    > In what sense is it unsafe?  You're writing that function.  You can
    > impose any requirements on the data the function receives and introduce
    > all checks necessary...


    Perhaps unsafe is the wrong word. Requires more checking and has more
    room
    for error?

    > What you get is a pointer to char [by means of its address], right?
    > Supposedly it points to a sequence of characters.  Each character in
    > that sequence has an address, yes?  One of the characters actually
    > starts the "token" you need to find.  The address of that character you
    > will need to return.


    That was my original thought, but to really get a "token" back the
    returned pointer must not only point to the address of that character,
    but there must be a '\0' inserted at the end of the token.

    Maybe I am misunderstanding the requirements. I can return the address
    of the first character of the token easily, but then the caller is
    going to have to do something useful with it. Probably calculate the
    token length using the original parameter and the returned pointer and
    create their own null terminated string.
    Christopher, Aug 15, 2011
    #3
  4. On 8/15/2011 4:31 PM, Christopher wrote:
    > On Aug 15, 2:40 pm, Victor Bazarov<> wrote:
    >> In what sense is it unsafe? You're writing that function. You can
    >> impose any requirements on the data the function receives and introduce
    >> all checks necessary...

    >
    > Perhaps unsafe is the wrong word. Requires more checking and has more
    > room
    > for error?


    Room for error is the reverse side of checking (i.e. when checking is
    lacking), so it can't be "and". As the programmer of the function, it's
    your responsibility to provide all the checking and thus make it "safe"
    (or "having no room for error").

    >> What you get is a pointer to char [by means of its address], right?
    >> Supposedly it points to a sequence of characters. Each character in
    >> that sequence has an address, yes? One of the characters actually
    >> starts the "token" you need to find. The address of that character you
    >> will need to return.

    >
    > That was my original thought, but to really get a "token" back the
    > returned pointer must not only point to the address of that character,
    > but there must be a '\0' inserted at the end of the token.
    >
    > Maybe I am misunderstanding the requirements. I can return the address
    > of the first character of the token easily, but then the caller is
    > going to have to do something useful with it. Probably calculate the
    > token length using the original parameter and the returned pointer and
    > create their own null terminated string.


    You're overthinking it. Program as requirements state, and for bonus
    points explain what shortfalls you see in the specification. Since the
    insertion of the null char is not in the requirements, point out to the
    person grading your results that the use of the returning pointer is
    limited if the token is not a true C-string... And offer your
    alternative solution (based on std::string).

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Aug 16, 2011
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    10
    Views:
    698
    Chris Torek
    Feb 4, 2005
  2. jimjim
    Replies:
    16
    Views:
    839
    Jordan Abel
    Mar 28, 2006
  3. Replies:
    4
    Views:
    1,253
    Fred Zwarts
    Jul 2, 2009
  4. A
    Replies:
    7
    Views:
    634
  5. , India

    pointer to an array vs pointer to pointer

    , India, Sep 20, 2011, in forum: C Programming
    Replies:
    5
    Views:
    453
    James Kuyper
    Sep 23, 2011
Loading...

Share This Page