I'm working on a program that collects family last names and then asks for names of first name of family members. I'm using an istringstream object to separate the names collected from a getline. For the step where I try to fill the elements in the map, I get the following error. I know that you can create keys by supplying them in brackets following the name of the map. If that method is valid, why do I get the following error.
ex11_14.cpp:19:6: error: reference to non-static member function must be called
family[lname].push_back[fname];
Code:
#include <iostream>
#include <map>
#include <vector>
#include <sstream>
int main()
{
std::string lname, fname;
std::string last, children;
std::map<std::string, std::vector<std::string>> family;
std::cout << "Enter family names" << std::endl;
getline(std::cin, last);
std::istringstream i{last};
std::cout << "Enter children's names" << std::endl;
while(i >> lname) {
std::cout << lname << std::endl;
getline(std::cin, children);
std::istringstream j{children};
while(j >> fname)
family[lname].push_back[fname];
}
for(auto &c:family) {
std::cout << c.first << std::endl;
for(auto &w:c.second)
std::cout << w << " ";
std::cout << std::endl;
}
std::cout << std::endl;
return 0;
}
Sorry. push_back should be called with () not []. Fixes the issue.
It seems, this line:
family[lname].push_back[fname];
wants to read
family[lname].push_back(fname);
BTW, don't use std::endl. Use '\n' to get a newline and std::flush to flush the stream: use of std::endl is most often a performance problem without being useful in the first place.
Related
Sorry I'm really new to programming and need some assistance. How would I make this happen. This is the function I currently have.
void DisplayTitle(string aTitle) {
cout << "\t" << aTitle << endl;
cout << "\t--------------\n\n";
}
How would I go about making sure that no matter which title is inputted, every character will be capitalized and the underscores will be the same amount of characters as the displayed title above.
You can use std::setfill combined with std::setw from <iomanip> as follows:
std::cout << std::setfill('-') << std::setw(title.size()) << "";
Here, you're telling the stream to use a padding character of '-', then a padded output size that's the length of your title, and then output an empty string. Because the string is empty, it will pad that entire area.
#include <iostream>
#include <iomanip>
#include <string>
void DisplayTitle(const std::string& title, const char* prefix = "\t")
{
std::cout << prefix << title << "\n";
std::cout << prefix << std::setfill('-') << std::setw(title.size()) << "" << "\n\n";
}
int main()
{
for (std::string title; std::getline(std::cin, title); )
{
DisplayTitle(title);
}
}
Example input:
One flew over the cuckoo's nest
The birds and the bees
Example output:
One flew over the cuckoo's nest
-------------------------------
The birds and the bees
----------------------
Here is a live demo of the above.
Oh, it seems I missed the fact your question was asking two things. You also want to capitalize the title. You can do that with std::transform, and in fact it can even be done without modifying the string:
void DisplayTitle(const std::string& title, const char* prefix = "\t")
{
// Write title in all-caps
std::cout << prefix;
std::transform(title.begin(), title.end(),
std::ostream_iterator<char>(std::cout),
[](char c) { return std::toupper(c); });
std::cout << "\n";
// Underline title
std::cout << prefix << std::setfill('-') << std::setw(title.size()) << "" << "\n\n";
}
Here is the updated live demo with the above change.
You can use std::transform and to_upper to capitalize the string.
You can use std::string's two-parameter constructor which takes a length and a character to generate a sequence of - of the same length as the title
Together we get:
#include <iostream>
#include <string>
#include <algorithm>
void DisplayTitle(std::string aTitle) {
std::transform(aTitle.begin(), aTitle.end(), aTitle.begin(), toupper);
std::cout << "\t" << aTitle << "\n";
std::cout << "\t" << std::string(aTitle.length(), '-') << "\n\n";
}
int main()
{
for (std::string title; std::getline(std::cin, title); )
{
DisplayTitle(title);
}
}
demo on godbolt
I am trying to write some string data to a .txt file that i read from the user but after doing so, the program shuts down instead of continuing and when i check the results inside the .txt file i see some part of the data and then some gibberish, followed by an assertion failure error! Here's the code:
#include "std_lib_facilities.h"
#include <fstream>
using namespace std;
using std::ofstream;
void beginProcess();
string promptForInput();
void writeDataToFile(vector<string>);
string fileName = "links.txt";
ofstream ofs(fileName.c_str(),std::ofstream::out);
int main() {
// ofs.open(fileName.c_str(),std::ofstream::out | std::ofstream::app);
beginProcess();
return 0;
}
void beginProcess() {
vector<string> links;
string result = promptForInput();
while(result == "Y") {
for(int i=0;i <= 5;i++) {
string link = "";
cout << "Paste the link skill #" << i+1 << " below: " << '\n';
cin >> link;
links.push_back(link);
}
writeDataToFile(links);
links.clear(); // erases all of the vector's elements, leaving it with a size of 0
result = promptForInput();
}
std::cout << "Thanks for using the program!" << '\n';
}
string promptForInput() {
string input = "";
std::cout << "Would you like to start/continue the process(Y/N)?" << '\n';
std::cin >> input;
return input;
}
void writeDataToFile(vector<string> links) {
if(!ofs) {
error("Error writing to file!");
} else {
ofs << "new ArrayList<>(Arrays.AsList(" << links[0] << ',' << links[1] << ',' << links[2] << ',' << links[3] << ',' << links[4] << ',' << links[5] << ',' << links[6] << ',' << "));\n";
}
}
The problem lies probably somewhere in the ofstream writing procedure but i can't figure it out. Any ideas?
You seem to be filling a vector of 6 elemenents, with indices 0-5, however in your writeDataToFile function are dereferencing links[6] which is out of bounds of your original vector.
Another thing which is unrelated to your problem, but is good practice:
void writeDataToFile(vector<string> links)
is declaring a function which performs a copy of your vector. Unless you want to specifically copy your input vector, you most probably want to pass a const reference, like tso:
void writeDataToFile(const vector<string>& links)
string toString() {
std::stringstream punkte;
std::stringstream name;
std::cout << name << "hat" << punkte << "Punkte" << '\n'
return 0;
}
At this line of code. I'm receiving the error C++ << no operator found
I can't figure out what my mistake is. I have read and tried different solutions. But nothing works. Can somebody please help?
std::cout << name << "hat" << punkte << "Punkte" << '\n';
I also included this in my code:
#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::stringstream, std::stringbuf
#include <fstream>
There is no overload of operator<<() that will format a std::stringstream to a std::ostream. There error does not lie.
You are trying to call operator "<<" with a stringstream parameter. In other words:
std::cout << name;
Is equivalent to:
std::cout.operator<<(name);
And that operator<<(const std::stringstream&) function doesn't exists.
I think that what you want to do is assign each stringstream their values and then print both, isn't?
string toString()
{
std::stringstream punkte;
std::stringstream name;
name << "hat";
punkte << "Punkte";
std::cout << name.str() << punkte.str() << std::endl;
return name.str();
}
Be careful with your return value, and remember that a std::stringstream is not a std::string. If you want to retrieve the std:string in the stream, you must call the str() method.
My program worked like it was supposed to until I added the toupper part into my program. I've tried looking at my error code but it's not really helping. The errors are:
no matching function to call
2 arguments expected, one provided
So I know the error is in those two statements in my while loop. What did I do wrong?
I want to make a name like
john brown
go to
John Brown
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
int main(){
string firstname[5];
string lastname[5];
ifstream fin( "data_names.txt" );
if (!fin) {
cout << "There is no file" << endl;
}
int i = 0;
while( i < 5 && (fin >> firstname[i]) && (fin >> lastname[i]) ) {
firstname[0] = toupper(firstname[0]);
lastname[0] = toupper(lastname[0]);
i++;
}
cout << firstname[0] << " " << lastname [0] << endl;
cout << firstname[1] << " " << lastname [1] << endl;
cout << firstname[2] << " " << lastname [2] << endl;
cout << firstname[3] << " " << lastname [3] << endl;
cout << firstname[4] << " " << lastname [4] << endl;
return 0;
}
std::toupper works on individual characters, but you are trying to apply it to strings. Besides adding #include <cctype>, you need to modify your while loop's body:
firstname[i][0] = toupper(firstname[i][0]);
lastname[i][0] = toupper(lastname[i][0]);
i++;
Then it should work as expected. Live demo here
As M.M helpfully pointed out in the comments, you should also check that your strings aren't empty before accessing their first characters, i.e. something like
if (!firstname[i].empty()) firstname[i][0] = toupper(...);
is strongly recommended.
Mind you, you will probably need more sophisticated logic if you get names like McDonald :)
You need ctype.h to get the proper definition for toupper(). It is usually implemented not as a function, but an array mapping.
#include <ctype.h>
The program has several flaws: using a string array instead of a string, not iterating through the string correctly, not declaring but using the C definition of toupper(), not exiting when the file does not exist.
Use this instead:
#include <ctype.h>
#include <iostream>
#include <string>
using namespace std;
int main ()
{
ifstream fin ("data_names.txt");
if (!fin)
{
cerr << "File missing" << endl;
return 1;
}
// not sure if you were trying to process 5 lines or five words per line
// but this will process the entire file
while (!fin.eof())
{
string s;
fin >> s;
for (i = 0; i < s.length(); ++i)
s [i] = toupper (s [i]);
cout << s << endl;
}
return 0;
}
I'm new to C++, could someone please explain to me why I received the below errors when I do use "std::getline"? Here's the code:
#include <iostream>
#include <string>
int main() {
string name; //receive an error here
std::cout << "Enter your entire name (first and last)." << endl;
std::getline(std::cin, name);
std::cout << "Your full name is " << name << endl;
return 0;
}
ERRORS:
te.cc: In function `int main()':
te.cc:7: error: `string' was not declared in this scope
te.cc:7: error: expected `;' before "name"
te.cc:11: error: `endl' was not declared in this scope
te.cc:12: error: `name' was not declared in this scope
However, the program would run and compile when I used "getline" with "using namespace std;" instead of std::getline.
#include <iostream>
#include <string>
using namespace std;
int main() {
string name;
cout << "Enter your entire name (first and last)." << endl;
getline(cin, name);
cout << "Your full name is " << name << endl;
return 0;
}
Thank you!
The errors are not from std::getline. The error is you need to use std::string unless you use the using namespace std. Also would need std::endl.
You need to use std:: on all the identifiers from that namespace. In this case, std::string and std::endl. You can get away without it on getline(), since Koenig lookup takes care of that for you.
#include <iostream>
#include <string>
int main()
{
std::string name; // note the std::
std::cout << "Enter your entire name (first and last)." << std::endl; // same here
std::getline(std::cin, name);
std::cout << "Your full name is " << name << std::endl; // and again
return 0;
}
You just needed to state the namespace for various elements that are in the std namespace (alternatively, you can remove all the std::s and place a using namespace std; line after your includes.)
Try this:
#include <iostream>
#include <string>
int main()
{
std::string name;
std::cout << "Enter your entire name (first and last)." <<
std::endl;
while(getline(std::cin, name))
{
std::cout <<"Your name is:"<< name << '\n';
}
return 0;
}