Re: String and interfacing with functions using char*

Discussion in 'C++' started by Alf P. Steinbach, Oct 14, 2013.

  1. On 14.10.2013 21:07, DSF wrote:
    >
    > [...] is there a way to get a C-type string directly into a [std::string] when
    > it's returned through a pointer as a parameter of a function? (And
    > no, unlike strcpy, the API call does not return the output C string
    > like strcpy does.)


    assert( buf_size > 0 );
    std::string s( buf_size, '#' );
    auto const new_length = some_c_function( &s[0], s.size() );
    s.resize( new_length );


    Cheers & hth.,

    - Alf
    Alf P. Steinbach, Oct 14, 2013
    #1
    1. Advertising

  2. On 16.10.2013 00:32, DSF wrote:
    > On Mon, 14 Oct 2013 21:53:25 +0200, "Alf P. Steinbach"
    > <> wrote:
    >
    >> On 14.10.2013 21:07, DSF wrote:
    >>>
    >>> [...] is there a way to get a C-type string directly into a [std::string] when
    >>> it's returned through a pointer as a parameter of a function? (And
    >>> no, unlike strcpy, the API call does not return the output C string
    >>> like strcpy does.)

    >>
    >> assert( buf_size > 0 );
    >> std::string s( buf_size, '#' );
    >> auto const new_length = some_c_function( &s[0], s.size() );
    >> s.resize( new_length );
    >>

    >
    > It seems I've encountered an "oops" moment! I became suspicious
    > when I noticed your "string" is in all lower case whilst mine is not;
    > "String." The String class I've been dealing with is evidently one
    > written by the compiler writers and has nothing to do with STL
    > strings. This was confirmed when a search through the help file for
    > "vector" produced one match having nothing to do with STL.


    Yep. The standard library's "char" based string type is "std::string".
    There's also a "wchar_t" based string type called "std::wstring".

    Both these types are just instantiations of the "std::basic_string"
    class template, which primarily means that in some help files and
    documentation sets you have to look up "std::basic_string".


    > Yet I know
    > my compiler can handle STL code. I browsed through the numerous help
    > files and found one for STL. So I shall now try to interpret the
    > above code.
    >
    > assert( buf_size > 0 );
    > std::string s( buf_size, '#' );
    >
    > These lines assume (and test for) the existence of a buffer of
    > undetermined type (I assume char) and of a known length (buf_size).


    Well I meant "buf_size" as just a required buffer size, like

    int buf_size = 42;


    > string s is created and filled buf_size number of the character #.


    Yes.

    This includes that it allocates a buffer of at least the specified size.

    The buffer is automatically deallocated when the string ceases to exist.


    > The next line made no sense, then made a little more sense, but
    > still makes no sense.
    >
    > auto const new_length = some_c_function( &s[0], s.size() );
    >
    > The first point of confusion was the use of "auto," but research led
    > to the new C++11 definition of the keyword. So we are creating a
    > constant variable of type to be determined by whatever some_c_function
    > returns.


    Yes.


    > (My compiler is so far behind C++11 that the light from C++11 would
    > take 2,346.77 years to reach it.)
    >
    > Beyond this is where things make no sense. Assuming that
    > some_c_function is an arbritrary function returning a string through a
    > pointer as I used in the strcpy example, some_c_function would be
    > handed a reference to the beginning of the string s. That's fine. But
    > the odds aren't very high that some_c_function wants the size as the
    > second parameter and will return the length of the string.


    Oh that's a not uncommon convention.

    Here's an example using the mbstowcs function (multi-byte to wide
    character string) from the standard library:


    Code:
    typedef ptrdiff_t Size;
    typedef Size Index;
    
    void fail( char const message[] )
    {
    cerr << "!" << message << endl;
    exit( EXIT_FAILURE );
    }
    
    std::wstring widened( char const* const s )
    {
    Size const n = strlen( s );
    Size const buffer_size = mbstowcs( 0, s, n );
    if( buffer_size == -1 ) { fail( "invalid multibyte string" ); }
    
    std::wstring result( buffer_size, L'#' );
    Size const n_result_chars = mbstowcs( &result[0], s, n );
    if( n_result_chars == -1 ) { fail( "mbstowcs conversion failed" ); }
    
    assert( 0 <= n_result_chars && n_result_chars <= buffer_size );
    result.resize( n_result_chars );
    return result;
    }
    

    The buffer size is first obtained, and then used to create a buffer of
    the requisite size for the second call.

    In general one will just have to do whatever the C function at hand
    permits and suggests.


    > It also requires an existing string of buf_size length, which is the
    > same problem with using a temporary c-string; the need to know or
    > guess how long of a string some_c_function will return.


    Yes.

    But by using std::string you avoid having to deal with copying and
    deallocation.


    > But I suppose
    > it's not possible for the string to grow as needed. It would need
    > some way to monitor what some_c_function is doing to its pointer. I
    > don't believe there is any kind of operator overloading that would
    > provide a string in these circumstances the information to auto size
    > based on the pointer or reference it feeds to a function.


    Right. One must just somehow or other obtain the required buffer size.
    One way, when the function reports failure for too small buffer, is to
    try repeatedly and double the buffer size each time.


    > In other words, you have to have a buffer of possibly estimated
    > size, whether it be within a string class or located using a char
    > pointer.


    Yes.


    > P.S. This actually came about because I am using my own string class,
    > (which the writing of was a big step in learning C++) yet most of my
    > large classes pass char * for I/O to the class. I'm in the process of
    > trying to convert these classes to use the string class instead, but I
    > keep encountering many places where I can't use a string because of
    > function calls that return their value(s) through pointer parameters.
    > All the extra code to get these values into strings leads to a lot of
    > extra writing and can often get "ugly." Leading me to believe I
    > should just stick to a char * interface in the functions these beasts
    > haunt and leave strings to the more string-friendly places.


    The main contribution of std::string is the automatic buffer allocation
    and deallocation management.


    > I know this is waaay off from the original question, but I figured
    > I'd ask it in STL string terms familiar to the group and leave the
    > burden of converting it into my particular needs to me.


    For documentation of std::string, look at
    <url: http://en.cppreference.com/w/cpp/string/basic_string>


    Cheers & hth.,

    - Alf
    Alf P. Steinbach, Oct 16, 2013
    #2
    1. Advertising

  3. On 16.10.2013 00:32, DSF wrote:
    > (My compiler is so far behind C++11 that the light from C++11 would
    > take 2,346.77 years to reach it.)
    >


    For Windows, for old PC with smallish memory look at

    <url: http://nuwen.net/mingw.html>

    Prince Nuwen was a master programmer in Vernor Vinge's galactic zones
    novels. STL who maintains the above g++ distro is also a master
    programmer, maintaining the standard library at Microsoft. And
    incidentally with the same initials as the Standard Template Library.

    If you have a modern PC, still Windows, but enough memory, then look at

    <url:
    http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-for-windows-desktop>

    for Visual C++.

    Very nice product when you use info available on the web to configure
    colors and not-all-uppercase menus, BUT it's a pretty huge download.

    For *nix you should have g++ already.

    Not sure about Mac but look around at e.g.
    <url: https://developer.apple.com/technologies/tools/>.

    All the above are FREE offerings.


    Cheers & hth.,

    - Alf
    Alf P. Steinbach, Oct 16, 2013
    #3
  4. Alf P. Steinbach

    Geoff Guest

    On Wed, 16 Oct 2013 02:46:46 +0200, "Alf P. Steinbach"
    <> wrote:

    >On 16.10.2013 00:32, DSF wrote:
    >> (My compiler is so far behind C++11 that the light from C++11 would
    >> take 2,346.77 years to reach it.)
    >>

    >
    >For Windows, for old PC with smallish memory look at
    >
    ><url: http://nuwen.net/mingw.html>
    >
    >Prince Nuwen was a master programmer in Vernor Vinge's galactic zones
    >novels. STL who maintains the above g++ distro is also a master
    >programmer, maintaining the standard library at Microsoft. And
    >incidentally with the same initials as the Standard Template Library.
    >
    >If you have a modern PC, still Windows, but enough memory, then look at
    >
    ><url:
    >http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-for-windows-desktop>
    >
    >for Visual C++.
    >
    >Very nice product when you use info available on the web to configure
    >colors and not-all-uppercase menus, BUT it's a pretty huge download.
    >
    >For *nix you should have g++ already.
    >
    >Not sure about Mac but look around at e.g.
    ><url: https://developer.apple.com/technologies/tools/>.
    >
    >All the above are FREE offerings.
    >
    >


    Good compiler advice all around. Xcode on the Mac is absolute fun to
    use whether you are coding Objective C or C++. Writing in the IDE
    feels like it's almost reading your mind at times.
    Geoff, Oct 16, 2013
    #4
  5. On 18.10.2013 13:18, Juha Nieminen wrote:
    >
    > Personally, I just use Emacs for editing because I can make it work like
    > I want. It's not perfect (because it doesn't have eg. autocompletion),
    > but I'm such an unix old-fogey that I just don't like anything else.
    > (And no, Emacs will probably not suit you because, while configuring it
    > to do whatever you want is possible, it's extremely laborious. Basically
    > you would have to learn elisp to such degree that you can call yourself
    > a fluent elisp programmer.)


    I think every programmer should have created at least one editor,
    without using an edit control.

    I can see that work lined up for me now, because I want some basic
    functionality that's not offered by edit controls or packages like the
    one Notepad++ is built on (Scintilla? whatever). However, it will
    probably not be a complete editor. Just text presentation with two or
    three fonts, plus a movable edit field.

    The last time around was in the early 80's, for the HP3000 under MPE/IV
    OS, with much leveraging of programmable function keys in HP terminals
    (they had these cute 8 little windows at the bottom of the screen
    showing the current fkey assignments). He he. I still have that on tape.


    Cheers,

    - Alf
    Alf P. Steinbach, Oct 18, 2013
    #5
  6. On 18.10.2013 00:15, DSF wrote:
    >
    > &s[0] works with STL string, but produces the error "Must take address
    > of a memory location."


    Presumably this is a typo, where the intended meaning was

    << &s[0] works with STL string, but with the String class it produces
    the error "Must take address of a memory location." >>

    If String::eek:perator[] returns a character value rather than a reference
    then that can cause such an error message. You will then just have to
    find some other way of obtaining a pointer to its buffer. Provided there
    IS a guaranteed buffer -- std::string guarantees a contiguous buffer,
    but the String class you've been using may not necessarily offer that
    guarantee.


    Cheers & hth.,

    - Alf
    Alf P. Steinbach, Oct 19, 2013
    #6
  7. Alf P. Steinbach

    Jorgen Grahn Guest

    On Fri, 2013-10-18, Paavo Helde wrote:
    > Juha Nieminen <> wrote in news:l3r5db$25o7$1
    > @adenine.netfront.net:
    >
    >> I want. It's not perfect (because it doesn't have eg. autocompletion),
    >> but I'm such an unix old-fogey that I just don't like anything else.


    "Autocompletion" makes me think of M-x dabbrev-expand. It's unaware
    of C++ -- it simply sees all open buffers as a sequence of words,
    available for expansion -- but that doesn't feel like a problem for
    me.

    > Have you tried ctags/etags/GNU Global with emacs? I'm vaguely thinking
    > about trying to get autocompletion into emacs myself, but so far lacking a
    > bit motivation.


    Tags is also an essential (albeit imperfect) feature. If you write
    code in Emacs or vi and don't use it, you're missing out.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
    Jorgen Grahn, Oct 20, 2013
    #7
  8. Alf P. Steinbach

    Guest

    On Wednesday, 30 October 2013 02:37:08 UTC, DSF wrote:
    > >
    > >> &s[0] works with STL string, but produces the error "Must take address
    > >> of a memory location."

    > >
    > >Presumably this is a typo, where the intended meaning was
    > >
    > ><< &s[0] works with STL string, but with the String class it produces
    > >the error "Must take address of a memory location.">

    >
    > I just tried changing:
    > char operator [] (int index) const {return str[index];}
    > to
    > char& operator [] (int index) const {return str[index];}
    >
    > and it works. It still functions like above, but can also be used as
    > a pointer, as in &str[0].


    No no NO! DON'T do this.

    The member function explicitly operates only on const objects.
    NEVER hand out mutable references from const member functions.
    Separate the functionality between const and non-const members:

    char& operator[](size_t const index) { return str[index]; }
    char operator[](size_t const index) const { return str[index]; }

    (the latter could, like std::string, return a char const&).
    , Oct 30, 2013
    #8
  9. Alf P. Steinbach

    Guest

    On Friday, November 1, 2013 2:08:58 PM UTC-5, DSF wrote:

    > To continue this OT discussion for one more item. Back then
    > everything was *DOCUMENTED*, right down to the support chips! There
    > were even books that fully documented the ROM code in the computer and
    > external floppies. These days, every company (except for CPU mfgrs.)
    > guard the slightest detail of their hardware as though it was a matter
    > of national security. Not that you can get at the hardware as easily,
    > anyway.
    >


    "I agree that my submission of this employment application
    does not obligate the Company (Bloomberg L.P., its
    subsidiaries, divisions and any affiliated entities,
    collectively "the Company") to employ me, or to offer me
    employment."

    I came across that in a job advertisement. They sound
    paranoid, but I guess the job market is so bad they have
    to add stuff like that. I recommend to start a company
    if you haven't already.

    Brian
    Ebenezer Enterprises - In G-d we trust.
    http://webEbenezer.net
    , Nov 3, 2013
    #9
  10. Alf P. Steinbach

    Guest

    On Wednesday, 16 October 2013 01:46:46 UTC+1, Alf P. Steinbach wrote:
    > On 16.10.2013 00:32, DSF wrote:
    >
    > > (My compiler is so far behind C++11 that the light from C++11 would
    > > take 2,346.77 years to reach it.)

    >
    > For Windows, for old PC with smallish memory look at
    > <url: http://nuwen.net/mingw.html>
    >
    > Prince Nuwen was a master programmer in Vernor Vinge's galactic zones
    > novels.


    ITYM "Pham Nuwen"

    <snip>
    , Nov 5, 2013
    #10
    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. wwj
    Replies:
    7
    Views:
    526
  2. wwj
    Replies:
    24
    Views:
    2,462
    Mike Wahler
    Nov 7, 2003
  3. lovecreatesbeauty
    Replies:
    1
    Views:
    993
    Ian Collins
    May 9, 2006
  4. Replies:
    3
    Views:
    710
  5. Ian Collins
    Replies:
    0
    Views:
    142
    Ian Collins
    Oct 14, 2013
Loading...

Share This Page