I have a vector of strings in C++, named lines.
This line
std::cout << "First line: >" << lines[0] << "<" << std::endl;
prints ">irst line: >string_here" instead of "First line: >string_here<".
Why does cout start printing at the start of the current line after the string, and how can I resolve it? I also tried to flush after every cout but result was the same.
This is a full code that ilustrates my problem, BEFORE it was solved:
#include <iostream>
#include <vector>
#include <string.h>
std::vector<std::string> parse(char *buffer, const char *delimiter) {
std::string buff(buffer);
size_t pos = 0;
std::string part;
std::vector<std::string> parts;
while ((pos = buff.find(delimiter)) != std::string::npos) {
part = buff.substr(0, pos);
parts.push_back(part);
buff.erase(0, pos + 1);
}
parts.push_back(buff);
return parts;
}
int main() {
char *s;
s = strdup("Many lines\r\nOf text");
std::cout << s << std::endl; // this should print the string how it is
std::vector<std::string> lines;
lines = parse(s, "\n"); // parsing the string, after "\n" delimiter
// that was the problem, I should have parsed after "\r\n"
std::cout << "First line: >"<< lines[0] << "<" << std::endl; // output
}
It's impossible to be sure without the full content of lines[0], but my (educated) guess would be that lines[0] ends with \r, the carriage return character, so everything printed after lines[0] is printed a the beginning of the line.
Related
Suppose I have
istringstream input("x = 42\n"s);
I'd like to iterate over this stream using std::istream_iterator<std::string>
int main() {
std::istringstream input("x = 42\n");
std::istream_iterator<std::string> iter(input);
for (; iter != std::istream_iterator<std::string>(); iter++) {
std::cout << *iter << std::endl;
}
}
I get the following output as expected:
x
=
42
Is it possible to have the same iteration skipping spaces but not a newline symbol? So I'd like to have
x
=
42
\n
std::istream_iterator isn't really the right tool for this job, because it doesn't let you specify the delimiter character to use. Instead, use std::getline, which does. Then check for the newline manually and strip it off if found:
#include <iostream>
#include <string>
#include <sstream>
int main() {
std::istringstream input("x = 42\n");
std::string s;
while (getline (input, s, ' '))
{
bool have_newline = !s.empty () && s.back () == '\n';
if (have_newline)
s.pop_back ();
std::cout << "\"" << s << "\"" << std::endl;
if (have_newline)
std::cout << "\"\n\"" << std::endl;
}
}
Output:
"x"
"="
"42"
"
"
If you can use boost use this:
boost::algorithm::split_regex(cont, str, boost::regex("\s"));
where "cont" can be the result container and "str" is your input string.
https://www.boost.org/doc/libs/1_76_0/doc/html/boost/algorithm/split_regex.html
I have some code that takes in a paragraph and starts a new line after every sentence.
I would like to buffer the output in the terminal with a new line, but adding "std::cout << endl;" outside of the loop does not seem to work. Any help in separating the input from the output if it is typed into a terminal.
I have commented out the code I expected to work, but which does not.
#include <iostream>
#include <string>
using namespace std;
int main() {
// std::cout << std::endl;
for (;;) {
string line;
getline(std::cin, line);
if (!cin) {
break;
}
for (unsigned int i = 0; i < line.length(); ++i) {
const string text = line.substr(i, 1);
if (text == "." || text == "?" || text == "!") {
std::cout << text;
std::cout << std::endl;
}else{
std::cout << text;
}
}
}
// std::cout << std::endl;
return 0;
}
The commented line will never work since it will never be called. You have an endless loop for(;;) before it.
I have a code that i want it to get input file from command line and create output file with XXX at the end - meanning if intput= "blabla.txt" or "/johny/first/blabla.txt" i till get "blablaXXX.txt" or "/johny/first/blablaXXX.txt"
The second question is that when i find a line i was looking for i want to copy only the numbers (keep in date mode) and the len
Line will be "IT IS HERE time 12:04:56.186, len 000120"
And i want to get in the new file line: 12:04:56.186 120
#include <iostream>
#include <fstream>
using namespace std;
int main( int argc, char* args[] )
{
string inputName=args[1];
ifstream inputName(inputFileName);
////// here i will need to get the output string name some thing like
// string outputFileName=EDITED_INPUT_NAME+"XXX"+".txt";
ofstream outpuName(outputFileName);
while( std::getline( inputName, line ) )
{
if(line.find("IT IS HERE") != string::npos)
// how to make it take only the parts i need??????
outpuName << line << endl;
cout << line << endl;
}
inputName.close();
outpuName.close();
return 0;
}
Does this solve your problem:
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
int main(int argc, char* args[]) {
ifstream inputFile(args[1]);
// Your first problem
string outputFileName(args[1]);
outputFileName.insert(outputFileName.find("."), "XXX");
cout << "Writing to " << outputFileName << endl;
// End of first problem
ofstream outputFile(outputFileName.c_str());
string line;
while (getline(inputFile, line)) {
if (line.find("IT IS HERE") != string::npos) {
// Your second problem
string::size_type time_start = line.find("time ") + 5;
string::size_type time_end = line.find(",", time_start);
cout << time_start << " " << time_end << endl;
string time = line.substr(time_start, time_end - time_start);
string::size_type len_start = line.find("len ") + 4;
string::size_type len_end = line.find(" ", len_start);
if (len_end != string::npos)
len_end += 4;
int len = atoi(line.substr(len_start, len_end - len_start).c_str());
// End of second problem
outputFile << time << " " << len << endl;
cout << time << " " << len << endl;
}
}
inputFile.close();
outputFile.close();
return 0;
}
Example input:
sdfghjk sdfghjk fghjkl
IT IS HERE time 12:04:56.186, len 000120
usjvowv weovnwoivjw wvijwvjwv
IT IS HERE time 12:05:42.937, len 000140
Example output:
12:04:56.186 120
12:05:42.937 140
The code could look nicer with std::regex and auto, but as this wasn't tagged with C++11, I held back.
I am wondering how I can check if the getline function, let's say on string buffer and ifstream input: getline(input, buffer), stores a blank line?
So lets say I had:
Hello
How are you
So how could I identify based on the string buffer if I am dealing with a newline? I need this for formatting checking in a much more complicated file. Thanks.
After you get the string buffer, you can check:
if (get_trimmed_string(buffer).length == 0)
{
// this line is a blank line, or contains only spaces/tabs
}
And the function to trim spaces or tabs can be something like:
// delete spaces/tabs in head and tail of str
string get_trimmed_string(string str)
{
int s=str.find_first_not_of(" \t");
int e=str.find_last_not_of(" \t");
// if do find real content
if (s!=-1 && e!=-1)
return str.substr(s, e-s+1);
return "";
}
Add a function to check whether it has only white space characters.
#include <iostream>
#include <string>
bool isBlankLine(char const* line)
{
for ( char const* cp = line; *cp; ++cp )
{
if ( !isspace(*cp) ) return false;
}
return true;
}
bool isBlankLine(std::string const& line)
{
return isBlankLine(line.c_str());
}
int main()
{
std::string s1 = "Hello";
std::string s2 = " ";
std::string s3 = "How are you";
std::cout << "Is s1 blank? " << isBlankLine(s1) << std::endl;
std::cout << "Is s2 blank? " << isBlankLine(s2) << std::endl;
std::cout << "Is s3 blank? " << isBlankLine(s3) << std::endl;
return 0;
}
Here's the output:
Is s1 blank? 0
Is s2 blank? 1
Is s3 blank? 0
I have a string with large content. I have to separate out content of string before the first newline character and after the newline character.
string content is as follows:
std::string = "exption is theo from my fimnct!
mt nsamre id kjsdf dskfk djfhj
/vonsfs/sdvfs/sdvjisd/dd.so
dfjg dfk dflkkm sdfk "
from above i have to get the content of first line upto the newline charcter in another string and keep the other content remain unchanged. The characters in first line are not fixed. it is variable sting.
What about string::substr and string::find:
#include <iostream>
int main()
{
std::string s = "foo\nbar";
std::cout << "first line: " << s.substr(0, s.find('\n')) << "\n";
}
You would do this like this:
std::string first, second, all = "...";
size_t pos = all.find('\n')
if(pos != std::string::npos)
{
first = all.substr(0, pos);
second = all.substr(pos+1);
}
Try std::algorithms:
int main (void)
{
std::string input(
"exption is theo from my fimnct!\n"
"mt nsamre id kjsdf dskfk djfhj\n"
"/vonsfs/sdvfs/sdvjisd/dd.so\n"
"dfjg dfk dflkkm sdfk"
);
std::string first_line(input.begin(), std::find(input.begin(), input.end(), '\n'));
std::string rest_lines(std::find(input.begin(), input.end(), '\n'), input.end());
std::cout << first_line << std::endl;
std::cout << "---" << std::endl;
std::cout << rest_lines << std::endl;
return 0;
}
This prints out
exption is theo from my fimnct!
---
mt nsamre id kjsdf dskfk djfhj
/vonsfs/sdvfs/sdvjisd/dd.so
dfjg dfk dflkkm sdf
std::string::substr and std::string::find_first_of