Acessing an array from a header file crashes program - c++

I recently finished a course on C++, to test to see what I knew from it I decided to start work on a operating system simulation, it seemed to be going fairly well up till I tried to implement a multiple users system by using a array to store user names, from which the user will select one and it will go into their user. However the problem with it that when I try and modify the array in the header file in the source file the program crashes.
header files:
#ifndef UBUNTU_LOGIN_H
#define UBUNTU_LOGIN_H
#include "Ubuntu_UserDetails.h"
#include <iostream>
#include <string>
#include <vector>
class Ubuntu_Login: protected UserDetails
{
public:
void Ubuntu_UserCreation();
void Ubuntu_login();
};
#endif // UBUNTU_LOGIN_H
#ifndef UBUNTU_USERDETAILS_H
#define UBUNTU_USERDETAILS_H
#include "Ubuntu_login.h"
#include <string>
#include <vector>
class UserDetails
{
protected:
std::string username;
std::string password;
std::string users[0];
};
#endif // UBUNTU_USERDETAILS_H
source files:
#include "Ubuntu_login.h"
#include "Ubuntu_UserDetails.h"
#include <iostream>
#include <vector>
#include <string>
void Ubuntu_Login::Ubuntu_UserCreation()
{
std::cout << "\t _____________" << std::endl;
std::cout << "\t|Create a user|\n" << std::endl;
std::cout << "Enter a username:" << std::endl;
std::getline(std::cin, username);
std::cout << "Enter a password:" << std::endl;
std::getline(std::cin, password);
users[0] = username;
std::cout << users[0] << std::endl;
std::cout << "User created successfully" << std::endl;
}
void Ubuntu_Login::Ubuntu_login()
{
std::cout << "\t ______" << std::endl;
std::cout << "\t|Log in|\n" << std::endl;
std::cout << "Select user" << std::endl;
}
#include "Ubuntu_login.h"
#include <iostream>
int main()
{
Ubuntu_Login UO;
UO.Ubuntu_UserCreation();
UO.Ubuntu_login();
}
when I try to run it I get as far as the initial password entry then the program crashed, I assume this is due to a stack overflow, but I wouldn't know how to solve it. Any help on solving this issue would be greatly appreciated as well as general help on the code as a whole :) .
also the reason I have not included things like storing passwords as hashes or not echoing the password is simply because I don't know the syntax to do it and I wanted to try to do the things I knew how to do first then add additional features later, so don't expect great code :P

Use std::vector<std::string> users
And then just users.push_back(username) to it. Dynamic array is suitable here.

In your Ubuntu_UserDetails.h you have this data member in the UserDetails class:
std::string users[0];
Then in a source file, you have this assignment:
users[0] = username;
If you access an item in an array with index 0, the array must have at least one element. In fact, index 0 refers to the first item in the array.
So, the users array should be defined as having some bigger size.
But, much better, consider using a convenient C++ container class for vectors, like std::vector.
So, in your header file, you can define a data member like this:
// Instead of:
// std::string users[0]
//
std::vector<std::string> userNames; // probably better than "users"
Then you can add new items to the vector using its push_back or emplace_back methods.

Related

Use of sstream causing a deleted copy constructor

So I am a CS student working on a project for exception handling (Try/catch). My teacher told us to implement the sstream library so we could use it in a class that outputs a message that includes a passed parameter of type int. For some reason unknown to me, when I use it, or even when I declare a variable of type stringstream, it causes a compile error with error message:
"copy constructor of 'tornadoException' is implicitly deleted because field 'ss' has a deleted copy constructor"
Here is my code. I am at a loss.
main.cpp
#include <iostream>
#include <string>
#include <sstream>
#include "tornadoException.h"
using namespace std;
int main()
{
try{
int tornado = 0;
cout << "Enter distance of tornado: ";
cin >> tornado;
if(tornado > 2){
throw tornadoException(tornado);
}
else{
throw tornadoException();
}
}
catch(tornadoException tornadoObj){
cout << tornadoObj.what();
}
}
tornadoException.cpp
#include <iostream>
#include <string>
#include <sstream>
#include "tornadoException.h"
using namespace std;
tornadoException::tornadoException(){
message = "Tornado: Take cover immediately!";
}
tornadoException::tornadoException(int m){
ss << "Tornado: " << m << "miles away!; and approaching!";
message = ss.str();
}
string tornadoException::what(){
return message;
}
tornadoException.h
#ifndef tornadoException_h
#define tornadoException_h
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class tornadoException{
public:
tornadoException();
tornadoException(int m);
string what();
private:
stringstream ss;
string message;
};
#endif
Alright, figured out the error but I'll leave up this post since I couldn't find the answer anywhere else. The problem was that I declared the stringstream buffer as a private variable in the class. The buffer needs to be declared locally within the function declaration it is being used in, in this case right before the loading of the buffer in the implementation file:
tornadoException::tornadoException(int m){
stringstream ss;
ss << "Tornado: " << m << " miles away!; and approaching!";
message = ss.str();
}
stringstream has a deleted copy constructor, which means that a stringstream object cannot be copied.
Since your tornadoException class has a stringstream variable, this means that your class cannot be copied either.
In your main function, you capture the exception by value, which means that you are copying it into the tornadoObj variable - which is not allowed.
Try changing the line
catch(tornadoException tornadoObj) to catch(tornadoException& tornadoObj) so that you're getting a reference to the exception instead of a copy of it.
This is actually a general rule: An exception shall always be caught by reference, not by copy: Core Guidelines E.15

I can't define a string in my C++ code in qt

My code is as follows.
#include "test.h"
#include "string"
#include "iostream"
using namespace std::string::find;
test::test(){
string str ("ffs test ffs");
string str2 ("test");
if (str.find(str2) != std::string::npos) {
std::cout << "found" << "\n";
} else {
std::cout << "not found" << "\n";
}
}
the issue I'm having is this, when trying to define a string in the C++ file qt states "unknown type name 'string'". Also on line 4 my 'import' highlights string as if it doesn't exist, despite it being an option the editor suggests to me while I'm typing it. What am I doing wrong here? Everything I find is to try and fix issues passing stuff to QStrings and nothing related to my issue as far as I can tell. I've tried both types of importing #include <thing> and #include "thing" on all the imports it doesn't seem to make a difference.
Use std::string instead of string.
#include "test.h"
#include <string>
#include <iostream>
test::test(){
std::string str ("ffs test ffs");
std::string str2 ("test");
if (str.find(str2) != std::string::npos) {
std::cout << "found" << "\n";
} else {
str::cout << "not found" << "\n";
}
}
Don't use using namespace (of course in your case, it wasn't a namespace, so that's another error), use <> for system headers.
After inclusion of the appropriate headers iostream, string etc, you can write:
using std::string;
This will bring in only string from the namespace std into your program.
And you can do this if you want to avoid typing std::string everywhere. You can do this for stream objects like cout, cin as well.
using std::cout;
using std::cin;
Use Scope operator :: in Your Code and Access manually to std class
std::string
it will help you !

Passing a Vector made of a Class to a function (C++)

I'm running into a lot of problems with this, primarily being that my passed Vector of my Class keeps getting flagged as an undeclared identifier. Any help on solving the problem or explanations to help me figure out what I don't understand would be greatly appreciated.
So here is a simplified version of what I have now:
main.cpp
#include "functions.h"
#include "vehicle.h"
int main()
{
int menuSelection;
vector<Vehicle> inventory;
do
{
cout << "Please make a selection:" << endl << endl;
cout << "1: Display Inventory" << endl;
.......
cout << "8 : Write inventory to file and exit" << endl << endl;
if (menuSelection == 1)
{
if (inventory.empty())
cout << "Database empty" << endl;
else
display(inventory);
.......
} while (menuSelection != 8);
return 0;
}
vehicle.h
#pragma once
#include "functions.h"
class Vehicle
{
private:
string VIN;
int year;
.......
// public:
// string getVIN();
.......
}
functions.h
#pragma once
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void display(vector<Vehicle>);
.......
void display(vector<Vehicle>& in)
{
Vehicle v;
cout << "VIN: " << v.getVIN(in)
}
.......
I've tried a bunch of different things to get it to work so that's why a lot of stuff may seem like odd syntax (I'm also not very good). My assignment is to have a menu in main.cpp which will create a vector from a class stored in vehicle.h, and then the menu is supposed to call functions which are located in functions.h that will communicate through vehicle.h to a fourth not included vehicle.cpp to work with information from the class.
In functions.h, void display(vector<Vehicle>); does not compile because Vehicle is undeclared at this point.
Also, in functions.h, void display(vector<Vehicle>& in) is a different overload to the previous prototype (the & makes a difference), probably not what you intended. And then you place a function body in functions.h -- this should not be there.
You need to organize your code so that Vehicle class definition appears, and then functions.h includes that.
So vehicle.h should look like:
#pragma once
#include <string>
// do NOT include functions.h
class Vehicle
{
// ...
};
and then functions.h should look like:
#pragma once
#include "vehicle.h"
// do NOT do "using namespace std;" in a header and don't include any unnecessary headers
void display(vector<Vehicle> &in);
and then functions.cpp should #include "functions.h" and contain the function body for display.
undeclared identifier means the compiler sees a name but don't see a declaration of that name (as a variable, class, function, etc.). It happens in your code in a few places, for example:
MyClass is used but not declared (main.cpp)
Vehicle is used but not declared (functions.h)
You use Vehicle.v but v not declared in class Vehicle (in addition, I doubt that this is what you intended - if you use class name Vehicle.v it means accessing a static variable, as opposed to vehicle.v).
It seems you lack some basic background. The most important thing is that you learn to decipher compiler errors, so at least you understand what went wrong.

cout print string variable cannot pass the build

Could any one help me to figure out which the following code cannot build successfully:
#include <iostream>
int main(void){
std::string str1("sfsfasfdsdf");
std::cout << str1 << std::endl;
return 1;
}
Thanks.
You have to include std::string header:
#include <string>
EDIT: According to #ShafikYaghmour's comments, include iostream sometimes brings in string, but it may not be the case for you if you only have the posted code.

typeinfo / typeid output

I'm currently trying to debug a piece of simple code and wish to see how a specific variable type changes during the program.
I'm using the typeinfo header file so I can utilise typeid.name(). I'm aware that typeid.name() is compiler specific thus the output might not be particularly helpful or standard.
I'm using GCC but I cannot find a list of the potential output despite searching, assuming a list of typeid output symbols exist. I don't want to do any sort of casting based on the output or manipulate any kind of data, just follow its type.
#include <iostream>
#include <typeinfo>
int main()
{
int a = 10;
cout << typeid(int).name() << endl;
}
Is there a symbol list anywhere?
I don't know if such a list exists, but you can make a small program to print them out:
#include <iostream>
#include <typeinfo>
#define PRINT_NAME(x) std::cout << #x << " - " << typeid(x).name() << '\n'
int main()
{
PRINT_NAME(char);
PRINT_NAME(signed char);
PRINT_NAME(unsigned char);
PRINT_NAME(short);
PRINT_NAME(unsigned short);
PRINT_NAME(int);
PRINT_NAME(unsigned int);
PRINT_NAME(long);
PRINT_NAME(unsigned long);
PRINT_NAME(float);
PRINT_NAME(double);
PRINT_NAME(long double);
PRINT_NAME(char*);
PRINT_NAME(const char*);
//...
}