Comparing two arrays of strings c++ - c++

Ok thank you everyone for your comments. I have fixed much of it. Now when I compile it, it gives me an error on line in main where I call getPercent() saying this :
error: cannot convert ‘std::string’ to ‘std::string*’ for argument ‘3’
to ‘void getPercent(int, std::string*, std::string*, std::string*)’
What can fix this?
#include <iostream>
#include <string>
using namespace std;
string getYours()
{
cout << "Enter your DNA sequence: " ;
string sequence;
cin >> sequence;
return sequence;
}
int getNumber()
{
cout << "Enter the number of potential relatives: ";
int number;
cin >> number;
cout << endl;
return number;
}
void getNames(int number, string name[])
{
for (int i = 0; i < number; i++)
{
cout << "Please enter the name of relative #" << i + 1 << ": ";
cin >> name[i];
}
}
void getSequences(int number, string name[], string newsequence[])
{
cout << endl;
for (int i = 0; i < number; i++)
{
cout << "Please enter the DNA sequence for " << name[i] << ": ";
cin >> newsequence[i];
}
}
void getPercent(int number, string name[], string sequence[],
string newsequence[])
{
cout << endl;
int count = 0;
for (int i = 0; i < number; i++)
{
if (sequence[i] == newsequence[i])
count = count + 10;
cout << "Percent match for " << name[i] << ": " << count << "%";
}
}
int main()
{
string sequence = getYours();
int number = getNumber();
string name[50];
string newsequence[50];
getNames(number, name);
getSequences(number, name, newsequence);
getPercent(number, name, sequence, newsequence);
return 0;
}

A few problems:
getYours() has no side effects. You probably meant to assign to the string sequence in main(), but instead are assigning to a local variable that will be destroyed as it goes out of scope.
No error checking for too many elements in your arrays (try using a std::vector).
You stop at 10 in getPercent() instead of number elements (if that's what you wanted).
In getPercent(), count is not initialized to 0. Something seems strange about the logic in getPercent(), so I am not exactly sure what you are trying to do.
The arguments sequence and newsequence in getPercent() are actually the same type, and would compile fine.
And probably a few other things I've overlooked.

Related

How to add numbers bigger than long long, long, int and etc C+11

forum!
I have a project where we are supposed to add numbers that are length 14 or greater. I did some digging and realized that there is no current type that takes numbers this big. So, I have the user enter the numbers as a string and the numbers they would like to add are stored in a static string array.
I would like to add the numbers from the static array together. The issue is I have no idea how to deal with numbers this large. I am assuming you would have to convert the string values into int's and add them up one by one? I am having a big issue coming up with the logic for this. Any help would be appreciated.
If not, if you can provide some context which could help me come up with some logic.
The only library functions I can use is iostream and string.
Here is my code if you'll like to see my logic! I have some test cases I am trying to figure out so please ignore the comment outs. But, if you run the code you should get a better sense of what I am trying to get out. I am trying to sum up the numbers the user enters.
#include <iostream>
#include <string>
using namespace std;
void amountOfNumbers(string &userAmount, int MIN_AMOUNT, int MAX_AMOUNT){
//string alpha = "abcdefghijklmnopqrstuvwxyz";
cout << "How many numbers? -> ";
cin >> userAmount;
cout << endl;
while(!userAmount.find("abcdefghijklmnopqrstuvwxyz")){
cout << "ERROR: must be a number, try again ->";
cout << userAmount;
//cin.clear();
//cin.ignore(1000, '\n');
cin >> userAmount;
cout << endl;
}
int temp = stoi(userAmount);
while((temp < MIN_AMOUNT) or (temp > MAX_AMOUNT)){
cout << "ERROR: Program can only take in " << MIN_AMOUNT << " - "<< MAX_AMOUNT << " numbers. Try again ->";
cin >> userAmount;
cout << endl;
temp = stoi(userAmount);
}
}
void takeNumbers(string &userAmount, string (&numberArray)[11]){
int temp = stoi(userAmount);
for (int i = 0; i < temp; i++){
cout << "Input number #" << i+1 << " ->";
cin >> numberArray[i];
cout << endl;
}
}
void display(string &userAmount, string (&numberArray)[11]){
int temp = stoi(userAmount);
for (int i = 0; i < temp; i++){
cout << numberArray[i];
cout << endl;
}
}
void addNumber(string &userAmount, string (&numberArray)[11]){
}
int main() {
const int MIN_AMOUNT = 2, MAX_AMOUNT = 11, MAX_INPUT = 14;
string userAmount = "0";
string numberInput;
// static array
string numberArray [MAX_AMOUNT];
amountOfNumbers(userAmount, MIN_AMOUNT, MAX_AMOUNT);
takeNumbers(userAmount, numberArray);
display(userAmount, numberArray);
}

Why am I getting this error message? 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.

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];

Segmentation fault using string pointer

I'm a C++ newbie, I'm trying to put in practice pointers with strings. The program I have made is just to store strings the user types in the command line. But I'm getting segfault, not sure why.
This is the code:
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
//This code is meant to learn how to use pointers and strings
//Ask the user for who are they in the family and save it in string array!
void print_string (string* Value, int const nSize);
int get_names(string* Family_input);
int main ( int nNumberofArgs, char* pszArgs[])
{
cout << "Tis program stores your family members\n";
cout<< "Type the names and write 0 to exit\n";
string familia_string;
string* familia = &familia_string;
int family_number;
family_number=get_names(familia);
cout << "The family members are: ";
print_string(familia, family_number);
cout << endl;
return 0;
}
int get_names(string* Family_input)
{
int i=0;
string input="";
string old_input="";
while (input!="0")
{
cout << "type " << i <<" member\n";
//cin >> *(Family_input+i);
//input=*(Family_input+i);
cin >> input;
*(Family_input + old_input.length()) = input;
old_input=input;
i++;
}
return i;
}
void print_string (string* Value, int const nSize)
{// I don't want to &psValue to be changed!
for (int i=0; i<nSize; i++)
{
cout << *(Value+i) << " ";
//&psValue++;
}
}
I'm not sure if it's because I'm not taking correctly the size of the string, or I'm not using correctly the pointer or is that I have to allocate memory before using the offset.
As #kleszcz pointed out already, the line
*(Family_input + old_input.length()) = input;
is wrong. You are accessing memory that you are not supposed to.
The easiest fix is to change get_names slightly:
int get_names(string* Family_input)
{
int i=0;
string input="";
while (input!="0")
{
cout << "type " << i <<" member\n";
cin >> input;
*Family_input += input; // Just keep on appending to the input argument.
*Family_input += "\n"; // Add a newline to separate the inputs.
i++;
}
return i;
}
Also change print_string to:
void print_string (string* Value)
{
cout << *Value;
}
Of course, print_string has become so simple, you don't need to have it at all.
You could change get_names to use a reference argument instead of a pointer argument. This is a better practice.
int get_names(string& Family_input)
{
int i=0;
string input="";
while (input!="0")
{
cout << "type " << i <<" member\n";
cin >> input;
Family_input += input; // Just keep on appending to the input argument.
Family_input += "\n"; // Add a newline to separate the inputs.
i++;
}
return i;
}
Then, change the call to get_names. Instead of using
family_number=get_names(familia);
use
family_number=get_names(familia_string);
You get seg fault because you haven't allocate memory for an array of strings.
*(Family_input + old_input.length()) = input;
This is total nonsense. If you'd have an array you increment index only by one not by length of string.
If you want to save different names in different string objects I would suggest:
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
void print_string(string** Value, int const nSize);
void get_names(string** Family_input, int count);
int main(int nNumberofArgs, char* pszArgs[]) {
cout << "This program stores your family members\n";
int family_number;
cout << "Types the number of family members";
cin >> family_number;
/*allocate the number of string pointers that you need*/
string** familia = new string*[family_number];
cout << "Type the names\n";
get_names(familia, family_number);
cout << "The family members are: ";
print_string(familia, family_number);
cout << endl;
return 0;
}
void get_names(string** Family_input, int count) {
for(int i = 0 ; i < count; i++){
cout << "type " << i << " member\n";
/*create a string obj in the heap memory*/
string *input = new string ("");
// using that way you get only a single word
cin >> *input;
/*create a string object on the stack and put its pointer in the family_array*/
Family_input[i] = input;
}
}
void print_string(string** Value, int const nSize) {
for (int i = 0; i < nSize; i++) {
cout << *(Value[i]) << " ";
}
}

Using variables declared inside an if else construct later in the program results in an undeclared identifier error

This program is pretty self explanatory, so I won't really get into the purpose of what its for.
My main problem right now is on lines 82, 89, 95, and 101, I'm getting "Undeclared Identifier" errors for "arr" and "input" when i compile.
Is this because I declared them inside of an if else if construct, and if so, is there any way to get around this. Thanks for any help in advance!!!!
Here is the code
#include <iostream>
#include <string>
using namespace std;
template<class T> void selectionSort(T arr[], T num)
{
int pos_min;
T temp;
for (int i = 0; i < num - 1; i++)
{
pos_min = i;
for (int j = i + 1; j < num; j++)
{
for (arr[j] < arr[pos_min])
{
pos_min = j;
}
}
if (pos_min != i)
{
temp = arr[i];
arr[i] = arr[pos_min];
arr[pos_min] = temp;
}
}
}
int main()
{
char check = 'C';
while (toupper(check) != 'Q')
{
char dataType;
int num = 0;
cout << "What kind of data do you want to sort?" << endl;
cout << " For integer enter i, for string enter s, for character enter c. ";
cin >> dataType;
//User input dataType
if (toupper(dataType) == 'I')
{
int arr[100];
int input;
cout << " You've chosen Integer dataType" << endl;
}
else if (toupper(dataType) == 'S')
{
string arr[100];
string input;
cout << " You've chosen String dataType" << endl;
}
else if(toupper(dataType) == 'C')
{
char arr[100];
char input;
cout << " You've chosen Character dataType" << endl;
}
else
{
cout << "Not a recognizable dataType. Shuting down..." << endl;
return -1;
}
//User input # of num
cout << "How many num will be sorted? ";
cin >> num;
for (int i = 0; i < num; i++)
{
cout << "Enter an input of the dataType you selected: ";
cin >> input;
arr[i] = input;
}
//Display user input
cout << "The data as you entered it: ";
for (int i = 0; i < num; i++)
{
cout << arr[i];
cout << " ";
}
cout << endl;
//Sort user input by calling template functon selectionSort
selectionSort(arr, num);
//Display sorted user input
cout << "After sorting your data by calling selectionSort: ";
for (int i = 0; i < num; i++)
{
cout << arr[i];
cout << " ";
}
cout << endl;
//Query user to quit or continue
cout << " Would you like to continue? Enter 'Q'. Enter anything else to continue.";
cin >> check;
}
return 0;
}
It is because you declared them inside an if/else block. Once the block completes, these variable go out of scope and are no longer accessible.
One way around this would be to always read in the input as character data, then convert it into the specified type after the fact. See atoi for how to convert from char to int.
A variable can never have unknown type. Even inside a template, the type of every variable is fixed for any particular instantiation.
Which suggests a solution. All the code that works on a variable with multiple types can be placed into a template function.
You may find the template syntax for passing an arbitrary length array of arbitrary element type useful:
template<typename T, size_t N>
void func1( T (&arr)[N] )
{
//...
}
But you really don't even need to pass the array. Just pass a type, and use that type when creating the array inside the function.
template<typename T>
void process_it()
{
T arr[100];
T input;
// now work on them
}
Either way, you'll need to call this function from inside all the if/else branches, where the exact type is known.