Mysterious addition issue [duplicate] - c++

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 7 years ago.
Using the following code in c++:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class User
{
public:
User();
void setName(string username);
string getName();
private:
string name;
};
User::User()
{}
void User::setName(string username)
{
name = username;
}
string User::getName()
{
return name;
}
class System
{
public:
System();
void createUser();
void postMessage();
string getCurrentUser();
string messageBuffer;
private:
vector<User> users;
string currentUser;
};
System::System()
{
messageBuffer = "";
}
void System::createUser()
{
string username;
bool userExists = false;
cout << "Please enter a user name: ";
cin >> username;
cout << endl;
for(int i = 0; i < users.size(); i++)
{
if(users.at(i).getName() == username)
userExists = true;
}
if(!userExists)
{
User temp; //creates a temporary user stored in vector of Users
users.push_back(temp); //puts new User at end of users
users.back().setName(username);
currentUser = users.back().getName();
}
if(userExists)
cout << "User already exists." << endl << endl;
}
void System::postMessage()
{
string line;
string message;
cout << "Enter message: ";
while(getline(cin,line))
{
if(line == "!!")
break;
message = message + line + "\\n";
}
messageBuffer = "{[" + currentUser + "::tweet]}" + message + messageBuffer;
cout << endl;
}
string System::getCurrentUser()
{
return currentUser;
}
int main()
{
System system;
system.createUser(); //create user named Cam
system.postMessage(); //input message "Hello!"
cout << system.messageBuffer << endl;
return 0;
}
I am outputted with messageBuffer equal to "{[Cam]}\nHello!\n". What I want to happen is messageBuffer to be set to "{[Cam]}Hello!\n". The message inputted can be more than one line long.
Example message input could be:
Hello!
How are you all?
I am great!
!!
messageBuffer should then be:
"{[Cam]}Hello!\nHow are you all?\nI am great!\n"
In actuality I get:
"{[Cam]}\nHello!\nHow are you all?\nI am great!\n"
Where does this mystery "\n" come from?!

This is because you have to flush your stdin buffer before starting to read the messages (you have some unflushed characters which cause getline() to read it and apped \\n to the message string).
In your case I would advice to do it that way:
cin.clear();
cin.ignore(INT_MAX,'\n');
while(getline(cin,line))
if(line == "!!")
break;
message = message + line + "\\n";
}

Related

Why is my program not processing all the functions?

Good day everyone! First off all I want to let you all know that I am a beginner at C++, so my code will have a lot of errors.
I was trying to make a program to refresh my concepts of C++. The problem I am facing is the program is asking me the email ID, but as soon as I input it, the program ends. Please let me know everything I am doing wrong and how to correct it. Thank you so much!
I decided to create a simple login program with the following algorithm:
It asks the user for their email ID.
Checks if the email is registered (in a text file)
If the email is registered, the user is prompted for the password.
If the password is correct, a success message is printed; if not, the user s given 2 more attempts.
If the email is not registered, the program prompts the user to enter a new password and tells them the password strength. An ideal password should have an uppercase letter, a lowercase letter and a digit, with the password length more than 6 characters.
data.h:
#include <iostream>
#include <string>
using namespace std;
#ifndef DATA_H
#define DATA_H
struct newAccount{
string email, password; //declaring email and password of the user
};
string readEmail(string email); //reads in the email id provided
void checkEmail(); //checks if the entered email address exists in the system
int addEmail(); //checks if the entered email address exists in the system
void checkPassword(); //checks if the password matches an already registered email id
void makeNewPassword(string& password); //this function helps the user create a secure password
#endif
data.cpp:
#include <iostream>
#include <string>
#include <fstream>
#include "data.h"
using namespace std;
newAccount tempAccount;
string readEmail(string email) //reads in the email id provided
{
cout << "Enter an email address: ";
getline(cin, tempAccount.email);
email = tempAccount.email;
return tempAccount.email;
}
void checkEmail()
{
ifstream file("database.txt");
string str;
while (getline(file, str))
{
if (str == tempAccount.email)
{
cout << "This email is already registered. Please enter your password: ";
getline(cin, tempAccount.password);
checkPassword();
}
else
{
cout << "This email is not registered. Please create a new password: ";
makeNewPassword(tempAccount.password);
}
}
}
int addEmail() //checks if the entered email address exists in the system
{
ofstream myFile("database.txt");
if (myFile.is_open())
{
myFile << tempAccount.email << endl;
myFile.close();
}
else
cout << "Unable to open file";
return 0;
}
void checkPassword() //checks if the password matches an already registered email id
{
ifstream file("database.txt");
string str;
while (getline(file, str))
{
if (checkEmail)
{
if (str == tempAccount.password)
{
cout << "Login successful! ";
getline(cin, tempAccount.password);
}
else
for (int i = 4; i > 1; i--)
{
cout << "Incorrect password! You have " << i - 1 << " tries remaining.\n";
if (str == tempAccount.password)
break;
}
}
}
}
void makeNewPassword(string &password) //this function helps the user create a secure password
{
int n = password.length();
bool hasLower = false, hasUpper = false, hasDigit = false;
for (int i = 0; i < n; i++)
{
if (islower(password[i]))
hasLower = true;
if (isupper(password[i]))
hasUpper = true;
if (isdigit(password[i]))
hasDigit = true;
}
// Displaying the strength of password
cout << "Strength of password you have entered is ";
if (hasUpper && hasDigit && hasLower && (n >= 6)) // considering a strong must be of length 6 or more
cout << "strong" << endl;
else if ((hasLower || hasUpper) && hasDigit && (n >= 6))
//when at least a lower case or uppercase is used along with digit
cout << "moderate" << endl;
else
cout << "weak" << endl;
}
main.cpp
#include <iostream>
#include <fstream>
#include "data.h"
using namespace std;
int main(){
string e, p;
readEmail(e);
checkEmail();
return 0;
}
I have created this program with the knowledge of a couple of basic C++ courses I took a few semesters ago, and using online tutorials. This is not a homework or an assignment of any kind.
In your readEmail() function, the string email is a local variable. You passed the variable to the function by value, not by reference.
Also, if you pass it by reference, then there's no need to return anything (the function should be void).
void readEmail(string& email) //reads in the email id provided
{
cout << "Enter an email address: ";
cin >> email;
}
int main() {
string e, p;
readEmail(e);
checkEmail();
return 0;
}
But if you want to return the value, than there's no need for parameter, but you need to give that return value to your variable.
string readEmail() //reads in the email id provided
{
cout << "Enter an email address: ";
cin >> email;
return email;
}
int main() {
string e = readEmail();
checkEmail();
return 0;
}

How to store lines from a file as a variable

I'd like to show the employee number name, occupation, and department of employees from a text file called organisation.txt, and save them in the variables declared in the class OrganisationRecord.
How can I do that?
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#define ORGANISATIONALRECORDSFILE "organisation.txt"
#define HRRECORDSFILE "HR_records.txt"
#define PAYROLLRECORDSFILE "payroll_records.txt"
using namespace std;
class OrganisationRecord
{
private:
public:
string name;
string occupation;
string department;
};
class HRRecord
{
private:
public:
string address;
string phonenumber;
string ninumber;
};
class PayrollRecord
{
private:
public:
string ninumber;
double salary;
};
class PayrollProcessing
{
private:
ifstream inputfile;
ofstream outputfile;
vector<OrganisationRecord> OrganisationRecords;
vector<HRRecord> HRRecords;
vector<PayrollRecord> PayrollRecords;
public:
void loadOrganisationRecords(string filename);
void loadHRRecords(string filename);
void loadPayrollRecords(string filename);
void displayEmployeeOfSalaryGTE(double salary);
//GTE = greater than or equal to
};
void PayrollProcessing::loadOrganisationRecords(string filename)
{
inputfile.open(ORGANISATIONALRECORDSFILE);
if (!inputfile)
{
cout << "the organisation records file does not exist" << endl;
return;
}
OrganisationRecord _organisationrecord;
int employeenumber;
while (inputfile >> employeenumber)
{
while (inputfile >> _organisationrecord.name)
{
cout << _organisationrecord.name;
cout << _organisationrecord.occupation;
cout << _organisationrecord.department <<endl;
}
OrganisationRecords.push_back(_organisationrecord);
}
}
int main(void)
{
PayrollProcessing database1;
database1.loadOrganisationRecords(ORGANISATIONALRECORDSFILE);
return 0;
}
organisation.txt
0001
Stephen Jones
Sales Clerk
Sales
0002
John Smith
Programmer
OS Development
0003
Fred Blogs
Project Manager
Outsourcing
When you use inputfile >> _organisationrecord.name it stops at the first whitespace character. Hence, only Stephen will be read and stored in organisationrecord.name.
You need to change your strategy a bit.
Read the contents of the file line by line. Stop when there are no more lines left.
Process each line as you seem fit.
Here's one way to deal with the input.
std::string line;
while ( std::getline(inputfile, line) )
{
// Extract the employeenumber from the line
std::istringstream str(line);
if ( !(str >> employeenumber) )
{
// Problem reading the employeenumber.
// Stop reading.
break;
}
if (!std::getline(inputfile, line) )
{
// Problem reading the next line.
// Stop reading.
break;
}
_organisationrecord.name = line;
if (!std::getline(inputfile, line) )
{
// Problem reading the next line.
// Stop reading.
break;
}
_organisationrecord.occupation = line;
if (!std::getline(inputfile, line) )
{
// Problem reading the next line.
// Stop reading.
break;
}
_organisationrecord.department = line;
std::cout << _organisationrecord.employeenumber << std::endl;
std::cout << _organisationrecord.name << std::endl;
std::cout << _organisationrecord.occupation << std::endl;
std::cout << _organisationrecord.department << endl;
OrganisationRecords.push_back(_organisationrecord);
}

C++ Validate Emails Via Substrings

I'm trying to take the profile info(username, email, etc.) from one directory and put it in another. I've been debugging the code for this program, and while there are no errors, the program won't run, saying that the program "has stopped working". I have already looked on this website and others for any possible answers, and found none.
#include <string>
#include <cstring>
#include <iostream>
#include <istream>
#include <ostream>
#include <fstream>
#include <iomanip>
#include <filesystem>
using namespace std;
class path{
public:
string parent_directory;
string root_directory;
};
class Data{
public:
string userName;
string nickName;
string fName;
string arena_FName;
string lName;
string arena_LName;
string email;
string arenaEmail;
friend std::istream& operator>>(std::istream& input, Data& d);
};
std::istream& operator>>(std::istream& input, Data& d){
std::getline(input, d.userName);
std::getline(input, d.nickName);
//...
std::getline(input, d.arenaEmail);
return input;
}
int main(){
ifstream myfile("myfunk.txt", ios::in);
ofstream arena("arena.txt");
myfile.open("myfunk.txt", ios::in);
if(myfile){
cout << "Input file open." << endl;
}
arena.open("arena.txt", ios::out | ios::app);
if(arena){
cout << "Output file open." << endl;
}
cout << "file opening test: success" << endl;
int x = 0;
int y = 4101; //Total number of users in the directory.
int z = 0; //For inputting the required lines of info for each profile.
int profile = 0;
bool valid = false;
string role;
//string arenaRole;
bool post = false;
string line;
string p = "This PC/..."; //Path to the folder of the individual pictures.
//myVar.save("...");
string p = "...";
path path1;
path root_directory;
path parent_directory;
//bool is_directory(const std::filesystem::path& p, std::error_code& ec) noexcept; //Checks if current location is a directory.
//bool postPic;
const unsigned int MAXIMUM_DATA = 4100u;
Data database[MAXIMUM_DATA];
cout << "All variables but the filesystem have been accepted! Please install this program on the network." << endl;
while(x < y){
cout << "Primary loop functioning" << endl;
if(post = true){
getline(myfile, line); //Grab and read next line.
myfile >> line;
line = userName[x];
arena << "Username: " << userName[x] << "\n";
z++;
getline(myfile, line);
myfile >> line;
line = role[x];
arena << "Role: " << role[x] << "\n";
z++;
getline(myfile, line);
line = nickName[x];
myfile >> nickName[x];
arena << "nickname: " << nickName[x] << "\n";
z++;
getline(myfile, line);
line = fName[x];
myfile >> fName;
arena << "First Name: " << fName[x] << "\n";
z++;
getline(myfile, line);
line = lName[x];
myfile >> lName;
arena << "Last Name: " << lName[x] << "\n";
z++;
getline(myfile, line);
myfile >> line;
line = email[x];
arena << "Email: " << email[x] << "\n";
getline(myfile, line);
z = 0; //Next profile...
}
int data;
while(myfile >> data){
if(nickName[x] = NULL){
myfile >> "<Error> Some required information is missing! Contact user! </Error> /n";
valid = false;
post = false;
x++;
}
if(email[x] != NULL){
std::string str("#");
std::string str2(".com");
std::string str3(".net");
std::string str4(".edu");
if(std::size_t found = email[x].find(str) & (std::size_t found = email[x].find(str2) || std::size_t found = email[x].find(str3) || std::size_t found = email[x].find(str4)){
valid = true;
if(valid = true){
post = true;
}
}
else{
valid = false;
post = false;
x++;
}
}
}
}
}
}
x++;
}
//x++;
myfile.close(); //Closes the file in the directory.
arena.close(); //Closes the file in Arena.
return 0;
}
Let's rework your code.
First, let's create a data structure for the data:
class Data
{
public:
string userName;
string nickName;
string fName;
string arena_FName;
string lName;
string arena_LName;
string email;
string arenaEmail;
};
If you need an array for the data, it would be declared as:
const unsigned int MAXIMUM_DATA = 4100u;
Data database[MAXIMUM_DATA];
Next, let's overload the extraction operator>> to make reading easier:
class Data
{
public:
//...
friend std::istream& operator>>(std::istream& input, Data& d);
};
std::istream& operator>>(std::istream& input, Data& d)
{
std::getline(input, d.userName);
std::getline(input, d.nickName);
//...
std::getline(input, d.arenaEmail);
return input;
}
This simplifies your input loop to:
std::vector<Data> database;
Data d;
while (my_file >> d)
{
database.push_back(d);
}
You can query the amount of data read in by using the std::vector::size() method, i.e. database.size().
Also, you don't need a separate structure for a file path. A simple std::string will suffice. I recommend using forward slash, '/', because it is recognized by both Windows and *nix operating systems and won't be interpreted as an escape character.

What is wrong with this code? I'm new to c++!

#include <iostream>
#include <string>
#include <Windows.h>
using namespace std;
class UserBase{
public:
void GetUsername(string GetName){
MyUserName = GetName;
}
void GetPassword(string GetPassword){
GetPassword = MyPassword;
}
private:
string MyUserName;
string MyPassword;
};
int main(){
UserBase Input;
string MyName;
string MyPassword;
Input.GetUsername("test");
Input.GetPassword("noob");
cout << "enter your username, please." << endl;
cin >> MyName;
if (MyName == Input.GetUsername){
cout << "enter your password.." << endl;
cin >> MyPassword;
if (MyPassword == Input.GetPassword){
cout << "login was successfull" << endl;
Sleep(5000);
}
}
return 0; // if 0 then its a success
}
//so basically im trying to make a username and login password application. i am new to c++, i have only coded for 3 weeks and im just toying around. whenever i try to run it says that there were erros, but it didnt show me where and no red whatsoever.i use vs 2013.
here, I corrected it. Lot's of mistakes.
#include <iostream>
#include <string>
#include <Windows.h>
using namespace std;
class UserBase{
public:
string GetUsername(){
return MyUserName;
}
string GetPassword(){
return MyPassword;
}
void setUsername(string name){
MyUserName = name;
}
void setPassword(string password){
MyPassword = password;
}
private:
string MyUserName;
string MyPassword;
};
int main(){
UserBase Input;
string MyName;
string MyPassword;
Input.setUsername("test");
Input.setPassword("noob");
cout << "enter your username, please." << endl;
cin >> MyName;
if (MyName == Input.GetUsername()){
cout << "enter your password.." << endl;
cin >> MyPassword;
if (MyPassword == Input.GetPassword()){
cout << "login was successfull" << endl;
Sleep(5000);
}
}
return 0; // if 0 then its a success
}
you had no real getPassword, getUsername, you only had setters (wich are called get... wich is confusing !!). You also called "getPassword" (in wrong context) with wrong syntax.
getPassword; //wrong
getPassword(); //correct
You have
if (MyName == Input.GetUsername)
But GetUsername is not a valid method call firstly, and anyways, GetUsername() returns void, where you're expecting to compare to a string MyName. Also, because the two strings within the class are private access, you don't have a way of accessing them at all outside of the class, in your main function. If you added a getter method like string getUsername() const which returned the correct string inside, then you could compare to this.

having problems with authentication if i use if statement

There is an error when i try to compile and im not sure whats wrong with it.
This is a program which authencate username and password with textfile, seperated with ";" delimeter in a single textfile.
The error is quite long.
/tmp/ccgs7RYV.o: In function 'Employee::Employee()':
main2.cpp:(.text+0xa5): undefined reference to 'Employee::authenticate(std::basic_string, std::allocator>, std::basic_string, std::allocator>)'
/tmp/ccgs7RYV.o: In function `Employee::Employee()':
main2.cpp:(.text+0x231): undefined reference to 'Employee::authenticate(std::basic_string, std::allocator>, std::basic_string, std::allocator>)'
collect2: ld returned 1 exit status
#include<iostream>
#include<string>
#include <fstream>
using namespace std;
class Employee
{
public:
Employee();
bool authenticate(string, string);
};
Employee::Employee()
{
string username, password;
cout << "Username: ";
cin >> username;
cout << "Password: ";
cin >> password;
if (authenticate(username, password) == true)
cout << "Sucess" << endl;
else
cout << "fail" << endl;
}
bool authenticate(string username, string password)
{
std::ifstream file("login.txt");
std::string fusername, fpassword;
while (!file.fail())
{
std::getline(file, fusername, ';'); // use ; as delimiter
std::getline(file, fpassword); // use line end as delimiter
// remember - delimiter readed from input but not added to output
if (fusername == username && fpassword == password)
return true;
}
return false;
}
int main()
{
Employee();
return 0;
}
bool Employee::authenticate(string username, string password) {
std::ifstream file("login.txt");
std::string fusername, fpassword;
while (!file.fail()) {
std::getline(file, fusername, ';'); // use ; as delimiter
std::getline(file, fpassword); // use line end as delimiter
// remember - delimiter readed from input but not added to output
if (fusername == username && fpassword == password)
return true;
}
You need to use the scope resolution operator. You were just missing that.
Ok I'm going to try to sort out class design a bit.
class Employee
{
public:
Employee( std::string name, std::string password ) :
m_name( name ), m_password( password )
{
}
bool authenticate( const char * filename ) const;
private:
std::string m_name;
std::string m_password;
};
Employee readEmployeeFromConsole()
{
std::string name, password;
std::cout << "Name: ";
std::cin >> name;
std::cout << "Password: "
std::cin >> password;
return Employee( name, password );
}
bool Employee::authenticate( const char * filename ) const
{
// your implementation
}
int main()
{
Employee emp = readEmployeeFromConsole();
if( emp.authenticate( "input.txt" ) )
{
std::cout << "You're in!\n";
}
else
{
std::cout << "Get out!\n";
}
}