yaml-cpp error while converting Node to a std::string - c++

I want to convert a Node object from yaml-cpp to a std::string. I keep getting an error that says it cannot find the right overloaded operator <<.
Here's my code:
#include <iostream>
#include <string>
#include <yaml-cpp/yaml.h>
using namespace std;
int main(int argc, char* argv[]) {
YAML::Node myNode;
myNode["hello"] = "world";
cout << myNode << endl; // That works but I want that not to stdout
string myString = "";
myNode >> myString; // Error at this line
cout << myString << endl;
return 0;
}
The error is
src/main.cpp:13:12: error: invalid operands to binary expression ('YAML::Node' and 'std::string' (aka 'basic_string<char, char_traits<char>, allocator<char>>')
[somefile] note: candidate function template not viable: no known conversion from 'YAML::Node' to 'std::byte' for 1st argument
operator>> (byte __lhs, _Integer __shift) noexcept
^
[A bunch of these 10+]
Using clang++ -std=c++20 -I./include -lyaml-cpp -o prog main.cpp
Please help me find out!

Actually needed to create an stringstream and then convert it to an normal string:
#include <iostream>
#include <string>
#include <yaml-cpp/yaml.h>
using namespace std;
int main(int argc, char* argv[]) {
YAML::Node myNode;
myNode["hello"] = "world";
stringstream myStringStream;
myStringStream << myNode;
string result = myStringStream.str();
cout << result << end;
return 0;
}
Output:
hello: world

Related

error c2679 binary '=' no operator found which takes right hand operand of type std::tuple

I know there are multiple other questions like this but I've tried all the suggestions I've seen to no avail. I am attempting to write a vector (made of tuples containing a bool, int, and another int) with ostream. I've made sure to add std:: in front of everything it might need as I know that can be the problem often. I would appreciate any help. (the error in question happens at the bottom two lines, specifically the std::copy one, not sure if the rest of the code is important).
#include "Options.h"
#include <fstream>
#include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include <vector>
#include <tuple>
#include <stdbool.h>
#include <stdint.h>
using namespace std;
using namespace smf;
int main(int argc, char** argv) {
Options options;
options.process(argc, argv);
MidiFile midifile;
midifile.read("lowtest.mid");
midifile.linkNotePairs();
midifile.sortTracks();
midifile.joinTracks();
midifile.deltaTicks();
std::tuple <bool, int, int> out;
std::vector <std::tuple<bool, int, int>> outlist;
int track = 0;
int i = 0;
for (int event = 0; event < midifile[track].size(); event++) {
if (midifile[track][event].isNoteOn()) {
out = std::make_tuple(true, (int)midifile[track][event][1], (int)midifile[track][event].getTickDuration());
outlist.push_back(out);
std::cout << std::get<0>(outlist[i]) << ' ' << std::get<1>(outlist[i]) << ' ' << std::get<2>(outlist[i]);
i = i + 1;
std::cout << " " << "I = " << i << std::endl;
}
}
std::cout << "done";
std::ofstream output_file("./output.txt");
std::ostream_iterator<std::tuple <bool, int, int>> output_iterator(output_file, "\n");
std::copy(outlist.begin(), outlist.end(), output_iterator);
return 0;
}
error:
Error C2679 binary '<<': no operator found which takes a right-hand operand of type 'const _Ty' (or there is no acceptable conversion) midiparser C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\iterator 336

c++ arguments aren't accepted into functions

My c++ program is this:
#include <iostream>
#include <cstdlib>
#include <dos.h>
using namespace std;
void arr(int pts,string *splt_msg){
for(int x=-1;x<pts-1;x++){
string input;
cout<<"Enter part "<<x<<endl;
cin>>input;
(*splt_msg)[x]=input;
}
}
void print_arr(string *splt_msg,int del,int parts){
for(int x=-1;x<parts-1;x++){
cout<<(*splt_msg)[x];
delay(del);
}
}
int main(){
cout<<"Parts in message: ";
int parts;
cin>>parts;
cout<<"Delay between parts(ms): ";
int del;
cin>>del;
parts--;
string splt_msg[parts];
string (*Parr)[parts]=&splt_msg;
arr(parts,Parr);
print_arr(Parr,del,parts);
return 0;
}
Here is the error code(on windows and mingw):
c:\Users\User\Desktop\c++>g++ -o program test1.cpp
In file included from test1.cpp:3:0:
c:\mingw\include\dos.h:54:2: warning: #warning "<dos.h> is obsolete; consider using <direct.h> instead." [-Wcpp]
^~~~~~~
test1.cpp: In function 'void arr(int, std::__cxx11::string*)':
test1.cpp:18:14: error: 'delay' was not declared in this scope
delay(del);
^
test1.cpp: In function 'int main()':
test1.cpp:32:17: error: cannot convert 'std::__cxx11::string (*)[parts] {aka std::__cxx11::basic_string<char> (*)[parts]}' to 'std::__cxx11::string* {aka std::__cxx11::basic_string<char>*}' for argument '2' to 'void arr(int, std::__cxx11::string*)'
arr(parts,Parr);
^
test1.cpp:33:27: error: cannot convert 'std::__cxx11::string (*)[parts] {aka std::__cxx11::basic_string<char> (*)[parts]}' to 'std::__cxx11::string* {aka std::__cxx11::basic_string<char>*}' for argument '1' to 'void print_arr(std::__cxx11::string*, int, int)'
print_arr(Parr,del,parts);
^
Does someone know what i have done wrong and the solution?
Thanks for the help, I'm just trying to write a simple program to test some concepts out like passing pointers into functions but it doesn't seem to be working.
This code is more C style then C++. You are doing difficult error prone things. Try using vectors and such
string splt_msg[parts];
should not even evaluate, as parts is not a constant expression.
Try using things like std::vector. and passing by reference. E.g.:
#include <iostream>
#include <string>
#include <vector>
#include <Windows.h>
template<typename T>
T Read() noexcept {
T output{};
std::cin >> output;
return output;
}
void arr(std::vector<std::string>& splt_msg) {
for (auto& msg : splt_msg) {
std::cout << "Enter part \n";
std::cin >> msg;
}
}
void print_arr(std::vector<std::string> const& splt_msg, int delay) {
for (auto& msg : splt_msg) {
std::cout << msg;
Sleep(delay);
}
}
int main() {
std::cout << "Parts in message: ";
auto parts = Read<int>();
std::cout << "Delay between parts(ms): ";
auto delay = Read<int>();
std::vector<std::string> splt_msg(parts);
arr(splt_msg);
print_arr(splt_msg, delay);
}
edit: or even better: use an object
#include <iostream>
#include <string>
#include <vector>
#include <Windows.h>
template<typename T>
T Read() noexcept {
T output{};
std::cin >> output;
return output;
}
class SplitMessage {
private:
std::vector<std::string> splitMessage;
public:
SplitMessage(size_t length) noexcept : splitMessage(length) {}
void GetData() noexcept;
void PrintData(int delay) const noexcept;
};
void SplitMessage::GetData() noexcept {
for (auto& msg : splitMessage) {
std::cout << "Enter part \n";
std::cin >> msg;
}
}
void SplitMessage::PrintData(int delay) const noexcept {
for (auto& msg : splitMessage) {
std::cout << msg;
Sleep(delay);
}
}
int main() {
std::cout << "Parts in message: ";
auto parts = Read<int>();
std::cout << "Delay between parts(ms): ";
auto delay = Read<int>();
SplitMessage splt_msg(parts);
splt_msg.GetData();
splt_msg.PrintData(delay);
}
Both functions require a std::string* (a pointer to a string) as first parameter, but both times you pass std::string*[] (an array of pointers to a string) as first paramater. The solution depends on what you want to achieve, but I guess, you want to call the function for one element of the array with an indexer: print_arr(Parr[0],del,parts);
Some other notes:
for(int x=-1;x<parts-1;x++){cout<<(*splt_msg)[x];...} will access the -1st character of a string, which is UB, but probably just crashes. Should be for(int x=0;x<parts;x++)
string splt_msg[parts]; is no valid C++, since parts is not constant at compile time.

Reading binary data into std::string c++

I am trying to read data from binary file to an std::string.Here is what I have tried at first.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main(int argc, char const *argv[])
{
fstream file("output.bin" , ios::out | ios::binary | ios::in);
string my_str(5, '\0');
file.read(my_str.c_str(), 5);
cout << "String = " << my_str<< endl ;
}
And the compiler gave the error :
error: invalid conversion from ‘const char*’ to ‘std::basic_istream<char>::char_type* {aka char*}’ [-fpermissive]
file.read(my_str.c_str(), 5);
As far as I understand, c_str() returns a const pointer which cannot be used in read method, so I changed my approach a little bit(which you can see below). Is there a better way to do this ?
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main(int argc, char const *argv[])
{
fstream file("output.bin" , ios::out | ios::binary | ios::in);
string my_str(5, '\0');
char buffer[6];
file.read(buffer, 5);
buffer[5] = '\0';
my_str = string(buffer);
cout << "String = " << my_str<< endl ;
}
ps : forgive me if I could not make myself clear, this is my first time here :)
In C++11, the way to get a non-const pointer to the string's data is:
file.read(&my_str[0], 5);
C++17 will introduce non-const data() for this as well:
file.read(my_str.data(), 5);
another way, using standard algorithms:
#include <iostream>
#include <string>
#include <fstream>
#include <algorithm>
#include <iterator>
using namespace std;
int main(int argc, char const *argv[])
{
fstream file("output.bin" , ios::out | ios::binary | ios::in);
auto my_str = string();
copy_n(istream_iterator<char>(file),
5,
std::back_inserter(my_str));
cout << "String = " << my_str<< endl ;
}
std::string is specially designed to work with strings and with c-style strings as well, so this fact will work against you in this situation. For example your code:
char buffer[6];
file.read(buffer, 5);
buffer[5] = '\0';
my_str = string(buffer);
what is wrong with it? You are reading binary data and who guarantees that there won't be '\0' byte there? You can fix it by:
my_str = string(buffer,5);
but this shows the point - std::string as a buffer is not a good choice. So you better use std::vector<char> or even better std::vector<uint8_t> which has method data() but will not implicitly convert from c-string, output to std::ostream etc.

How do I use STL algorithms with ICU's iterators?

I wonder how to use ICU library iterators with STL. For instance, what if we decided to output all permutations of a string?
With std::string it looks like the following:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
static void _usage(const char *executable)
{
cout << "Usage: " << executable << " <string>" << endl;
}
int main (int argc, char const* argv[]) {
if (argc < 2) {
cerr << "Target string expected" << endl;
_usage(argv[0]);
return 1;
}
string s(argv[1]);
do {
cout << s << endl;
} while (next_permutation(s.begin(), s.end()));
return 0;
}
I tried to do the same using ICU:
#include <unicode/unistr.h>
#include <unicode/uchriter.h>
#include <unicode/ustdio.h>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
static void _usage(const char *executable)
{
cout << "Usage: " << executable << " <string>" << endl;
}
int main (int argc, char const* argv[]) {
if (argc < 2) {
cerr << "Target string expected" << endl;
_usage(argv[0]);
return 1;
}
UnicodeString ustr(argv[1]);
UChar *uc = ustr.getBuffer(-1);
int32_t len = u_strlen(uc);
UCharCharacterIterator iter_start(uc, len);
UCharCharacterIterator iter_end(uc, len, len - 1);
do {
// XXX
} while (next_permutation(iter_start, iter_end ));
return 0;
}
But it fails to compile:
x86_64-pc-linux-gnu-g++ -I/usr/include -licuio -licui18n -licuuc -licudata permute2.C -o permute2
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.4/include/g++-v4/algorithm:63:0,
from permute2.C:4:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.4/include/g++-v4/bits/stl_algo.h: In function ‘bool std::next_permutation(_BIter, _BIter) [with _BIter = icu_49::
UCharCharacterIterator]’:
permute2.C:31:49: instantiated from here
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.4/include/g++-v4/bits/stl_algo.h:3531:7: error: no match for ‘operator++’ in ‘++__i’
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.4/include/g++-v4/bits/stl_algo.h:3535:7: error: no match for ‘operator--’ in ‘--__i’
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.4/include/g++-v4/bits/stl_algo.h:3540:4: error: no match for ‘operator--’ in ‘--__i’
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.4/include/g++-v4/bits/stl_algo.h:3541:4: error: no match for ‘operator*’ in ‘*__ii’
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.4/include/g++-v4/bits/stl_algo.h:3541:4: error: no match for ‘operator*’ in ‘*__i’
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.4/include/g++-v4/bits/stl_algo.h:3544:8: error: no match for ‘operator--’ in ‘--__j’
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.4/include/g++-v4/bits/stl_algo.h:3544:8: error: no match for ‘operator*’ in ‘*__i’
...
What's the proper way to make use of STL with ICU? Extend the UCharCharacterIterator class and provide code for all these operators?

c++ sscanf reading string vector

thanks for the support on the previous post... i am now trying to store the vector string on another string and do a sscanf to check for a text eg. "TEXT" and if found append another text at the end of line....
any ideas???
#include <iostream>
#include <vector>
#include <string>
#include <stdio.h>
using namespace std;
int main() {
vector<string> vs;
vector<string>::iterator vsi;
string agent;
string buffer;
string line;
while (!(cin.eof())) {
getline(cin, buffer);
cout << buffer << endl;
vs.push_back(buffer);
};
vsi = vs.begin();
for (int count=1; vsi != vs.end(); vsi++,count++){
cout << "string" << count <<"="<< *vsi << endl;
line = *vsi;
sscanf(line, "%s %[^\n]",text);
//dummy code
if text=="TEXT" do this:
cout << "agent" << text << "endl";
}
else: do nothing
return 0;
}
[root#server dev]# g++ -o newcode newcode.cpp
newcode.cpp: In function ‘int main()’:
newcode.cpp:24: error: cannot convert ‘std::string’ to ‘const char*’ for argument ‘1’ to ‘int sscanf(const char*, const char*, ...)’
[root#server dev]#
UPDATE:
i used line.c_str() on sscanf and gives out this error
#include <iostream>
#include <vector>
#include <string>
#include <stdio.h>
using namespace std;
int main() {
vector<string> vs;
vector<string>::iterator vsi;
string agent;
string buffer;
string line;
while (!(cin.eof())) {
getline(cin, buffer);
cout << buffer << endl;
vs.push_back(buffer);
};
vsi = vs.begin();
for (int count=1; vsi != vs.end(); vsi++,count++){
cout << "string" << count <<"="<< *vsi << endl;
line = *vsi;
cout << "LINE:" << line.c_str() << endl;
sscanf(line.c_str(), "%s %[^\n]",agent);
/* cout << "agent" << agent << "endl"; */
}
return 0;
}
[root#server dev]# g++ -o newcode newcode.cpp
newcode.cpp: In function ‘int main()’:
newcode.cpp:25: warning: cannot pass objects of non-POD type ‘struct std::string’ through ‘...’; call will abort at runtime
[root#server dev]#
what i want to do is when a string on a particular line is detected it will append a text to the end of line and stdout...
It's not entirely clear what you are trying to do but if you want to get the right type passed into sscanf you'll need to change some things around. sscanf only deals with c strings and you've tried to pass it in a c++ string object, to fix this you might want to use line.c_str() in sscanf to get it passed in the right format.
A better approach would be to use a c++ algorithm like string::find though as this will remove the need to use sscanf.
I'm not sure of you want to do, but you should check out string::find : Cplusplus reference
Instead of using sscanf try using stringstream which work nearly the same as cin/cout.