I am trying to push back 3 vectors in parallel, and when I get to push_back() into the string vector, I get this error:
no instance of overloaded function "std::vector<_Ty, _Alloc>::push_back [with _Ty=std::string, _Alloc=std::allocator<std::string>]" matches the argument listC/C++(304)
ask3.cpp(38, 8): argument types are: (int)
ask3.cpp(38, 8): object type is: std::vector<std::string, std::allocator<std::string>>
Here is the chunk of code that I'm in:
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
int main()
{
int length, count = 0, moviecount = 0, spacecount = 0;
;
vector<int> status, price;
vector<string> movies;
string FileName, text, line, dummy;
FileName = "MovieList.txt";
ifstream InFile;
InFile.open(FileName);
while (!InFile.eof()) {
getline(InFile, line);
text += line + "\n";
}
cout << text;
length = text.length();
for (int i = 0; i <= length; i++) {
if (text[i] == ' ') {
spacecount++;
}
}
if (spacecount == 2) {
moviecount = 1;
}
else if (spacecount > 2) {
int temp = spacecount;
temp = temp - 2;
temp = temp / 3;
moviecount = 1 + temp;
}
movies.push_back(moviecount); //<-- problem line
status.push_back(moviecount);
price.push_back(moviecount);
}
movies is a vector of string, so you cannot push int directly.
If you are using C++11 or later, you can use std::to_string to convert integers to strings.
Another way to convert integers to strings is using std::stringstream like this:
std::stringstream ss;
ss << moviecount;
movies.push_back(ss.str());
This is because you are trying to push int values in a vector movies that is initialized to store string values.
Not sure what you are trying to get out of this code but
You can either change the vector's type to int like so : vector<int> movies or convert int to string using std::to_string() before push_back() like so :
movies.push_back(std::to_string(moviecount))
I am studying pointers in C++. I have studied call by value and call by reference concept. I am trying to create a function to reverse a string which accepts a pointer to string and the size of string. The code is as follow
void reverse(string* str, int size)
{
int start = 0;
int end = size - 1;
while(start < end)
{
swap(*str[start++], *str[end--]);
}
}
int main()
{
string str = "Something";
reverse(&str, str.length());
cout << "Reversed string: " << str << endl;
return 0;
}
I am getting this error:
error: no match for ‘operator*’ (operand type is ‘std::string’ {aka
‘std::__cxx11::basic_string’})
12 | swap(*str[start++], *str[end--]);
I don't want to use the character array, is there way to do it?
Someone please explain, what's wrong in my code. Thank you.
Here is the simple fix. You don't need to change anything except a few lines.
#include <iostream>
#include <algorithm>
#include <cstring>
void reverse( std::string* str ) // no need to pass size to this function
{
int start = 0;
int end = str->length() - 1; // get the length of str like this
char* ptrToCharArray = const_cast<char*>( str->c_str() ); // gets the pointer to str's internal buffer
while ( start < end )
{
std::swap( ptrToCharArray[start++], ptrToCharArray[end--] ); // no need to use * operator anymore
}
}
int main()
{
std::string str = "Something";
reverse( &str );
std::cout << "Reversed string: " << str << std::endl;
return 0;
}
Output is:
Reversed string: gnihtemoS
Hopefully, this helps you.
Just need a little bit of change in your code
Change this *str[start++] to (*str).at(start++)
void reverse(string* str, int size)
{
int start = 0;
int end = size - 1;
while(start < end)
{
swap((*str).at(start++),(*str).at(end--));
}
}
int main()
{
string str = "Something";
reverse(&str, str.length());
cout << "Reversed string: " << str << endl;
return 0;
}
Note that there is no need to pass the size of the string as an argument to the function. You can use the member function std::string::size for that purpose as shown below:
Version 1: Passing pointer to string as argument
#include <iostream>
#include <algorithm>
void reverse(std::string *str)
{
int n=(*str).size()-1;//dereference the pointer and use size member function on the resulting string object
for(int i=0;i<((*str).size()/2);i++){
//Using the swap method to switch values at each index
std::swap((*str).at(i),(*str).at(n)); //note this can also be written as std::swap((*str)[i],(*str)[n]);
n = n-1;
}
}
int main()
{
std::string myString = "myString";
reverse(&myString);
std::cout<<"Reversed string is: "<<myString<<std::endl;
return 0;
}
In version 1, *(str) gives us a std::string type object. Next we call size member function on this std::string object. Similarly we can call the std::string::at member function on this std::string object.
Version 2: Passing reference to string as argument
#include <iostream>
#include <algorithm>
void reverse( std::string &str)
{
int n=str.size()-1;
for(int i=0;i<(str.size()/2);i++){
//Using the swap method to switch values at each index
std::swap(str.at(i),str.at(n));
n = n-1;
}
}
int main()
{
std::string myString = "myString";
reverse(myString);
std::cout<<"Reversed string is: "<<myString<<std::endl;
return 0;
}
I was writing a code that would substitute some random 17 character strings into a single alphabet, and I can't find a way. Basically, what I'm trying to do is this:
char strings[] = {
"L-nIbhm5<z:92~+,x",
"9bC5f0q#qA(RKZ>|r",
"9bC5f0q#qA(RKZ>|r",
"k=5,ln(08IAl(gGAK",
"|N,8]dGu)'^MaYpu[",
"!&,Y*nz8C*,J}{+d]",
"Us9%^%?n5!~e##*+#",
"zF8,1KV#¥]$k?|9R#",
"0B4>=nioEjp>4rhgi",
}
char alphabet[]{
"a","b","c","d","e","f","g","h","i",
}
replace(std::string str){
/**get str and then see the index of the corresponding string in strings[], and replace the string with alphabet[index number], while deleting the original string part that was replaced**/
int main(){
cin >> std::string replace;
replace(replace);
example input: L-nIbhm5<z:92~+,x9bC5f0q#qA(RKZ>|r9bC5f0q#qA(RKZ>|r
expected output: abc
EDIT:
New Code
Changes from the original code
It also has a bigger array than the simplified version(previous code). It displays the structure of the full program.(where the strings are routed to and why)
Basically What it's doing
getting input from user, put it in the input variable, input goes through algorithm() function untouched, and then goes to the replace function and is replaced. It then the replaced string gets returned back through the original route to the main function, where it is displayed.
I've kept the arrays a string type because the const char* gave me a segmentation error.
std::string Subs[53]=
{
"LQlMv]G5^^1kcm?fk",
"7W^S;/vB(6%I|w[fl",
"<w7>4f//Z55ZxK'z.",
"_W5g(lu<pTu3^_A7n",
"OfLm%8:EF}0V1?BSS",
"|+E6t,AZ~XewXP17T",
"L-nIbhm5<z:92~+,x",
"L-nIbhm5<z:92~+,x",
"9bC5f0q#qA(RKZ>|r",
"9bC5f0q#qA(RKZ>|r",
"k=5,ln(08IAl(gGAK",
"|N,8]dGu)'^MaYpu[",
"!&,Y*nz8C*,J}{+d]",
"Us9%^%?n5!~e##*+#",
"zF8,1KV#¥]$k?|9R#",
"0B4>=nioEjp>4rhgi",
"EG#0[W9.N4i~E<f3x",
"(0Pwkk&IPchJHs.7A",
"7XgmQ6fW<|J+NY[m0",
".g4CwX/DU!!~!zbtZ",
"+_U'qn_/9Fo|gT/!n",
"=0s(mYh&F%y=MBS5(",
"cg71(}bo+Q5P8F[T6",
"lc|a\%5.9pOpooU+QR",
"E_(3A:o+.]qL3MYA6",
"H#O'X_RiVS#8l0bKD",
"Y1gbGD`~8d>HSWN35",
"LQlMv]G5^^1kcm?fk",
"T4}gI;`BFVfhw=-sf",
"6BHMA0IRix]/=(jht",
"yS$=#Jdpp?P2k6SMQ",
"t1~|kkh+>4d>}OQ`a",
"2Y-\\CU\"944yBluWD5",
"'M\\ZbIX5{`Xd;qi!o",
"?N+RtVqj_r(C5##0\"",
"2;*Livh?V$X/8z#Md",
")IN|7FOs2l-mAM[d#",
"(~f268J},xXrK'Rp'",
"&r/qf9fFHnzV!RzH/",
"}naDRH4p$NI2a).t,",
"{8DM+7!.Mge|~fnO|",
")r[#nI0YDH>6cE38p",
"(0Pwkk&IPchJHs.7A",
")r[#nI0YDH>6cE38p",
"8M-=cQFQ,pPo7eu=p",
"0PHw=/|(tZ1}FHm/'",
"[su`'0Oybc.\"-/W5)",
"1uHl[IC7Sr#NUJV;I",
"8z8%,jK0CDOkJz8I?",
"3Ao2yXDN%YzpE&Suy",
"zNs`7E'e/$i8VqaUL",
"bzHmA^K2>7`UZ?!AO",
};
std::string Alphabet[53] =
{
" ","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","r","w","x","y","z",
"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
};
std::string replace(std::string rep) {
int len = sizeof(Subs)/sizeof(Subs[0]);
std::stringstream ss1;
for(int i = 0; i < len; i++) {
if (rep.find(Subs[i]) != std::string::npos) {
ss1 << Subs[i];
}
}
std::string input = ss1.str();
return input;
}
std::string algorithm(std::string input)
{
//some other algorithms come here(not relative to this question)
input = replace(input);
return input;
}
int main(void){
int ed;
std::cin >> ed;
if(ed == 1){
//different function(not relative to the question)
}
else if(ed == 0){
std::string input;
std::cin >> input;
input = algorithm(input);
std::cout << input << std::endl;
}
else{
std::cout << "1 or 0" << std::endl;
main();
}
return 0;
}
example input: L-nIbhm5<z:92~+,x9bC5f0q#qA(RKZ>|r9bC5f0q#qA(RKZ>|r
expected output: abc
actual output: L-nIbhm5<z:92~+,xL-nIbhm5<z:92~+,x9bC5f0q#qA(RKZ>|r9bC5f0q#qA(RKZ>|r
Sorry it's become long.
There are few mistakes in above code :
char array initialization is not correct.
method body for main and replace method is not closed.
Currently by default return type of replace method is int.
There is string#find method which can be helpful here.
I have tried to make those fixes and here is updated code in C++17 :
#include <iostream>
#include <sstream>
using namespace std;
const char *strings[9] = {
"L-nIbhm5<z:92~+,x",
"9bC5f0q#qA(RKZ>|r",
"9bC5f0q#qA(RKZ>|r",
"k=5,ln(08IAl(gGAK",
"|N,8]dGu)'^MaYpu[",
"!&,Y*nz8C*,J}{+d]",
"Us9%^%?n5!~e##*+#",
"zF8,1KV#¥]$k?|9R#",
"0B4>=nioEjp>4rhgi"
};
const char *alphabet[9] = {
"a","b","c","d","e","f","g","h","i"
};
void replace(std::string rep) {
int len = sizeof(strings)/sizeof(strings[0]);
std::stringstream ss1;
for(int i = 0; i < len; i++) {
if (rep.find(strings[i]) != std::string::npos) {
ss1 << alphabet[i];
}
}
std::cout << ss1.str();
}
int main(){
std::string rep;
cin >> rep;
replace(rep);
}
For reference : https://onlinegdb.com/Bd9DXSPAa
Note - Above code is just for reference, please make sure to add all test cases handling.
I made a c++17 version for your code.
Replacing 'c' style arrays and pointers with C++ style containers, iterators.
And using std::string::replace function. Use the standardlibrary if you can,
its tested and well documented.
#include <algorithm>
#include <iostream>
#include <regex>
#include <string>
#include <vector>
// std::vector/std::array instead of 'c' style arrays.
// allows us to us range based for loops later.
std::vector<std::string> strings =
{
"L-nIbhm5<z:92~+,x",
"9bC5f0q#qA(RKZ>|r",
"k=5,ln(08IAl(gGAK",
"|N,8]dGu)'^MaYpu[",
"!&,Y*nz8C*,J}{+d]",
"Us9%^%?n5!~e##*+#",
//"zF8,1KV#¥]$k?|9R#", // <<== I commented out this line, ¥ is not a valid charcter in my environment
"0B4>=nioEjp>4rhgi"
};
// a string is already an array of characters.
std::string alphabet{ "abcdefghijkl" };
std::string replace_with_alphabet(const std::string& input)
{
std::string retval{ input };
std::size_t index{ 0 };
// range based for, it will keep the order of the vector.
for (const auto& str : strings)
{
// look if you can find any of the predefined strings
// in the input strings.
const size_t pos = retval.find(str, 0);
// if found
if (pos != std::string::npos)
{
// get the next character from the alphabet
std::string replacement{ alphabet[index++] };
// use std::string::replace for replacing the substring
const size_t len = str.length();
retval.replace(pos, len, replacement, 0);
}
}
return retval;
};
/**get str and then see the index of the corresponding string in strings[], and replace the string with alphabet[index number], while deleting the original string part that was replaced**/
int main()
{
auto output = replace_with_alphabet("L-nIbhm5<z:92~+,x9bC5f0q#qA(RKZ>|rk=5,ln(08IAl(gGAK");
std::cout << output << std::endl;
}
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string s;
cin >> s;
for (int i = 0; i < s.size (); i++)
{
if (s[i] == 'A')
{
s[i] = "10";
}
cout << s[i];
}
return 0;
}
I am getting following error:
main.cpp: In function
'int main()': main.cpp:10:5: error: invalid conversion from 'const char*' to 'char' [-fpermissive] s[i]= "10";
Any help would be highly appreciated. Thank you.
You can find the position of A, starting from index 0 until end of the string and whenever you find, replace it with 10 using the information of both position where you found and the length of the string you would like to find in the given string.
Something like follows: https://www.ideone.com/dYvF8d
#include <iostream>
#include <string>
int main()
{
std::string str;
std::cin >> str;
std::string findA = "A";
std::string replaceWith = "10";
size_t pos = 0;
while ((pos = str.find(findA, pos)) != std::string::npos)
{
str.replace(pos, findA.length(), replaceWith);
pos += replaceWith.length();
}
std::cout << str << std::endl;
return 0;
}
why not use string::find() to locate the character you want to replace and then string::insert to insert a "10"? maybe not the best way, but can finish it correctly.
You code's question is that the operator[] of std::string returns a char&, and you can not assign a string literal to it.
And I think I should give you a function to implement it.
void Process(std::string& op)
{
auto pos=op.find('A');
op.erase(pos,1);
if(pos!=std::string::npos)
{
op.insert(pos,"10");
}
}
I need to sort the first name and then last name of of student and then display the fully sorted names on screen using structure in C++. I tried but compiler showing Lvalue Required error - in these line
tfname = s[i].fname;
s[i].fname = s[j].fname;
s[j].fname = tfname;
tlname = s[i].lname;
s[i].lname = s[j].lname;
s[j].lname = tlname;
Here the complete code
#include <iostream.h>
#include <conio.h>
#include <stdio.h>
#include <string.h>
struct student
{
char fname[20];
char lname[20];
int id_no;
};
typedef student S;
void main()
{
S s[25];
char tfname[20], tlname[20];
int t;
for(int i = 0; i<25; i++)
{
cout<<"\n Enter Student's first name:";
cin>>s[i].fname;
cout<<"\n Enter Student's last name:";
cin>>s[i].lname;
cout<<"\n Enter ID NO";
cin>>s[i].id_no;
}
for(i = 0; i<24; i++)
{
for(int j = i+1; j<25; j++)
{
if(strcmp(s[i].fname, s[j].fname)>0)
{
tfname = s[i].fname;
s[i].fname = s[j].fname;
s[j].fname = tfname;
tlname = s[i].lname;
s[i].lname = s[j].lname;
s[j].lname = tlname;
t = s[i].id_no;
s[i].id_no = s[j].id_no;
s[j].id_no = t;
}
else
{
if(strcmp(s[i].fname, s[j].fname)==0)
{
if(strcmp(s[i].lname, s[j].lname)>0)
{
tfname = s[i].fname;
s[i].fname = s[j].fname;
s[j].fname = tfname;
tlname = s[i].lname;
s[i].lname = s[j].lname;
s[j].lname = tlname;
t = s[i].id_no;
s[i].id_no = s[j].id_no;
s[j].id_no = t;
}
}
}
}
cout<<"\n\n FIRST NAME \t LASTNAME \t ID NO ";
for(int i = 0; i<25; i++)
{
cout<<"\n"<< c[i].fname<<"\t" <lt; c[i].lname <<="" <
}
getch();
}
}
Kindly help me how can I solve this error
Use std::vector and std::string instead of arrays. Arrays have all kinds of problems in use cases such as yours. One of their big problems if that you cannot pass around or return them like "normal" objects, e.g. of type int or double. Their "second-class citizen" status in the C++ language also causes the strange behaviour you've observed in your program.
int GetInt() // works fine
{
return 123;
}
void DoSomethingWithDouble(double d) // works fine
{
// ...
}
char[] GetArray() // does not even compile
{
// ...
}
void DoSomethingWithArray(int array[]) // does not work as expected, either
{
// ...
}
This is why in C++, we use std::string, std::vector or other sophisticated classes which allow us to treat strings or collections exactly (or almost exactly) like simple (so-called "primitive") types such as int or double:
std::string GetString()
{
// ...
}
void DoSomethingWithString(std::string const &s) // you should use const & here because
// it does not cost you anything and may
// increase speed of your program
{
// ...
}
std::vector<int> GetInts()
{
// ...
}
void DoSomethingWithInts(std::vector<int> const &v) // you should use const & here because
// it does not cost you anything and
// may increase speed of your program
{
// ...
}
You can even assign them completely safely and with no special syntax:
std::vector<int> v1;
std::vector<int> v2;
v1 = v2;
std::string s1;
std::string s2;
s1 = s2;
And you can create string vectors, and they will behave exactly as you expect:
std::vector<std::string> string_vector;
string_vector.push_back("abc");
string_vector[0][0] = 'A';
std::cout << string_vector[0]; // prints "Abc"
Arrays do have their place in C++, but not for beginners and not in high-level programming.
You cannot swap strings this way. Strings should be copied using strcpy().
strcpy(tfname, s[i].fname);
strcpy(s[i].fname, s[j].fname);
strcpy(s[j].fname, tfname);
Another way is #include <string> and declare student::fname, student::lname, tfname and tlname as std::string. Then you could use assignment operator to copy them correctly.
Arrays has no the assignment operator. Instead of it you have to copy elements from one array to another. As in your code arrays has type char and designed to store strings you should use standard C function std::strcpy declared in header <cstring>
So this code snippet
tfname = s[i].fname;
s[i].fname = s[j].fname;
s[j].fname = tfname;
tlname = s[i].lname;
s[i].lname = s[j].lname;
s[j].lname = tlname;
will look the following way
std::strcpy( tfname, s[i].fname );
std::strcpy( s[i].fname,s[j].fname );
std::strcpy( s[j].fname, tfname );
std::strcpy( tlname, s[i].lname );
std::strcpy( s[i].lname, s[j].lname );
std::strcpy( s[j].lname, tlname );
The other approach is to use standard class std::array. In this case you may use the assignment operator. For example
#include <array>
//...
struct student
{
std::array<char, 20> fname;
std::array<char, 20> lname;
int id_no;
};
And at last you could use class std::string instead of raw character arrays.
If your task description contains C++, struct, and sort, what about this version?
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
struct Student
{
std::string fname;
std::string lname;
int id_no;
};
/// checks order after comparing (fname, then lname)
/// (usable with std::sort)
bool operator<(const Student& lhs, const Student& rhs)
{
int c=lhs.fname.compare(rhs.fname);
if (c < 0) {
return true;
} else if (c > 0) {
return false;
}
return lhs.lname < rhs.lname;
}
/// write student to standard output stream
/// (usable with std::for_each)
void out_student(const Student& s)
{
std::cout << s.fname << " " << s.lname << " " << s.id_no << std::endl;
}
int main()
{
std::list<Student> students;
// entering students left out
std::sort(students.begin(), students.end());
std::for_each(students.begin(), students.end(), out_student);
return 0;
}