Why am I getting this error message? C++ - c++

I am getting this error every time I try to run my program.
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
terminate called after throwing an instance of
'std::logic_error' what(): basic_string::_M_construct null not valid
#include <iostream>
#include <string>
using namespace std;
struct Bin
{
string desc;
int partsQty;
};
void addParts(Bin bList[], int i);
void removeParts(Bin bList[], int i);
int main() {
char response;
int binNumber;
const int NUM_OF_BINS = 11;
Bin binList[NUM_OF_BINS] = {
{0,0},
{"Valve", 10},
{"Earing",5},
{"Bushing",15},
{"Coupling",21},
{"Flange",7},
{"Gear",5},
{"Gear Housing",5},
{"Vaccum Gripper",25},
{"Cable",18},
{"Rod",12}
};
for(int i=1;i < 11;i++)
{
cout << "Bin #" << i << " Part: " << binList[i].desc << " Quantity " << binList[i].partsQty << endl;
}
cout << "Please select a bin or enter 0 to terminate";
cin >> binNumber;
cout << "Would you like to add or remove parts from a certain bin?(A or R)";
cin >> response;
if(response == 'a')
addParts(binList, binNumber);
else if(response == 'r')
removeParts(binList, binNumber);
return 0;
}
void addParts(Bin bList[], int i)
{
int parts;
int num;
cout << "How many parts would you like to add?";
cin >> num;
parts = bList[i].partsQty + num;
cout << "Bin # " << i << " now contains " << parts << " parts";
}
void removeParts(Bin bList[], int i)
{
int parts;
int number;
cout << "Which bin would you like to remove parts to?";
cin >> i;
cout << "How many parts would you like to remove?" << endl;
cin >> number;
parts = bList[i].partsQty - number;
if(parts < 0)
cout << "Please enter a number that isn't going to make the amount of parts in the bin negative.";
cin >> number;
parts = bList[i].partsQty - number;
cout << "The remaining amount of parts in bin #" << i << " is " << parts;
}

It comes from:
{0,0}
in your list of initializers for binList. 0 is not a correct initializer for std::string. You could perhaps use {"", 0} instead, or even {}.
Another idea might be to revise your program logic so that you do not require a dummy entry at the start of the array.

Related

Pointers in Dev C++ vs Visual Studio

I have coded a program that gets the information of employees of a company, when I run it in Dec C++, it does run without any errors, but when I run it in Visual Studio, it returns the following error :
Error C4703 potentially uninitialized local pointer variable 'data' used
and VS asks me to rewrite the pointer like this :
employ *data{};
instaed of : employ *data;
Can anyone please explain why does it happen? and What this {} means here? Is it a thing of C++ or VS?
#include <iostream>
using namespace std;
struct employ {
long int emp_num;
string fn;
string ln;
int work_days;
long int payday;
};
int main()
{
int n=0;
employ *data;
int act;
do {
cout << "___________________________________________________________________________________________________________";
cout << "\n\n\t\tWelcome to the EMPLOTASK!";
cout << "\n\t\tFor doing any of the commands, enter number of that command.";
cout << "\n\t\t_______________________________________________________________";
cout << "\n\n\t\t\ ADD & EDIT : ";
cout << "\n\t\t[1] Add new employees.";
cout << "\n\t\t[2] Edit an existing employee.";
cout << "\n\t\t[3] Delete an existing employee.";
cout << "\n\t\t[4] Print list of all employees.";
cout << "\n\t\t_______________________________________________________________";
cout << "\n\n\t\t\ ACTIONS : ";
cout << "\n\t\t[5] Sort based on their salary.";
cout << "\n\t\t[6] Search for an emplyee.";
cout << "\n\t\t[7] Calculate the average salary.";
cout << "\n\t\t[8] Show maximum and minimum sallary.";
cout << "\n\n\t\tWhat do you want to do?";
cin >> act;
if (act > 8)
cout << "Invalid request!" << endl;
switch (act)
{
case 1: {
cout << "\n\t\t_______________________________________________________________";
cout << "\n\n\t\t\'ADD NEW EMPLOYEES\'";
cout << "\n\t\tEnter number of the employees : ";
cin >> n;
data = new employ[n];
for (int i = 0; i < n; i++)
{
cout << "\n\t\t========== Employee number " << i + 1 << " ==========";
cout << "\n\t\tFirst name : ";
cin >> data[i].fn;
cout << "\t\tLast name : ";
cin >> data[i].ln;
cout << "\t\tEmployee's number : ";
cin >> data[i].emp_num;
cout << "\t\tDays of work : ";
cin >> data[i].work_days;
cout << "\t\tDaily rate : ";
cin >> data[i].payday;
}
cout << "\n\t\t=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=";
cout << "\n\t\tOperatuon's done successfully! =)";
cout << "\n\t\t=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << endl;
break;
}
case 2: {
cout << "\n\t\t_______________________________________________________________";
cout << "\n\n\t\t\'EDIT AN EMPLOYEE\'";
cout << "\n\t\tEnter the employee number : ";
int em_num;
cin >> em_num;
int yes = 0;
if (n == 0)
{
cout << "There's no employee!";
}
for (int i = 0; i < n; i++)
{
if (em_num == data[i].emp_num)
{
for (int j = 0; j < n; j++)
{
cout << "\n\t\t========== Edit Employee number " << i + 1 << " ==========";
cout << "\n\t\tFirst name : ";
cin >> data[i].fn;
cout << "\t\tLast name : ";
cin >> data[i].ln;
cout << "\t\tEmployee's number : ";
cin >> data[i].emp_num;
cout << "\t\tDays of work : ";
cin >> data[i].work_days;
cout << "\t\tDaily rate : ";
cin >> data[i].payday;
yes++;
}
}
}
if (yes == 0)
{
cout << "The entered employee number is invalid.";
}
break;
}
default:
break;
}
} while (act != 0);
return 0;
}
Regarding {}: uniform initialization(C++11). It enables you to initialize everything in the same way. It also provides better safety guarantees when it comes to narrowing conversions.
The following code shows some examples.
#include <iostream>
#include <string>
#include <vector>
struct Point
{
Point(float x, float y) : m_x{ x }, m_y{ y } {}
float m_x;
float m_y;
};
int main()
{
int a{ 0 }; // same as a{}
int b{ 1 };
// int c{ 2.0 }; // at least warning, often error
double d{ 3.0 };
char* pc{nullptr}; // same as pc{}
std::string s{ "C++" };
std::vector<int> vi{1, 2, 3, 4, 5};
Point p1{ 3.0f, 4.0f };
}

Error when passing vectors as parameter in Xcode

I'm working on a program that I've seen other people do online except I'm trying to use functions to complete it to make it somewhat more challenging for me to help me better understand pointers and vectors. The problem I'm having in xcode is I keep getting this error..
Expected ';' after top level declarator
right here on my code,
void showMenu(menuItemType (&menu_List)[8])[], vector<int> numbers) //<<< Error
{
cout << fixed << setprecision(2);
...
Where I am trying to use vector numbers in my function. Basically I want the numbers from the function passed back so that I can use them in another function I have not created yet. I've googled this error and it seems like no one can give a straight answer on how to fix this problem. Is anyone familiar with how to correct this? By no means is this code finished I'm just trying to get information regarding vectors as a parameter because from what I'm seeing syntax wise on other sites it looks to be correct. Thanks for your feedback.
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
#include <iterator>
using namespace std;
struct menuItemType{
string menuItem;
double menuPrice;
};
void getData(menuItemType (&mlist)[8]);
void showMenu(menuItemType (&menu_List)[8], vector<int> numbers);
int main() {
vector<int> temp;
menuItemType menuList[8];
getData(menuList);
showMenu(menuList,temp);
/*
cout << menuList[0].menuItem << " " << menuList[0].menuPrice << endl;
cout << menuList[1].menuItem << " " << menuList[1].menuPrice << endl;
*/
return 0;
}
void getData(menuItemType (&mlist)[8]){
string Str;
ifstream infile;
infile.open("cafe135.txt");
if(infile.is_open())
{
for (int i = 0; i < 8; ++i){
infile >> mlist[i].menuItem >> mlist[i].menuPrice;
}
}
else cout << "Unable to open file";
}
void showMenu(menuItemType (&menu_List)[8])[], vector<int> numbers)
{
cout << fixed << setprecision(2);
string choice;
cout << "Would you like to view the menu? [Y] or [N]: ";
cin >> choice;
cout << endl;
int x = 3;
int count = 1;
while (choice != "Y" && choice != "N" && choice != "y" && choice != "n")
{
if (count == 4){
return;
}
cout << "Error! Please try again ["
<< x
<< "] selections remaining: ";
cin >> choice;
cout << endl;
x--;
count++;
}
if (choice == "N" || choice == "n"){
return;
}
else
{
cout << "___________ Breakfast Menu ___________" << endl;
for (int i = 0; i < sizeof(menu_List)/sizeof(menu_List[0]); ++i)
{
cout << "Item "
<< (i+1)
<< ": "
<< menu_List[i].menuItem
<< " "
<< menu_List[i].menuPrice
<< endl;
}
cout << endl;
string itemSelection = " ";
//int str_length = 0;
cout << "Select your item numbers separated"
<< " by spaces (e.g. 1 3 5) Select 0 to cancel order: ";
cin.ignore();
getline(cin, itemSelection);
if (itemSelection == "0")
{
return;
}
vector<int> vectorItemSelection;
stringstream text_stream(itemSelection);
string item;
while (getline(text_stream, item, ' '))
{
vectorItemSelection.push_back(stoi(item));
}
int n = vectorItemSelection.size();
int arr[n];
for (int i = 0; i < n; i++)
{
arr[i] = vectorItemSelection[i];
}
}
}
Compare how menu_List is declared in this line
void showMenu(menuItemType (&menu_List)[8], vector<int> numbers);
and this line
void showMenu(menuItemType (&menu_List)[8])[], vector<int> numbers)
The first one is correct.
But I have to agree with the comments above, you are mixing up a lot of different things here. Just use vectors, 99% of the time it's the right thing to do anyway. and it's easier to learn one thing at a time.
Prefer to write your code like this
void getData(vector<menuItemType>&);
void showMenu(vector<menuItemType>&, vector<int> numbers);
int main() {
vector<int> temp;
vector<menuItemType> menuList(8);
...
See? Just use vectors everywhere.

printing name in multiple for loops and arrays

I've come across a little problem, how do I print the winning candidate's name? See the instructions here are, input five names, their number of votes and percentage of votes, whoever has the highest wins. I don't know if I did my code right, but it works.. well except for the name part. I've tried everything from a lot of for loops to transfer the array or what.
I'm almost done with the code.
Here's the code
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
char candidates[50];
int votes[5]={0};
float percent[5]={0};
int a,b,c,d,e,i;
int maxx;
int champ=0;
char winner[50];
cout << "Enter the candidates' last names: ";
cout << endl;
for(a=1;a<=5;a++)
{
cout << a << ". ";
cin >> candidates;
}
cout << endl;
cout << "Enter their number of votes: " << endl;
for(b=1;b<=5;b++)
{
cout << b << ". ";
cin >> votes[b];
}
cout << endl;
cout << "percentage of votes: " << endl;
for(c=1;c<=5;c++)
{
cout << c << ". ";
percent[c]=votes[c]*0.2;
printf("%.2f\n", percent[c]);
}
cout <<"Candidates\t\tVotes\t\t% of Votes" << endl;
for(int k=1;k<=5;k++)
{
cout << candidates[k] << "\t\t\t" << votes[k] << "\t\t\t";
printf("%.2f\n", percent[k]);
}
maxx=percent[0];
for(d=1;d<=5;d++)
{
if(maxx<percent[d]);
{
//what happens here?
}
}
return 0;
}
You should keep a 2d array of characters or array of string for storing candidate names instead of a 1-d array.
char candidates[5][10]; //
for(int i = 0; i < 5; i++)
{
cin >> candidates[i];
}
Then keep a variable to store index for winning candidate
int winIndex = 0;
int winPercent = 0;
for(int i = 0; i < 5; i++)
{
if(percent[i] > winPercent)
{
winPercent = percent;
winIndex = i;
}
}
Finally print name of winning candidate;
cout << candidates[winIndex];
In object oriented approach, you may create a class with following information
class Candidate
{
string name;
int votes;
float percent;
};
Use string candidates[50]; instead of char candidates[50];
then cin >> candidates[a];

C++, Program ends before allowing input

To practice C++ I am trying to make a simple program that allows a user to input a name followed by a score and then allows the user to enter a name and get the score that name was entered with. The program works fine until I enter an escape character (ctrl + z) once I'm done entering names, after entering the escape character the program will output the line "Enter name of student to look up the score" but not allow the user to input the name and instead reads out "Press any key to exit". I'm totally stumped on how to fix this and any help is greatly appreciated.
#include "stdafx.h"
#include <std_lib_facilities.h>
int main()
{
vector <string>names;
vector <int>scores;
string n = " "; // name
int s = 0; // score
string student = " ";
cout << "Enter the name followed by the score. (Ex. John 89)" << endl;
while(cin >> n >> s)
{
for(size_t i = 0; i < names.size(); ++i)
{
if(n == names[i])
{
cout << "Error: Duplicate name, Overwriting" << endl;
names.erase(names.begin() + i);
scores.erase(scores.begin() + i);
}
}
names.push_back(n);
scores.push_back(s);
}
cout << "Name: Score:" << endl;
for(size_t j = 0; j < names.size(); ++j)
{
cout << names[j];
cout <<" " << scores[j] << endl;
}
cout << "Enter name of student to look up their score" << endl;
cin >> student;
for(size_t g = 0; g < names.size(); ++g)
{
if(student == names[g])
{
cout << "Score: " << scores[g] << endl;
}
}
keep_window_open();
return 0;
}
After you press the CTRL+Z key combination, which induces an EOF state to the cin stream, you need to bring the cin input stream back to its normal 'good' state to be able to use it again.
Add the following code after your for loop where you print the contents of the vectors.
cin.clear();
You may also check the state of the standard input stream using the rdstate() function. Anything other than 0 means that the standard stream is in an error state.
As has been said, you need to clear the error state on std::cin after reading the records failed.
std::cin.clear();
should do the trick. Here's my take on this using
proper data structures instead of two isolated vectors
const correctness
separating functions
no more hacky .erase() calls with magic indexes
#include <map>
#include <iostream>
std::map<std::string, int> read_records()
{
std::map<std::string, int> records;
std::string name;
int score;
std::cout << "Enter the name followed by the score. (Ex. John 89)" << std::endl;
while(std::cin >> name >> score)
{
if (records.find(name) != end(records))
{
std::cout << "Error: Duplicate name, Overwriting" << std::endl;
} else
{
records.insert({name, score});
}
}
std::cin.clear();
return records;
}
int main()
{
auto const records = read_records();
std::cout << "Name\tScore:" << std::endl;
for(auto& r : records)
std::cout << r.first << "\t" << r.second << std::endl;
std::cout << "Enter name of student to look up their score: " << std::flush;
std::string name;
if (std::cin >> name)
{
std::cout << "\nScore: " << records.at(name) << std::endl;
}
}
If you required contiguous storage, use a flat_map like the one from boost.

How to use a dynamically sized array of structs?

I have to make my homework. It is console application which uses an array of structs that keep information about a computer(brand, year of manufactoring, weight and inventory number). So I wrote a completely working program, but I want to use a dynamic array, because I dont know how many records the user will input.
Is there way to do this. To add new records in array until the user say n/N? Any suggestions?
This is my version of program:
#include "stdafx.h"
#include <iostream>
using namespace std;
struct ComputerInfo
{
char computerMark[20], invertarNumber[6];
unsigned int year;
float weight;
};
ComputerInfo computerArray[300];
ComputerInfo AddComputers(ComputerInfo compterArray[], int counter)
{
cout << "Enter mark of the computer: ";
cin >> computerArray[counter].computerMark;
cout << "Enter year of establish: ";
cin>> computerArray[counter].year;
while ((computerArray[counter].year < 1973)
|| (computerArray[counter].year > 2013))
{
cout << "INVALID YEAR!!!" << endl;
cout << "Enter year of establish: ";
cin>> computerArray[counter].year;
}
cout << "Enter computer weidth: ";
cin >> computerArray[counter].weight;
cout << "Enter computer invertar number(up to six digits): ";
cin >> computerArray[counter].invertarNumber;
return computerArray[counter];
}
void ShowRecords()
{
int counter = 0;
while (computerArray[counter].year != 0)
{
cout << "Mark: " << computerArray[counter].computerMark << endl;
cout << "Year: " << computerArray[counter].year << endl;
cout << "Weidth: " << computerArray[counter].weight << endl;
cout << "Inv. number: " << computerArray[counter].invertarNumber << endl << endl;
counter++;
}
}
void MoreThanTenYearsOld(ComputerInfo computerArray[])
{
int counter = 0;
float counterOldComputers = 0;
float computerPer = 0;
while (computerArray[counter].year == 0)
{
if (computerArray[counter].year <= 2003)
{
counterOldComputers++;
}
counter++;
}
computerPer = counterOldComputers / 3;
cout << endl;
cout << "Percantage of old computers is: " << computerPer << endl;
}
int main()
{
int counter = 0;
float computerPer = 0;
char answer = 'y';
for (int i = 0; i <= 299; i++)
{
strcpy(computerArray[i].computerMark,"");
}
while((answer == 'Y') || (answer == 'y'))
{
computerArray[counter] = AddComputers(computerArray, counter);
cout << endl;
cout << "Do you want to enter more records (Y/N): ";
cin >> answer;
cout << endl;
counter++;
}
MoreThanTenYearsOld(computerArray);
return 0;
}
Yes. Instead of your array, use
std::vector<ComputerInfo> computerArray;
and you can add as many objects as you want:
ComputerInfo c;
// read the data
computerArray.push_back(c);
now, computerArray[0] will have the info in c.
You'll need to #include <vector>.
Also, instead of char computerMark[20] you can use a std::string.
You have two options:
1) Use std::vector instead of an array. This is a very powerful tool and certainly worth learning how to use.
2) Dynamically allocate the array and resize it as you add more items. Basically this means writing your own version of std::vector. This is a good way to strengthen your programming skills. You will learn what goes into writing standard classes and functions. However, I advise using std::vector in more serious programming because it has already been thoroughly tested and debugged.