For example if the input was:
My name is Alex and
I also love coding
The correct output should be:
1:My nam
1:e is A
1:lex an
1:d
2:I also
2: love
2:coding
So far I have this
int main () {
string i;
i.substr(0,6);
while (getline(cin, i)) {
cout << i << endl;
}
}
CodePudding user response:
Using ranges, what you ask is almost as easy as
auto result = view | split('\n') | transform(chunk(6));
where view
represents somehow the input, | split('\n')
splits that input in several lines, and | transform(chunk(6))
transforms each line by splitting it in chunks of 6 char
s. The result
is therefore a "range of ranges of chunks", on which you can loop with a double nested for
.
Here's a full example:
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <range/v3/range/conversion.hpp>
#include <range/v3/view/chunk.hpp>
#include <range/v3/view/istream.hpp>
#include <range/v3/view/split.hpp>
#include <range/v3/view/transform.hpp>
// Comment/uncomment the line below
//#define FROM_FILE
using namespace ranges;
using namespace ranges::views;
int main() {
// prepare a path-to-file or string buffer
#ifdef FROM_FILE
std::string path_to_file{"/path/to/file"};
#else
std::basic_stringbuf<char> strbuf{"My name is Alex and\nI also love coding"};
#endif
// generate an input stream from the file or the string buffer
#ifdef FROM_FILE
std::ifstream is(path_to_file);
#else
std::istream is(&strbuf);
#endif
// prevent the stream from skipping whitespaces
is >> std::noskipws;
// generate a range view on the stream
ranges::istream_view<char> view(is);
// manipulate the view
auto out_lines = view | split('\n') // split at line breaks
| transform(chunk(6)); // split each in chunks of 6
// output
int index{};
for (auto line : out_lines) {
index;
for (auto chunk_of_6 : line) {
std::cout << index << ':'
<< (chunk_of_6 | to<std::string>)
<< std::endl;
}
}
}
CodePudding user response:
First I suggest that you give your variables meaningful names. i
isn't good for a variable you use to read lines from std::cin
. I've changed that name to line
in my example below.
You are on the right track with i.substr(0,6);
but you've placed it outside of the loop where i
is empty - and you don't print it.
You are also supposed to prepend each line with the line number but that part is completely missing.
You have also missed that you should print the next 6 characters of the read line on the next line until you've printed everything that you read.
Here's an example how that could be fixed:
#include <iostream>
#include <string>
int main() {
unsigned max_len = 6;
std::string line;
for(unsigned line_number = 1; std::getline(std::cin, line); line_number) {
// loop until the read line is empty:
while(!line.empty()) {
// print max `max_len` characters and prepend it with the line number:
std::cout << line_number << ':' << line.substr(0, max_len) << '\n';
// if the line was longer than `max_len` chars, remove the first
// `max_len` chars:
if(line.size() > max_len) {
line = line.substr(max_len);
} else { // otherwise, make it empty
line.clear();
}
}
}
}