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;
}
Related
So i set my array value as 100 and when i want to display my array,the others array with no value will also display. Any ways to remove it ? Thanks!
#include<iostream>
#include<iomanip>
#include<cstring>
#include<string>
#include<fstream>
#include<limits>
#include<sstream>
using namespace std;
char add();
char list();
struct Book //structure for the book
{
char title[50];
char author[50];
int price;
void display() {
cout << "Name:" << title << endl
<< "Author:" << author<< endl
<< "Price:" << price << endl << endl;
}
};
Book book[100];
void main()
{
int selection;
do {
cout << "Activity Selection: " << endl;
cout << "1. Add book" << endl;
cout << "2. List all books" << endl;
cout << "3. Search book" << endl;
cout << "4. Check total book purchased and total spent" << endl;
cout << "5. Quit" << endl;
cout << "Please enter your selection(1/2/3/4/5): ";
cin >> selection;
cin.ignore();
switch (selection)
{
case 1:
add();
break;
case 2:
list();
break;
case 3:
cout << "number 3" << endl;
break;
case 4:
cout << "number 4" << endl;
break;
default:
exit(1);
break;
}
} while (selection <= 4);
system("pause");
}
char add()
{
int i;
ofstream outFile;
outFile.open("Records.dat", ios::app);
if (!outFile.is_open())
{
cout << "Can’t open file.";
system("pause");
exit(1);
}
cout << "Please enter the book title:";
cin.getline(book[i].title, 51);
cout << "Please enter the author name of the book:";
cin.getline(book[i].author, 51);
cout << "Please enter the price of the book RM: ";
cin >> book[i].price;
cout << "\nThe book\""<< book[i].title <<"\"has been added to the system.\n" <<
endl;
outFile << book[i].title << "," << book[i].author << "," << book[i].price <<
endl;
outFile.close();
}
char list() //second solution but still doesnt work need some fixing here i think
{
int i;
string line, token;
ifstream inFile;
inFile.open("Records.dat", ios::in);
if (!inFile.is_open())
{
cout << "File could not open" << endl;
system("pause");
exit(1);
}
char data;
while (getline(inFile,line))
{
inFile.get(data);
if (!(data == 0));
cout << data;
}
cout << endl;
inFile.close();
}
when i debug something like this come out :
ss
this is the second solution i come out with but still does not work
char list()
{
int i , count = 0;
string line, token;
ifstream inFile;
inFile.open("Records.dat", ios::in);
if (!inFile.is_open())
{
cout << "File could not open" << endl;
system("pause");
exit(1);
}
char data;
while (getline(inFile, line))
{
stringstream ss(line);
getline(ss, token, ',');
stringstream(token) >> book[i].title;
getline(ss, token, ',');
stringstream(token) >> book[i].author;
getline(ss, token, ',');
stringstream(token) >> book[i].price;
i++;
}
cout << endl;
inFile.close();
for (int count = 0; count < i; count++)
book[i].display();
}
The problem is i dont really know how to display the array using the dat file and i successfully display it but theres error
You are reading the CSV as a text file and just printing it.
So, the solution is to make a record class, read it from stream, then check it whether it is empty or no.
#include <iostream>
#include <sstream>
using namespace std;
class Record {
private:
std::string title;
std::string shortTitle;
int number;
public:
Record(std::string title, std::string shortTitle, int number): title(title),
shortTitle(shortTitle),
number(number){
}
inline std::string getTitle() const { return title; }
inline std::string getShortTitle() const { return shortTitle; }
inline int getNumber() const { return number; }
};
// Make this function capable of handling any stream by making it template
// (anything that could be passed to a `getline` as a first parameter and have
// an operator >> overloaded that accepts an integer)
template<typename Stream>
Record readFromStream(Stream &str) {
std::string title;
std::string shortTitle;
int number;
std::string line;
// Read a line from the stream
getline(str, line);
// Make a new stream from that line
std::stringstream lineStream(line);
// Read until the comma
getline(lineStream, title, ',');
getline(lineStream, shortTitle, ',');
// The last one is an integer, simply read it
lineStream >> number;
return Record(title, shortTitle, number);
}
int main() {
Record rec = readFromStream(cin);
// Check for emptiness, if is NOT empty write it
if (rec.getTitle().size() && rec.getShortTitle().size()) {
cout << rec.getTitle() << "\n";
cout << rec.getShortTitle() << "\n";
cout << rec.getNumber() << "\n";
}
return 0;
}
I have a problem with this code. Could you please help me to find out why it does not save new total donation values (total) to the file (donation_total.txt)? It should be noted that the default value saved in the file is zero, but it keeps it for each iteration. I need the new value is saved at the last line each time.
Thanks
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
int main()
{
fstream records;
records.open("donation_total.txt", ios_base::in | ios_base::out | ios_base::app);
if (records.is_open())
{
cout << "The record file is open!" << endl;
string line;
while (!records.eof())
{
getline(records, line);
}
int total = stoi(line);
cout << "Total donation is: "<<total << endl;
cout << "Is there any new record?" << endl;
string str,newname;
stringstream field;
string name;
int donation;
getline(cin , str);
while (str=="Yes" | str=="yes")
{
cout << "Enter name and donation value: ";
getline(cin, newname);
field.str(newname);
field >> name >> donation;
total += donation;
field.clear();
cout << name << " donates " << donation << "$" << endl;
cout << "Total donation is: " << total << endl;
records << endl << total;
cout << "Is there any new record?" << endl;
getline(cin, str);
}
}
else
{
cerr << "Could not find the file!" << endl;
}
records.close();
return 0;
}
Your program has many logical incorrectness. When a name is entered with no donation amount, it takes the previously donated value.
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
int main()
{
fstream records;
records.open("donation_total.txt", ios_base::in | ios_base::out | ios_base::app);
if (records.is_open())
{
cout << "The record file is open!" << endl;
string line;
while (getline(cin, line))
{
int total = stoi(line);
cout << "Total donation is: "<<total << endl;
cout << "Is there any new record?" << endl;
string str,newname;
stringstream field;
string name;
int donation;
getline(cin , str);
while (str=="Yes" || str=="yes")
{
cout << "Enter name and donation value: ";
getline(cin, newname);
field.str(newname);
field >> name >> donation;
total += donation;
field.clear();
cout << name << " donates " << donation << "$" << endl;
cout << "Total donation is: " << total << endl;
records << endl << total;
cout << "Is there any new record? ";
getline(cin, str);
}
break;
}
}
else
{
cerr << "Could not find the file!" << endl;
}
records.close();
return 0;
}
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.
all!
I'm trying to find the best way to accept user input, timestamp it, then place it into a file with correct formatting (One timestamp/input per line. What is the best way to timestamp then give over to put it all in a file? Thanks!
Heres my barebones code as an example:
#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
using namespace std;
//void passwordCheck()
//{
//
//}
string timestamp(string passwordInput1, string passwordInput2, string passwordInput3, string passwordInput4, string passwordInput5, string passwordInput6, string passwordInput7, string passwordInput8, string passwordInput9, string passwordInput10)
{
time_t now = time(0);
char* dt = ctime(&now);
cout << "The local date and time is: " << dt << endl;
tm *gmtm = gmtime_s(&now);
dt = asctime(gmtm);
}
//void saveToFile()
//{
//
//cout << "I've saved 10 passwords for you." << endl;
//}
int main()
{
ofstream outputToFile;
outputToFile.open("manageMyPasswords.txt");
// Look for easier/cleaner way to do this.
string passwordInput1, passwordInput2, passwordInput3, passwordInput4, passwordInput5, passwordInput6, passwordInput7, passwordInput8, passwordInput9, passwordInput10;
// Put into a function then call back here.
cout << "Welcome to Password Manager!" << endl;
cout << " Enter your first password" << endl;
getline (cin, passwordInput1);
cout << "Enter the next password." << endl;
getline (cin, passwordInput2);
cout << "Enter the next password." << endl;
getline (cin, passwordInput3);
cout << "Enter the next password." << endl;
getline (cin, passwordInput4);
cout << "Enter the next password." << endl;
getline (cin, passwordInput5);
cout << "Enter the next password." << endl;
getline (cin, passwordInput7);
cout << "Enter the next password." << endl;
getline (cin, passwordInput8);
cout << "Enter the next password." << endl;
getline (cin, passwordInput9);
cout << "Enter the next password." << endl;
getline (cin, passwordInput10);
//void saveToFile();
system("pause");
return 0;
}
As I understood your question you need sth like this:
#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
#include <map>
int main(int argc, char** argv)
{
typedef std::multimap<time_t, std::string> Passwords;
Passwords passwords;
short counter = 1;
std::cout << "Enter passwords or \"quit\" to stop" << std::endl;
for (std::string line;;)
{
std::cout << "Enter password " << counter << " -> ";
getline(std::cin, line);
if (line.empty())
{
continue;
}
else if (line.compare("quit") == 0)
{
break;
}
passwords.insert(std::pair<time_t, std::string>(time(0), line));
counter++;
}
std::ofstream outputFile;
outputFile.open("manageMyPasswords.txt", std::ios::trunc);
for (Passwords::const_iterator it = passwords.begin(); it != passwords.end(); it++)
{
outputFile << it->first << " " << it->second << "\n";
}
outputFile.close();
return 0;
}
It will wait for users input infinitely, until "quit" is not entered. After that it will dump timestamps with password line by line.
P.S. I've used multimap, because you can have duplicate timestamps.
Update
It seems from your code that you need human-readable time. Use this function to retrieve current date and time:
// Returns current date-time formatted like [YYYY-MM-DD][HH:mm:ss]
const std::string GetCurrentDateTime()
{
time_t currentTime = time(0);
struct tm localDateTime;
char buf[80];
localtime_s(&localDateTime, ¤tTime);
strftime(buf, sizeof(buf), "[%Y-%m-%d][%X]", &localDateTime);
return buf;
}
I'm trying to assign some values to a vector from cin.
How can I achieve that the while loop breaks immediately after a specific word, e.g. end, was entered?
In my example it only breaks if I enter this word as "age", so only at the end of the loop. If I enter it at the beginning (as "name") it just continues.
#include <iostream>
#include <vector>
using namespace std;
struct person {
string name;
string age;
};
int main() {
vector<person> myPerson;
string text;
while(text != "end") {
person tempPerson;
cout << "Name:" << endl;
cin >> text;
tempPerson.name = text;
cout << "Age:" << endl;
cin >> text;
tempPerson.age = text;
myPerson.push_back(tempPerson);
}
for(int i=0; i<myPerson.size(); i++) {
cout << "Person No. " << i << ": " << endl;
cout << "Name: " << myPerson[i].name << endl;
cout << "Age: " << myPerson[i].age << endl;
}
return 0;
}
break out of the loop if "end" is entered.
while (true) {
cin >> text;
if (text == "end")
break;
// ...
}