I have just started C++ after working with C for almost a year. I'm writing a program for a user to input info about a song. I read that I should use getline() to read strings with spaces. Here is my code:
#include <string>
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
typedef struct Song
{
char title[20];
char album[20];
char artist[20];
int year;
} song;
//store song info
Song Input;
char inputStr[20];
int inputYear;
cout << "Enter the name of a song: ";
getline(cin, inputStr);
strcpy(Input.title, inputStr);
cout << "Enter the album of your song: ";
getline(cin, inputStr);
strcpy(Input.album, inputStr);
cout << "Enter the artist of your song: ";
getline(cin, inputStr);
strcpy(Input.artist, inputStr);
cout << "Enter the year your song was released: ";
cin >> inputYear;
Input.year = inputYear;
//print
cout << "Song title: " << Input.title << endl;
cout << "From album: " << Input.album << endl;
cout << "Artist: " << Input.artist << endl;
cout << "Released: " << Input.year << endl;
return 0;
}
My compiler1 throws 3 errors, one for each of the getline() calls, not recognizing getline() despite the fact I have #include <string>. I have looked up sample usage of the getline() function.
Thanks for any help.
1I have wondered if this problem might concern an issue with the standard of C++ that my compiler supports. I did a bit of research and I did not find anything that helped me learn which standard I am using. Here's some info:
I'm using Terminal on Mac.
After g++ version:
Configured with: --prefix=/Applications/Xcode.app/Cont.../usr/include/c++/4.2.1
Apple LLVM version 8.1.0 (clang-802.0.42)
These lines seem to be the only ones of use here, but I could give more info. If someone has any idea which standard of C++ this is, whether it's C++11, or C++14, or otherwise, that would also be very helpful. Thanks again.
UPDATE:
started from scratch, tried to take as much of your advice as possible while still sticking to some of what I know. No errors and works just as I hoped. Thanks for all your help.
New code:
#include <string>
#include <cstring>
#include <iostream>
using namespace std;
struct Song
{
string title;
string artist;
string album;
string year;
}song;
int main()
{
Song Input;
cout << "Song? ";
getline(cin, Input.title);
cout << "Artist? ";
getline(cin, Input.artist);
cout << "Album? ";
getline(cin, Input.album);
cout << "Year? ";
getline(cin, Input.year);
cout << "Song: " << Input.title << endl;
cout << "Artist: " << Input.artist << endl;
cout << "Album: " << Input.album << endl;
cout << "Year: " << Input.year << endl;
return 0;
}
The version of getline you are using takes a std::string as a parameter, not an array of char. If you want to use an array of char (and you shouldn't), you need to use the member function version:
cin.getline( some_char_array, array_size );
I would switch from using char arrays to using string's everywhere. For example I would do your code like this:
#include <string>
#include <iostream>
struct Song{
std::string title;
std::string album;
std::string artist;
int year;
};
int main()
{
//store song info
Song Input;
int inputYear;
std::cout << "Enter the name of a song: ";
getline(std::cin, Input.title);
std::cout << "Enter the album of your song: ";
getline(std::cin, Input.album);
std::cout << "Enter the artist of your song: ";
getline(std::cin, Input.artist);
std::cout << "Enter the year your song was released: ";
std::cin >> Input.year;
//print
std::cout << "Song title: " << Input.title << '\n';
std::cout << "From album: " << Input.album << '\n';
std::cout << "Artist: " << Input.artist << '\n';
std::cout << "Released: " << Input.year << std::endl;
return 0;
}
My preference is to not use using namespace std; but there's nothing wrong with it. Notice that using strings directly I don't need to copy things. I can use getline to do all that for me. I also don't need to worry about overrunning the size of the char array because string does that for me as well.
Related
I have a school assignment in which I have to create a Wine Inventory System where the user can add multiple different wines without a finite number I assume.
I need to create vectors but I'm not sure. I don't know what to try.
#include <string>
#include <iostream>
#include <vector>
using namespace std;
struct Wine1
{ //struct for Wine pssibly needs Vector
string name;
string year;
string place;
string price;
} wine;
void printwine(Wine1 wine);
int main()
{
string str; //input for data
cout << "Please enter the data of the First wine: " << endl;
cout << "Enter name: ";
getline(cin, wine.name);
cout << endl << "Enter year: ";
getline(cin, wine.year);
cout << endl << "enter country of creation: ";
getline(cin, wine.place);
cout << endl << "enter price: ";
getline(cin, wine.price);
cout << endl;
cout << "your entered data: " << endl;
printwine(wine);
cout << endl;
printwine2(wine2);
cout << endl;
printwine3(wine3);
}
void printwine(Wine1 wine)
{ //data the user typed as output
cout << "Wine1" << endl;
cout << "the name is: " << wine.name << endl;
cout << "it's year is: " << wine.year << endl;;
cout << "its country of creation is: " << wine.place << endl;;
cout << "it's price is: " << wine.price << endl;
}
It should output the name of the wine, the year, it's country, and it's price, for each wine which was added.
A good starting should be using vector of Wine1.
std::vector<Wine1> wineVec;
wineVec.reserve(/*size*/) // reserve the memory if you know the number of wines beforehand
The printwine function should now take std::vector<Wine1>(preferably const-reference as the data is read-only) and iterate through the vector to print the attributes of the Wine1.
Something like:
#include <string>
#include <iostream>
#include <vector>
void printwine(const std::vector<Wine1>& vecWine)
{
for (const auto& wine : vecWine)
{
// do printing each: wine.name, wine.year,... so on
}
}
int main()
{
std::vector<Wine1> vecWine;
int wineNumber = 2;
vecWine.reserve(wineNumber);
std::string name, year, place, price;
for (int i = 0; i < wineNumber; ++i)
{
// get the user input for name, year, place, and price
std::cin >> name >> year >> place >> price;
vecWine.emplace_back(Wine1{ name, year, place, price });
}
printwine(vecWine);
}
That said, you should read more about std::vector
to get to know more, how it works.
Also, good to read about, how to overload operator>> and operator<<, so that you could even write code, much simpler.
Following is an incomplete code, which I leave you to complete after covering the topics which I mentioned.
void printwine(const std::vector<Wine1>& vecWine)
{
for (const auto& wine : vecWine)
{
std::cout << wine << '\n';
}
}
int main()
{
std::vector<Wine1> vecWine(wineNumber);
for (Wine1& wine : vecWine)
{
std::cin >> wine;
}
printwine(vecWine);
}
I believe there is a misunderstanding: you do not intend your struct Wine1 to contain a vector but instead, you want a vector of Wine1's.
I suggest a data structure similar to the following:
struct Wine {
string name;
string year;
string place;
string price;
};
void printwinelist(vector<Wine>& list){
for(Wine& w : list){
printwine(w);
}
}
vector<Wine> winelist;
The main method has to be rewritten accordingly, to append additional objects to the vector.
While I could rewrite your code accordingly I suspect, that a better next step for you would be to read up on some of the concepts used, such as vectors.
You probably want something like this:
#include <string>
#include <iostream>
#include <vector>
using namespace std;
struct Wine1
{ //struct for Wine pssibly needs Vector
string name;
string year;
string place;
string price;
};
void printwine(Wine1 wine);
int main()
{
vector<Wine1> wineinventory;
// read 3 wines
for (int i = 3; i < 10; i++)
{
Wine1 wine;
string str; //input for data
cout << "Please enter the data of the First wine: " << endl;
cout << "Enter name: ";
getline(cin, wine.name);
cout << endl << "Enter year: ";
getline(cin, wine.year);
cout << endl << "enter country of creation: ";
getline(cin, wine.place);
cout << endl << "enter price: ";
getline(cin, wine.price);
cout << endl;
cout << "your entered data: " << endl;
printwine(wine);
wineinventory.push_back(wine); // store in vectore
}
// print all wines in the vector
for (int i = 0; i < wineinventory.size(); i++)
{
cout << "Wine " << i << ":" endl;
printwine(wineinventory[i]);
}
}
Disclaimer: this is untested code, I'm not even sure if it compiles, but you should get the idea.
There is still much room for improvement.
So here is the rundown:
I am creating a small music library using structs. The library has a few functions that it has to do with one of them being that I should be able to add new songs to the library. I have to use cin.get() and go from there but everytime I execute it, it goes into and infinite loop. Here is what my code for the add song functions looks like. The integer i is just some index value.
struct song {
char title[50];
char artist[50];
char minutes[50];
char seconds[50];
char album[50];
}info[50];
void new_song(int& i)
int main(){
}
new_song(i);
{
cin.get(info[i].title,50,'\n');
cin.ignore(100, '\n');
cin.get(info[i].artist, 50, '\n');
cin.ignore(50, '\n');
cin.get(info[i].minutes, 50, '\n');
cin.ignore(50, '\n');
cin.get(info[i].seconds, 50, '\n');
cin.ignore(50, '\n');
cin.get(info[i].album, 50, '\n');
cin.ignore();
}
Any help helps.
I'd probably do something like this instead of using cin.get(), C strings, and static arrays:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct Song {
string title;
string artist;
string minutes;
string seconds;
string album;
};
void add_song_from_stdin(vector<Song> &songs) {
Song s;
getline(cin, s.title);
getline(cin, s.artist);
getline(cin, s.minutes);
getline(cin, s.seconds);
getline(cin, s.album);
songs.push_back(s);
}
int main() {
vector<Song> songs;
add_song_from_stdin(songs);
Song &song = songs[0];
cout << "song[0]:" << endl;
cout << " \"" << song.title << "\"" << endl;
cout << " \"" << song.artist << "\"" << endl;
cout << " \"" << song.minutes << "\"" << endl;
cout << " \"" << song.seconds << "\"" << endl;
cout << " \"" << song.album << "\"" << endl;
}
I am new to c++ but do have a basic knowledge in coding. This program works fine and well but I'm wondering if there is a better way to do this.
The program makes a star wars name by taking the first three letters of your last name and the first 2 of your first name to make your first name of your star wars name. Then for your star wars surname it takes the first two letters of your mother's maiden name and the first three letters of the city you were born in.
// starWarsName.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
string firstName;
string surname;
string maidenName;
string city;
cout << "This program is designed to make you a star wars name, it takes some information and concatinates parts of the information to make your NEW name" <<endl << endl;
cout << "please enter your first name" << endl;
cin >> firstName;
cout << "please enter your surname" <<endl;
cin >> surname;
cout << "what is your mothers maiden name?" << endl;
cin >> maidenName;
cout << "please tel me which city you were born in" << endl;
cin >> city;
cout << firstName << " " << surname << endl;
cout << firstName[0] << " " << surname << endl;
int size = firstName.length();
//cout << size;
cout << surname[0] << surname[1] << surname[2] << firstName[0] << firstName[1];
cout << " " << maidenName[0] << maidenName[1] << city[0] << city[1] << city[2];
cin.get();
cin.ignore();
return 0;
}
You can use string::substr here to store character sequence instead of writing surname[0]..surname[2] again and again.
Here is an example of string::substr
#include <iostream>
#include <string>
int main ()
{
std::string str="We think in generalities, but we live in details.";
// (quoting Alfred N. Whitehead)
std::string str2 = str.substr (3,5); // "think"
std::size_t pos = str.find("live"); // position of "live" in str
std::string str3 = str.substr (pos); // get from "live" to the end
std::cout << str2 << ' ' << str3 << '\n';
return 0;
}
Output:
think live in details.
I am wringing a simple code to learn more about string. When I ran my code it would not print my last name. Can someone explain why? I used string phrase to store it and it only appears to have stored my first name. Here is the code.
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int main()
{
cout << "Exercise 3B" << endl;
cout << "Kaitlin Stevers" << endl;
cout << "String arrays" << endl;
cout << endl;
cout << endl;
char greeting[26];
cout << "Please enter a greeting: " << endl;
cin >> greeting;
cout << "The greeting you entered was: " << greeting << endl;
string phrase;
cout << "Enter your full name " << endl;
cin >> phrase;
cout << greeting << ", how are you today " << phrase << "?" << endl;
return 0;
}
I used string phrase to store it and it only appears to have stored my first name.
That makes sense.
cin >> phrase;
will stop reading when it encounters a whitespace character in the input.
To read the full name you can use one of the following approaches.
Use two calls to cin >>.
std::string first_name;
std::string last_name;
cin >> first_name >> last_name;
Use getline to read the entire line. getline will read everything in a a line, including whitespace characters.
getline(cin, phrase);
When you call cin >> phrase;, it only reads the string up to the first non-space character. If you want to include spaces in your name, best goes with getline(cin,phrase);.
IMPORTANT: getline() will reads whatever it is in the stream buffer up to the first \n. It means that when you enter cin >> greeting;, if you hit ENTER, getline() will read everything before that \n that is not already read, which is NOTHING into your phrase variable, making it an empty string. An easy way out is to call getline() twice. E.g.
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int main()
{
cout << "Exercise 3B" << endl;
cout << "Kaitlin Stevers" << endl;
cout << "String arrays" << endl;
cout << endl;
cout << endl;
char greeting[26];
cout << "Please enter a greeting: " << endl;
cin >> greeting; //IMPORTANT: THIS ASSUME THAT GREETING IS A SINGLE WORD (NO SPACES)
cout << "The greeting you entered was: " << greeting << endl;
string phrase;
cout << "Enter your full name " << endl;
string rubbish_to_be_ignored;
getline(cin,rubbish_to_be_ignored); //this is going to read nothing
getline(cin, phrase); // read the actual name (first name and all)
cout << greeting << ", how are you today " << phrase << "?" << endl;
return 0;
}
Assuming you store that code in the file stackoverflow.cpp. Sample run:
Chip Chip#04:26:00:~ >>> g++ stackoverflow.cpp -o a.out
Chip Chip#04:26:33:~ >>> ./a.out
Exercise 3B
Kaitlin Stevers
String arrays
Please enter a greeting:
Hello
The greeting you entered was: Hello
Enter your full name
Kaitlin Stevers
Hello, how are you today Kaitlin Stevers?
Tested on ubuntu 14.04
I'd like to use cin and I used char for the int type (do you call it like that?) and it just shows one letter of what typed. How can I get the whole sentence?
Since you're using c++ why not use std::string instead? Something like this should do what you're looking for:
#include <iostream>
#include <string>
int main()
{
using namespace std;
string sentence;
cout << "Enter a sentence -> ";
getline(cin, sentence);
cout << "You entered: " << sentence << endl;
}
use cin.getline()
char name[256];
cout << "What is your name?\n>";
cin.getline(name, 256);
cout << "Your name is " << name;