Globalisation of variables within code block - c++

I am having trouble with using the array/matrix which was created within the first if statement (if (choice == 1)) at a later point within the code. I would like to edit the array (when I mention if (choice == 2), but the array created within the first "if" code block is localised. How can I get around this?
#include "pch.h"
#include <iostream>
#include <vector>
int main()
{
if (choice == 1)
{
std::cout << "Choose a letter from A to C, where A = 1" << std::endl;
short matNamechoice;
std::cin >> matNamechoice;
if (matNamechoice == 1)
{
bool matAlive = true;
std::vector<int> matrixA(0);
std::cout << "How many elements would you like to add to Matrix" << matNamechoice << "?" << std::endl;
short matAelements;
std::cin >> matAelements;
std::cout << "For the " << matAelements << "elements that you have created, please choose \
each element value: " << std::endl;
for (int n = 0; n < matAelements; ++n)
{
std::cout << "ELEMENT NO " << n << ":" << std::endl;
int elementValue = 0;
std::cin >> elementValue;
matrixA.push_back(elementValue);
}
std::cout << matAelements << " elements have been appended to matrixA." << std::endl;
}
if (matNamechoice == 2)
{
bool matBLive = true;
std::vector<int> matrixB(0);
std::cout << "How many elements would you like to add to Matrix " << matNamechoice << "?" << std::endl;
short matBelements;
std::cin >> matBelements;
std::cout << "For the " << matBelements << "elements that you have created, please choose \
each element value: " << std::endl;
for (int n = 0; n < matBelements; ++n)
{
std::cout << "ELEMENT NO " << n << ":" << std::endl;
int elementValue = 0;
std::cin >> elementValue;
matrixB.push_back(elementValue);
}
std::cout << matBelements << " elements have been appended to matrixB." << std::endl;
}
if (matNamechoice == 3)
{
bool matCLive = true;
std::vector<int> matrixC(0);
std::cout << "How many elements would you like to add to Matrix" << matNamechoice << "?" << std::endl;
short matCelements;
std::cin >> matCelements;
std::cout << "For the " << matCelements << "elements that you have created, please choose \
each element value: " << std::endl;
for (int n = 0; n < matCelements; ++n)
{
std::cout << "ELEMENT NO " << n << ":" << std::endl;
int elementValue = 0;
std::cin >> elementValue;
matrixC.push_back(elementValue);
}
std::cout << matCelements << " elements have been appended to matrixC. \n \n" << std::endl;
}
}
if (choice == 2 && (matAlive == true))
std::cout << "LOADING MATRICIES..." << std::endl;
for (int n = 10; n <= 100; n += 10)
{
std::cout << n << "%" << std::endl;
}
std::cout << "MATRIX DATA LOAD SUCCESSFUL..." << std::endl;
std::cout << "Enter 1 to edit a Matrix. Enter 2 to print a Matrix. Enter 3 to clear a Matrix." << std::endl;
short userChoice = 0;
std::cin >> userChoice;
}
int x = 0;
if (x < 100)
{
int y = 1;
}
return 0;
}

Move the variable outside of inner block:
bool matAlive = false;
std::vector<int> matrixA(0);
if (choice == 1) {
if (matNamechoice == 1) {
matAlive = true;
// ...
}
}
// ...
if (choice == 2 && (matAlive == true)) {
// ...
}

Related

How to static cast 2D vector size() (size_t to int) in C++?

I have not found any other posts which answer this question. This is a c++ program. I am receiving an error at the line:
int entryval = static_cast<int>(database[0].size());
The error says: Thread 1: EXC_BAD_ACCESS (code = 1, address = 0x8)
it directs my attention to a size() file within a vector file, to the line:
{return static_cast<size_type>(this->__end_ - this->__begin_);}
Am I formatting the type conversion incorrectly?
//Species ID,Kingdom,Phylum,Class,Order,Family,Genus,Species,Authority,Infraspecific rank,Infraspecific name,Infraspecific authority,Stock/subpopulation,Synonyms,Common names (Eng),Common names (Fre),Common names (Spa),Red List status,Red List criteria,Red List criteria version,Year assessed,Population trend,Petitioned
//2055,ANIMALIA,CHORDATA,MAMMALIA,CARNIVORA,OTARIIDAE,Arctocephalus,australis,"(Zimmermann, 1783)",,,,,Arctophoca australis,South American Fur Seal,Otarie fourrure Australe,Oso Marino Austral,LC,,3.1,2016,increasing,N
//41664,ANIMALIA,CHORDATA,MAMMALIA,CARNIVORA,OTARIIDAE,Arctocephalus,forsteri,"(Lesson, 1828)",,,,,Arctocephalus australis subspecies forsteri|Arctophoca australis subspecies forsteri,"New Zealand Fur Seal, Antipodean Fur Seal, Australasian Fur Seal, Black Fur Seal, Long-nosed Fur Seal, South Australian Fur Seal",,,LC,,3.1,2015,increasing,N
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
int main()
{
std::string entry;
std::vector<std::vector<std::string> > database;
std::ifstream file("C:/Users/mewtwo/Desktop/Programs/Seals.csv");
if (file) {
while (std::getline(file, entry)) {
size_t dbsize = database.size();
database.resize(dbsize + 1);
std::istringstream ss(entry);
std::string field, push_field("");
bool no_quotes = true;
while (std::getline(ss, field, ',')) {
if (static_cast<size_t>(std::count(field.begin(), field.end(), '"')) % 2 != 0) {
no_quotes = !no_quotes;
field.erase(remove(field.begin(), field.end(), '\"'), field.end());
}
push_field += field + (no_quotes ? "" : ",");
if (no_quotes) {
database[dbsize].push_back(push_field);
push_field.resize(0);
}
}
}
}
int dbval = static_cast<int>(database.size());
int entryval = static_cast<int>(database[0].size());
int animalChoice;
int dataChoice;
int switchChoice;
bool moreData;
bool moreAnimal = true;
while (moreAnimal == true) {
std::cout << "*********************ENDANGERED ANIMALS*********************" << std::endl;
std::cout << "Choose an animal! (1-" << dbval - 1 << ")" << std::endl;
for (int x = 1; x < database.size(); x++) {
if (database[x][14] != ""){
std::cout << x << ". " << database[x][14] << std::endl;
}
else {
std::cout << x << ". " << database[x][6] << " " << database[x][7] << std::endl;
}
}
std::cout << "\nAnimal choice:";
while (!(std::cin >> animalChoice) || animalChoice <= 0 || animalChoice >= dbval ){
std::cout << "\nYou pressed an incorrect key. Try again1." << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "\nAnimal choice:";
}
moreData = true;
while (moreData == true) {
std::cout << "\nWhat data do you want to access about the ";
if(database[animalChoice][14] != ""){
std::cout << database[animalChoice][14] << std::endl;
}
else{
std::cout << database[animalChoice][6] << " " << database[animalChoice][7] << std::endl;
}
std::cout << "?" << std::endl;
for (int x = 0; x < entryval; x++) {
std::cout << x + 1 << "." << database[0][x] << std::endl;
}
std::cout << "\nData choice:";
while (!(std::cin >> dataChoice) || dataChoice <= 0 || dataChoice >= entryval ){
std::cout << "You pressed an incorrect key. Try again2." << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "\nData choice:";
}
std::cout << database[animalChoice][14] << std::endl;
std::cout << database[0][dataChoice - 1] << ": " << database[animalChoice][dataChoice - 1] << std::endl;
std::cout << "\nWould you like to access more data about the " << database[animalChoice][14];
if(database[animalChoice][14] != ""){
std::cout << database[animalChoice][14] << std::endl;
}
else{
std::cout << database[animalChoice][6] << " " << database[animalChoice][7] << std::endl;
}
std::cout << "?" << std::endl;
std::cout << "1. Yes" << std::endl;
std::cout << "2. Access data of a different animal" << std::endl;
std::cout << "3. Quit" << std::endl;
std::cout << "\nChoice:";
while (!(std::cin >> switchChoice) || switchChoice <= 0 || switchChoice >= 4 ){
std::cout << "You pressed an incorrect key. Try again3." << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "\nChoice:";
}
if (switchChoice == 1) {
moreData = true;
}
else if (switchChoice == 2) {
moreData = false;
break;
}
else if (switchChoice == 3) {
exit(1);
}
else {
std::cout << "\nPROGRAM FAILURE" << std::endl;
exit(1);
}
}
}
return 0;
}
Also, are there any other obvious problems with my code? The code takes the whole species database of IUCN and presents the data using menus.
The low value in address = 0x8 hints that the code tried to access a member through a null pointer, which comes from an invalid "null" reference returned by database[0].
The only way operator[] would return such a broken reference is if the access was out of bounds, triggering undefined behaviour. In this case, it looks like your std::vector implementation just blindly indexes through its data pointer, which is null when the vector is empty.
Bottom line: nothing was ever inserted into your vector. This is probably caused by an error while reading your file. You should add error checking to your code and report them cleanly.

Setting up precision C++

So, i'm attempting to set the precision for input values in my code. I want the values to be printed with two decimal points afterwards of precision though i'm not exactly sure how.
Here's my code.
#include <iostream>
#include <iomanip>
float uphill, wellD, waterLvl, buckVol;
float buckAscRate, downHill, volume;
float last;
float timeReq;
int scene = 1;
void timeRequired()
{
std::setw(2);
std::setprecision(2);
std::cout << "Scenario " << scene << ":" << std::endl;
std::cout << "up hill" << " " << uphill << " sec" << std::endl;
std::cout << "well diamter" << " " << wellD << " in" << std::endl;
std::cout << "water level" << " " << waterLvl << " in" << std::endl;
std::cout << "bucket volume" << " " << buckVol << " cu ft" << std::endl;
std::cout << "bucket ascent rate" << " " << buckAscRate << " in/sec" << std::endl;
std::cout << "down hill" << " " << downHill << " sec" << std::endl;
std::cout << "required volume" << " " << volume << " cu ft" << std::endl;
timeReq = (uphill + downHill);
std::cout << "TIME REQUIRED" << " " << timeReq << " sec" << std::endl;
std::cout << " " << std::endl;
}
void scenarioCONT()
{
do
{
std::cin >> wellD;
std::cin >> waterLvl;
std::cin >> buckVol;
std::cin >> buckAscRate;
std::cin >> downHill;
std::cin >> volume;
std::cin >> last;
if (uphill <= 1) uphill = 2;
if (wellD <= 0) wellD = 1;
if (waterLvl <= 0) waterLvl = 1;
if (buckVol <= 0) buckVol = 1;
if (buckAscRate <= 0) buckAscRate = 1;
if (downHill <= 0) buckAscRate = 1;
if (volume <= 0) volume = 1;
if (last > 1)
{
uphill = last;
scenarioCONT();
}
} while (last != 0);
}
void scenario()
{
do
{
std::cin >> uphill;
std::cin >> wellD;
std::cin >> waterLvl;
std::cin >> buckVol;
std::cin >> buckAscRate;
std::cin >> downHill;
std::cin >> volume;
std::cin >> last;
if (uphill <= 1) uphill = 2;
if (wellD <= 0) wellD = 1;
if (waterLvl <= 0) waterLvl = 1;
if (buckVol <= 0) buckVol = 1;
if (buckAscRate <= 0) buckAscRate = 1;
if (downHill <= 0) buckAscRate = 1;
if (volume <= 0) volume = 1;
if (last > 1)
{
timeRequired();
uphill = last;
scenarioCONT();
}
scene++;
timeRequired();
} while (last != 0);
}
int main()
{
scenario();
system("pause");
}
I've been told to use ionmanip to set the precision, though i'm not 100% on how to do it. Any suggestions?
You can use std::setprecision function. The below example is directly taken from http://www.cplusplus.com/reference/iomanip/setprecision/
double f =3.14159;
std::cout << std::setprecision(5) << f << '\n';
std::cout << std::setprecision(9) << f << '\n';
If you want to output 2 decimal digits, you should use std::fixed, together with std::setprecision().
Take a look here.
For easier understanding, here is an example:
cout << setprecision(2)<< 3.1415; outputs 3.1 (2 digits in total) and
cout << setprecision(2)<<fixed<< 3.1415; outputs 3.14 (2 digits after floating point)

Printing values from a pointer to an array returned from a function (C++)

I have a function that returns a pointer to an array, and I want to print each value in the array
When I run it, it prints
int* merge_sort(int arr[], int size) {
if (size <= 1) {
return &arr[0];
}
int size1 = size/2;
int arr1[size1];
for (int i = 0; i < size1; i++) {
arr1[i] = arr[i];
}
int size2 = size-size1;
int arr2[size2];
for (int i = 0; i < (size2); i++) {
arr2[i] = arr[i+size1];
}
int p1 = 0;
int p2 = 0;
int sorted[size];
while (p1 < size1 && p2 < size2) {
if (arr1[p1] < arr2[p2]) {
sorted[p1+p2] = arr1[p1];
p1++;
} else {
sorted[p1+p2] = arr2[p2];
p2++;
}
}
while (p1 < size1) {
sorted[p1+p2] = arr1[p1];
p1++;
}
while (p2 < size2) {
sorted[p1+p2] = arr2[p2];
p2++;
}
cerr << "sorted: ";
for (int& i : sorted) {
cerr << i << ",";
}
cerr << endl;
return &sorted[0];
}
/**
* Auto-generated code below aims at helping you parse
* the standard input according to the problem statement.
**/
int main()
{
int N;
int horses[N];
cin >> N; cin.ignore();
for (int i = 0; i < N; i++) {
int Pi;
cin >> Pi; cin.ignore();
horses[i] = Pi;
}
int *sorted = merge_sort(horses, N);
cerr << "~ " << sorted[0] << " " << sorted[1] << " " << sorted[2] << endl;
//cerr << "~~ " << sorted << " " << *sorted << " " << endl;
cerr << "^ " << *(sorted + 0) << endl;
cerr << "^ " << *(sorted + 1) << endl;
cerr << "^ " << *(sorted + 2) << endl;
for (int i = 0; i < N; i++) {
//cerr << "i " << i << endl;
// cerr << "SORTED?? " << sorted[i] << endl;
cerr << "value: " << *(sorted + i) << " ";
//cerr << "*** " << *(sorted) + i << endl;
}
cerr << endl;
}
When I run it, it prints
sorted: 5,8,9,
~ 5 8 9
^ -5728
^ 942815029
^ 6297320
value: 959592096 value: 0 value: -157570874
Why is my for loop not printing the values "5, 8, 9"? How can I fix it so that it does?
(Edited to be more detailed. Also, I realize my merge sort is wrong but I'm just trying to get it to return something I can use right now ^.^)
Make sure that you returned correct pointer, for example (if pointer should point to values):
std::cerr << "\n" << sorted << " "<< &values << "\n";
should return same values:
003DFD64 003DFD64
Seems ok. Check your sort function
cpp.sh/4rrk
// Example program
#include <iostream>
#include <algorithm>
const size_t N = 3;
int* sort(int arr[]) {
// Sort arr and it should be equal to [5, 7, 8]
std::sort(arr, arr+N);
return arr;
}
int main() {
int values[N];
values[0] = 7;
values[1] = 5;
values[2] = 8;
for (size_t i = 0; i < N; ++i) {
std::cout << *(values + i) << " ";
}
std::cout << std::endl << values[0] << " " << values[1] << " " << values[2] << std::endl;
int *sorted = sort(values);
std::cout << "It is same arrays: " << values << " " << sorted << std::endl;
for (size_t i = 0; i < N; ++i) {
std::cout << *(sorted + i) << " ";
}
std::cout << std::endl << sorted[0] << " " << sorted[1] << " " << sorted[2] << std::endl;
return 0;
}
Output:
7 5 8
7 5 8
It is same arrays: 0x7329bfdc1d90 0x7329bfdc1d90
5 7 8
5 7 8

Empty string position to return as *

Very new to programming.
This bit of my program accepts two strand of DNA as input and output them in a double helix drawing. The problem is, if one of the two input strand is longer than the other, i will receive error.
So I thought, is it possible that if strand[add] is non-existent anymore, replace it with *?
#include <iostream>
#include <string>
#include <conio.h>
using namespace std;
void helix(string &strand1, string &strand2)
{
int nucleo;
int length;
if (strand1.length() >= strand2.length())
{
length = strand1.length();
}
else
{
length = strand2.length();
}
int add;
for (int add = 0; add <= length - 1; add++)
{
if (add > 7)
{
nucleo = add % 8;
}
else
{
nucleo = add;
}
if (nucleo == 0)
{
cout << " " << strand1[add] << "---"<<strand2[add] << endl;
}
else if (nucleo == 1)
{
cout << " " << strand1[add] << "------" << strand2[add] << endl;
}
else if (nucleo == 2)
{
cout << " " << strand1[add] << "------" << strand2[add] << endl;
}
else if (nucleo == 3)
{
cout << " " << strand1[add] << "---" << strand2[add] << endl;
cout << " *" << endl;
}
else if (nucleo == 4)
{
cout << " " << strand2[add]<<"---" << strand1[add] << endl;
}
else if (nucleo == 5)
{
cout << " " << strand2[add]<<"------" << strand1[add] << endl;
}
else if (nucleo == 6)
{
cout << " " << strand2[add]<<"------" << strand1[add] << endl;
}
else if (nucleo == 7)
{
cout << " " << strand2[add]<<"-----" << strand1[add] << endl;
cout << " *" << endl;
}
}
}
int main()
{
string strand1,strand2;
cout << "ENTER STRAND:" << endl;
cin >> strand1;
cout << "ENTER STRAND:" << endl;
cin >> strand2;
helix(strand1,strand2);
_getch();
return 0;
}
I was hoping I could still show the longer strand even if the other side of the strand is empty(want to put *) like this :imgur.com/t7riVrS
I think you inverted the legnth test, it should be:
//if (strand1.length() >= strand2.length())
if (strand1.length() < strand2.length())
{
length = strand1.length();
}
else
{
length = strand2.length();
}
Edit:
If you want it fill one the string with '*', replace the code above with:
while (strand1.length() < strand2.length())
{
strand1 += "*";
}
while (strand1.length() > strand2.length())
{
strand2 += "*";
}

C++ program to display votes in percentage not showing correct result

I'm solving some C++ problems from ebooks. I made this C++ program but it isn't working properly. I've 2 problems:
Even after applying the forumla (votePercentage = firstAnswer/totalVotes*100;) it isn't showing the output, but only 0.
The program should display the bar chart, how am I suppose to do that? Any hints, reference or solution will be appreciated.
Here is my code:
/*
* Write a program that provides the option of tallying up the
* results of a poll with 3 possible values.
* The first input to the program is the poll question;
* the next three inputs are the possible answers.
* The first answer is indicated by 1, the second by 2, the third by 3.
* The answers are tallied until a 0 is entered.
* The program should then show the results of the poll—try making
* a bar graph that shows the results properly scaled to fit on
* your screen no matter how many results were entered.
*/
#include <iostream>
#include <string>
void startPoll (void);
void showPoll (void);
void pollCheck (void);
std::string pollQuestion, answer1, answer2, answer3;
int pollChoice, firstAnswer, secondAnswer, thirdAnswer;
int main (void)
{
int totalVotes = 1;
float votePercentage;
startPoll();
showPoll();
for(;;totalVotes++)
{
if (pollChoice == 1)
{
firstAnswer = firstAnswer + 1;
}
else if (pollChoice == 2)
{
secondAnswer++;
}
else if (pollChoice == 3)
{
thirdAnswer++;
}
else
{
std::cout << "==============*======*======*==============\n"
<< " RESULT \n"
<< "==============*======*======*==============\n"
<< "Question: " << pollQuestion << "\n"
<< "Total Votes: " << totalVotes << "\n";
votePercentage = (firstAnswer/totalVotes)*100;
std::cout << answer1 << ": " << firstAnswer << " votes. | " << votePercentage << "\n";
votePercentage = secondAnswer/totalVotes*100;
std::cout << answer2 << ": " << secondAnswer << " votes. | " << votePercentage << "\n";
votePercentage = thirdAnswer/totalVotes*100;
std::cout << answer3 << ": " << thirdAnswer << " votes. | " << votePercentage << "\n";
return 0;
}
std::cout << "\nEnter your vote again\nOR\nuse 0 to show the results.\n";
std::cin >> pollChoice;
}
std::cout << "Error: Something went wrong!\n";
}
void startPoll (void)
{
std::cout << "Enter your poll question:\n";
getline (std::cin, pollQuestion, '\n');
std::cout << "Enter answer 1:\n";
getline (std::cin, answer1, '\n');
std::cout << "Enter answer 2:\n";
getline (std::cin, answer2, '\n');
std::cout << "Enter answer 3:\n";
getline (std::cin, answer3, '\n');
}
void showPoll (void)
{
std::cout << "==============|======|======|==============\n"
<< " POLL \n"
<< "==============|======|======|==============\n"
<< pollQuestion << "\n"
<< "1. " << answer1 << "\n"
<< "2. " << answer2 << "\n"
<< "3. " << answer3 << "\n\n"
<< "Enter 1,2 or 3:\n\n";
std::cin >> pollChoice;
pollCheck();
}
void pollCheck (void)
{
if (pollChoice != 1 && pollChoice != 2 && pollChoice != 3)
{
std::cout << "Wrong choice entered! Please try again.\n\n";
return showPoll();
}
}
You need to take care that integer/integer = integer. In your case, changing
(firstAnswer/totalVotes)*100
to
(1.0*firstAnswer/totalVotes)*100
or
(firstAnswer*100.0/totalVotes)
should work. They all give a floating point result.
Well, the solution for the Bar Chart could be the following:(Not written by me) I think thats very self explaining because its really basic
void line (int n, char c)
{
// this is the loop for n
for (int i = 0; i < n; i++)
cout << c << endl;
}
Here is my solution, you can see how I made the bars work by reading the comments.
#include <iostream>
using namespace std;
int main()
{
int a = 0;
int b = 0;
int c = 0;
cout << "What is your favorite animal? 1 Cat, ";
cout <<"2 Dog, 3 Fish, 0 Count votes" << endl;
//Choice counter
while (true)
{
int choice;
cout << "Choice: ";
cin >> choice;
if(choice == 1)
a++;
else if(choice == 2)
b++;
else if(choice == 3)
c++;
else if(choice == 0)
break;
else
continue;
}
cout << endl << " 1: " << a << endl;
cout << " 2: " << b << endl;
cout << " 3: " << c << endl;
cout << endl << "1\t" << "2\t" << "3\t" << endl;
//Finds the max voted option
int max = 0;
if(a > b && a > c)
max = a;
else if(b > c && b > a)
max = b;
else if(c > a && c > b)
max = c;
/* If the max voted option is bigger than 10, find by how much
we have to divide to scale the graph, also making 10 bar
units the max a bar can reach before scaling the others too */
int div =2;
if(max > 10)
{
do
{
max = max/div;
if(max < 10)
break;
div++;
}while(true);
}else
div = 1;
//Sets the final number for the bars
a=a/div;
b=b/div;
c=c/div;
if(a==0)
a++;
if(b==0)
b++;
if(c==0)
c++;
//Creates the bars
while(true)
{
if(a>0)
{
cout << "[]" << "\t";
a--;
}else
cout << " ";
if(b>0)
{
cout << "[]" << "\t";
b--;
}else
cout << " ";
if(c>0)
{
cout << "[]" << "\t";
c--;
}else
cout << " ";
cout << endl;
if(a==0 && b==0 && c==0)
break;
}
}