I'm using the boost spirit x3 semantic parser as lambda functions.
I would to like assign the value of string to an "external" variable, but my code doesn't work:
template <typename Iterator>
bool comment(Iterator first, Iterator last)
{
string varName = ""; //<- this is my "extranal" variable
auto do_varName = [&](auto& ctx)
{
cout << "VAR name: " << _attr(ctx) << endl; //This work well
//This don't work; varName is a external variable
varName = std::string( _where(ctx).begin(),
_where(ctx).end()) ;
};
The varName assumed the value of all character that are AFTER the expected content. The output of cout is correct. Why?
Related
I'm practicing <thinking in c++ > for chapter5, ex01:
Write a struct called Lib that contains three string objects a, b, and c.
In main( ) create a Lib object called x and assign to x.a, x.b, and x.c.
Print out the values.
in the beginning, I'm trying:
// ex02.cpp
#include <iostream>
#include <string>
using namespace std;
struct Lib {
string a;
string b;
string c;
};
int main(){
Lib x;
x.a = 1; // here I forgot the string object, and incorrectly assign the wrong value to x.a
x.b = 2;
x.c = 3;
cout << x.a << " " << x.b << " " << x.c << endl;
return 0;
}
and it can compile successfully, but the run result seems only two blank spaces:
[root#VM-0-2-centos ch05]# g++ ex02.cpp
[root#VM-0-2-centos ch05]# ./a.out
[root#VM-0-2-centos ch05]#
at this time I find the wrong assignment. but why it should not give a compile error?
when I modify the assignment to the follows:
x.a = "hello";
x.b = "world";
x.c = "welcome";
it compiles success, and give the right run result:
[root#VM-0-2-centos ch05]# g++ ex02.cpp
[root#VM-0-2-centos ch05]# ./a.out
hello world welcome
[root#VM-0-2-centos ch05]#
my question is why x.a = 1 can compile success?
and when I try:
string test = 1;
it will compile error:
error: invalid conversion from ‘int’ to ‘const char*’ [-fpermissive]
U need to verify my statement by yourself. To see string code.
First, When u declare Lib x, the member of x (a, b, c) will call string constructor. So when assign value to the member of x (x.a = 1), it will call "=operation".
However, string test = 1, it will call constructor.
the most difference is caller. the type of parameter of string constructor is "const char*", but "=operation" can get other type of parameter. So, x.a = 1 at compile is passing.
Note, "int" will cast to a certain type by default.
Thx, #Muqali He, you give me the hint and direction.
I try to understand the string class from here: https://www.cplusplus.com/reference/string/string/operator=/
And I understand a bit more.
for c++98, when I use "=", there is three overload member function:
when I try:
string t2;
t2 = "test";
it's OK. and I try:
string t3;
t3 = 256;
it will get a warning:
warning: overflow in implicit constant conversion
at this time, 256 will be recognized as a char. when you output this value, it will transform into its ASCII code:
string t4;
t4 = 100;
cout << "t4= " << t4 << endl;
the ouput is
t4 = d
if I try:
string t5 = 100; // it will compile error
because there's no corresponding constructor
I'm new to coding in C and C++, and I have a program with
an issue. When I (try) to run it, it gives me this error:
"No suitable constructor exists to convert from "char" to "std::string".
I'm not sure what it means. My code is an example of a simple
substitution cipher covered in the book "Cracking Codes with Python" by Al Sweigart.
I just want to replicate it in C++. Here's my code:
#include <iostream> // for communicating with user
#include <string>
using namespace std;
string symbols = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // all symbols
string encrypt(string msg, string key, string mode) {
string ca = symbols;
string cb = key;
string translated;
if (mode == "decrypt") {
ca, cb = cb, ca;
}
int index = 0;
for (index = 0; index < msg.length(); index++) {
cout << "index is " << index << endl;
int sindex = ca.find(msg[index]); // it works here
cout << "sindex is " << sindex << endl;
string cl = cb[sindex]; // the problem
translated += cl;
}
return translated;
}
int main() {
string msg = "";
string key = "";
string mode = "";
string ciphertext = ""; // our variables
cout << "Enter message: (no spaces please)\n";
cin >> msg;
cout << "Enter key (or \"none\" for using default):\n";
cin >> key;
if (key == "none") {
key = "QWERTYUIOPASDFGHJKLZXCVBNM";
}
cout << "Enter mode: (\"encrypt\" or \"decrypt\")\n";
cin >> mode;
ciphertext = encrypt(msg, key, mode);
cout << "The ciphertext is\n" << ciphertext;
}
For some reason it works with msg on line 17 but not with cb on line 19, even though
they're both std::string. The actual error is on line 19 with string cl = cb[sindex];.
Not even sure what's wrong. It works on line 17 int sindex = ca.find(/*The thing here*/msg[index]);.
(Maybe my Visual Studio 2019 has gone nuts.) If I replace cb with msg it still gives me the
same error. Maybe line 17 is a lucky line? Who knows? But please help, I'm so
confused!
Example
For example:
string MyString = "Normal\tString";
cout << MyString << endl;
produces the following: "Normal String"
Appending the raw string modifier to the string like so:
string MyString = R"(Normal\tString)";
cout << MyString << endl;
produces the following: "Normal\tString"
The Question
Is there a way to append the raw string modifier to a variable containing a string in order to print the raw form of the string contained within the variable?
string TestString = "Test\tString";
cout << R(TestString) << endl;
So you get: "Test\tString"
Is there a way to append the raw string modifier to a variable containing a string in order to print the raw form of the string contained within the variable?
No.
However, you can write a function that substitutes the characters that are defined by escape sequences by an appropriate string, i.e. replace the character '\t' by the string "\\t".
Sample program:
#include <iostream>
#include <string>
// Performs only one substitution of \t.
// Needs to be updated to do it for all occurrences of \t and
// all other escape sequences that can be found in raw strings.
std::string toRawString(std::string const& in)
{
std::string ret = in;
auto p = ret.find('\t');
if ( p != ret.npos )
{
ret.replace(p, 1, "\\t");
}
return ret;
}
int main()
{
std::string TestString = "Test\tString";
std::cout << toRawString(TestString) << std::endl;
}
Output:
Test\tString
This question is tagged as C++11, in which case rolling your own conversion function is probably the best call.
However, if you have a C++14 compiler, you can use the std::quoted stream manipulator:
#include <iostream>
#include <iomanip>
int main() {
string s = "Hello\tWorld!";
std::cout << std::quoted(s) << std::endl; // Prints "Hello\tWorld!"
}
Kind of. This works but it's not a pretty solution:
std::string strToInsert = " insert this "
std::string myRawString = R"(
raw string raw string raw string
raw string raw string raw string
)"; myRawString += strToInsert; myRawString += R"(raw string
raw string raw string raw string
)";
Beginner C++ student here, first ever programming class. Currently learning string functions and input/output files. Trying to put a program together which will look at an existing file for the name 'john' or 'JOHN' in both upper and lower case. Then output the results into another file.
We were told we could convert all instances of the name to upper or lower case (I chose upper) so the the program would output instances of the name regardless what case it is in.
I noted below where I am having one of my problems and I may have more somewhere else which I can't see yet. Wondering if any of you kind folks can help me out with this.
Below is what I have so far and I noted the errors being returned as well.
Thank you so very much for your time and help!!!
#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
bool die(const string & msg);
bool input(string & s, const string & prompt);
bool open(ifstream & fin, const string & fileName);
bool open(ofstream & fout, const string & fileName);
//bool name(const string & line);
bool convert(string & str, string & converted);
int main() {
string inName, outName;
ifstream fin;
ofstream fout;
if (!input(inName, "Name of input file: "))
die("I can't read the name of the input file");
if (!open(fin, inName))
die("I can't open " + inName + " for output");
if (!input(outName, "Name of output file: "))
die("I can't read the name of the input file");
if (!open(fout, outName))
die("I can't open " + outName + " for output");
for (string converted; getline(fin, converted);) {
if (convert(converted)) //<---***HAVING AN ISSUE HERE***
fout << converted << endl;
}
if (fin.rdstate() != (ios::failbit | ios::eofbit))
die("Input file " + inName + " terminated input incorrectly");
fout.close();
if (!fout)
die("Output file " + outName + "had a problem with writing or closing");
fin.close();
cout << "read from " << inName << ", wrote to " << outName << ", ok" << endl;
}// main
bool die(const string & msg){
cout << "Fatal error: " << msg << endl;
exit(EXIT_FAILURE);
}
bool input(string & s, const string & prompt) {
cout << prompt;
return getline(cin, s) ? true : false;
}
bool open(ifstream & fin, const string & fileName){
fin.open(fileName);
return fin ? true : false;
}
bool open(ofstream & fout, const string & fileName){
ifstream tin(fileName);
if (tin) return false;
fout.open(fileName);
return fout ? true : false;
}
//bool name(const string & line){
//return line.find("john") != UINT_MAX;
//}
bool convert(string & str, string & converted)
{
for (short i = 0; i < str.size(); ++i)
converted += toupper(str[i]);
return converted.find("john") != UINT_MAX;
}
Errors I am getting:
Error 1 error C2660: 'convert' : function does not take 1 arguments Line 40
Warning 2 warning C4018: '<' : signed/unsigned mismatch Line 93
3 IntelliSense: too few arguments in function call Line 40
Well, the error message pretty much says it all. The convert function is declared to take two arguments, but you're only passing in one argument.
bool convert(string & str, string & converted)
You need to pass another string reference that takes the converted string.
Off topic: Also, for the sake of security (and maybe you later wanting to switch to other programming languages): Please don't start learning the bad habit of considering everything not 0 to be true.
Things like the following are bound to cause trouble sooner or later:
return fin ? true : false;
hi guys i would like u to help me in my assignment i had try to solve it but there are some of the things that making me :s i knw how to creat the name and id
string Name;
int Id;
bt wt does it mean a pointer to a dynamically allocated array of grades:s:s:S?
i jst knw how to declare a pointer like : double* Grades;
here is the assignment......
Create a Class StudentGrades with the following Data members:
Name : type String
Id: type integer
Grades: a pointer to a dynamically allocated array of Grades. Type is: pointer to double (* double)
It includes the following member functions:
A No-argument Constructor
A Constructor that takes two arguments : a String and an Integer and initializes the Name with the String and the ID with the Integer.
Set and get functions for Name, ID
A print function for Student information. It prints name, Id and the grades.
An overloaded Assignment operator of the Class Objects
A Copy Constructor of the Class Objects
Use the Syntax for the copy constructor and the overloaded assignment operator.
In another file create a C++ program that prompts the user for data to create four objects of the class StudentGrades. The first object (std1) has 5 grades, and the second (std2) has 6 grades and the third (std3) has 4 grades and fourth (std4) has no grades and data.
Then copy std2 into std4 and assign std1 to std3. Then print the details of the four objects
hey i solved my assignment bt iam trying to running it bt it doesn't work can any body please tell me where the problem is n the program
#include <iostream>
using namespace std;
class student_grades{
private:
string name,n;
int Id,i;
double* grades[];
public:
student_grades();
student_grades(sting, int);
student_grades(const student_grades&);
void set(string name,int Id){
cout << "enter the name and the ID";
cin >> n >> i;
n = name;
i = Id;
}
void get(){
return i;
return n;
}
void student_grades (student_grades&opr){
name = name.opr;
Id = Id.opr;
grades[] = grades[].opr;
}
void student_info(){
cout << "the name of the student is:" << name;
cout << "the id for the srudent is:" << Id;
grades = new double[];
cout << "the grades of the student is:" << grades[] << endl;
delete []grades;
}
};
student_grades::student_grades() {}
student_grades::student_grades(string name, int Id) {
name=" ";
Id=0;
}
student_grades::student_grades(const student_grades& copy) {
name=copy.name;
Id=copy.Id;
}
int main() {
student_grades std1;
std1.set();
cin >> std1.grades[5];
std1.get();
student_grades std2;
std2.set();
cin >> std2.grades[6];
std2.get();
student_grades std3;
std3.set();
cin >> std3.grades[4];
std3.get();
student_grades std4;
std4.set();
cin >> std4.grades[];
std4.get();
std1 = std3;
std2 = std4;
cout << std1 << std2 << std3 << std4;
return 0;
}
A dynamically allocated array is an array that isn't given a specific size until run time, unlike a fixed array declaration is at compile time. A declaration of a fixed array looks like:
int grades[500];
That array will allocate memory for 500 integers and stay that way unless you destroy it or resize it.
Creating a dynamically allocated array would look more like this:
int* grades = NULL; // A declaration in your StudentGrades class
int n = <get size from somewhere>; // Makes the size "dynamic"
grades = new int[n]; // This definition could be in your StudentGrades ctor,
// with n being a parameter.
Then you could continue by initializing all of the array elements to 0 or fill up your array with other values as needed. When you're done with the array, clean it up. This could be in your destructor:
delete [] grades;
grades = NULL;