Pulling strings out of a string without stringstream

I realize I'm overcomplicating things but my thought process is this. I have a string called "description" all I want to do is break it up into 76 character lines and instantly display them, why should I have to use stringstream. perhaps if I wanted to save them in an array stringstream would make more sense, but I am trying to get better at pointers and it seem as though there should be a way to recursively point to a section of a string with a pointer and retrieve that information. Here was my attempt at it:
1
2
3
4
5
6
7
8
9
10
11
12
  void displayDescription(){
        /* In case the description is more than one
         * line, I want to break it into multiple lines */
        size_t rowCnt = description.length() / descriptionWidth;
        if( description.length() % descriptionWidth > 0 ) rowCnt++;
        string *descLine[ descriptionWidth +1 ];
        for( size_t i = 0; i < rowCnt; i++ ){
            descLine = &( description + ( descriptionWidth * i ) ) ;
            *descLine = descLine + '\0';
            cout << *descline; 
        }
        delete descLine;

description is a string which would be somewhat variable in length
descriptionWidth is a preprocessor definition of 76

It goes without saying that the pointer assignment is what is giving me trouble. I'm not sure about the next line either. I'm still horrible with pointers.
Since your dealing with std::strings and you don't want to use stringstreams, have you considered std::string.substr()?

Where have you allocated memory for that pointer?

I realize I'm overcomplicating things but my thought process is this. I have a string called "description" all I want to do is break it up into 76 character lines and instantly display them, why should I have to use stringstream.


One can achieve a lot by reading each char up to the limit (76), then printing that string.

perhaps if I wanted to save them in an array stringstream would make more sense, but I am trying to get better at pointers and it seem as though there should be a way to recursively point to a section of a string with a pointer and retrieve that information. Here was my attempt at it:


To be honest IMO, this looks like a messy mixture of C and C++. IMO either write C or write C++.

There is a problem with your pointer arithmetic on line 8. It looks like you are invoking the + operator for std::string instead. If doing Pointer math, start with an address, then add a number to it. But you might run into difficulties with the internal structure of std::string, maybe you should deal with the c string version of the std::string instead?

description is a string which would be somewhat variable in length
descriptionWidth is a preprocessor definition of 76


Don't use global variables or preprocessor definitions. Pass the variables to the function, and use const variables instead.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
std::string split( std::string text, std::size_t line_size )
{
    if( text.size() <= line_size ) return text ;

    auto pos = text.find( '\n' ) ; // the string may already contain new-line characters

    if( pos == std::string::npos || pos > line_size ) // if there is no new-line is not within line_size
    {
       pos = text.find_last_of( " \t", line_size ) ; // find the last white-space before line_size
       if( pos != std::string::npos ) text[pos] = '\n' ; // and make it a new line
       else return text ; // too bad; can't reasonably split this
    }

    // split the rest of the string and append it to the substring ending with the new-line
    return text.substr( 0, pos+1 ) + split( text.substr(pos+1), line_size ) ;
}

http://coliru.stacked-crooked.com/a/abec30f3051e6eb2
There's no need to extract from the string at all. If you want to write 76 characters from a string then use ostream::write(). The program below reads up to 1000 characters from cin and then writes them out in 76-character lines.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <string>
#include <algorithm>

using std::cin;
using std::cout;
using std::string;
using std::min;

void display(string &str)
{
    const int width=76;
    for (size_t start=0; start < str.size(); start += width) {
        size_t end = min(str.size(), start+width);
        cout.write(&str[start], end-start);
        cout << '\n';
    }
}


int
main()
{
    // Create a string with 1000 characters and read up to 1000
    // chars into it.  Then truncate it to number actually read
    string str(1000, '\0');
    cin.read(&str.front(), 1000);
    str.resize(cin.gcount());

    display(str);
}

> use ostream::write()
> The program below reads up to 1000 characters from cin and then writes them out in 76-character lines.

This is delectably ludicrous.

Break ....................... inflict abasement ........................
into
1
2
....................... inflict a
basement ........................


Break text already containing a new line after every 72 lines into an unreadable kangaroo form.

etc.
This is delectably ludicrous.

Hey, I didn't make the requirements, that's what the OP wanted :).

My main point is that there's no need to incur the overhead of splitting the string up.
> My main point is that there's no need to incur the overhead of splitting the string up

It is not difficult to demonstrate that without writing palooka code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <string>

std::string& insert_new_lines( std::string& text, std::size_t line_size, std::size_t start = 0 )
{
    if( text.size() <= (start+line_size) ) return text ;

    auto pos = text.find( '\n', start ) ;

    if( pos == std::string::npos || pos > (start+line_size) )
    {
       pos = text.find_last_of( " \t", start+line_size ) ;
       if( pos != std::string::npos ) text[pos] = '\n' ;
       else return text ;
    }

    return insert_new_lines( text, line_size, pos+1 ) ;
}

int main()
{
    std::string description = "std::basic_string\n=================\n\n"
                              "The templated class std::basic_string generalizes how sequences of characters "
                              "are manipulated and stored. String creation, manipulation, and destruction "
                              "are all handled by a convenient set of class methods and related functions.\n\n"
                              "Several specializations of std::basic_string are provided for commonly-used "
                              "types. (cppreference.com)" ;

    std::cout << insert_new_lines( description, 64 ) << '\n' ;
}

std::basic_string
=================

The templated class std::basic_string generalizes how sequences
of characters are manipulated and stored. String creation,
manipulation, and destruction are all handled by a convenient
set of class methods and related functions.

Several specializations of std::basic_string are provided for
commonly-used types. (cppreference.com)

http://coliru.stacked-crooked.com/a/dbc8e5e90452aebf
Topic archived. No new replies allowed.