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.
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.
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
elsereturn 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 ) ;
}
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.
#include <iostream>
#include <string>
#include <algorithm>
using std::cin;
using std::cout;
using std::string;
using std::min;
void display(string &str)
{
constint 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);
}
#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' ;
elsereturn 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)