Array- looping through secondary array - c++

Unable to get the index from the second array to match the first array
// array constants
const int people = 7;
const int phoneNumbers = 7;
int main() {
char person, family;
int index;
string found;
int size =7;
//array declaration and set values
string people [] ={"Darryl","Jasmine","Brian","Duane","Ayana","Mia","Maya"};
// const char phoneNumbers = 7;
string phoneNumbers[] = {"678-281-7649", "818-933-1158", "212-898-2022",
"361-345-3782","817-399-3750","313-589-0460","818-634-4660"};
//set boolean value
found = "False";
//initialize index
index = 0;
// search variable and user input
cout << "who are you looking for? " << endl;
cin >> people[index];
for (index=0; index<=6; index--) {
if (people[index] == people[index] )
cout << "phone num for " << people[index] << " is "<<
phoneNumbers[index] << endl;
}
return 0;
}
When I put in Jasmine which is the people[] array, the phoneNumbers[] array brings back the first index of phoneNumbers[] which it should bring back the second index on phoneNumbers[] array

There are two problems here.
You are replacing content of the people[0] with the cin - so first item of the array will be always user's input.
You are decrement index, so the FOR cycle goes to the indexes 0,-1,-2... This is problem as arrays in C and C++ goes from 0 to upper values.
I would prefer to add one variable:
string input;
then:
cin >> input;
for cycle should be used:
for (index = 0; index < 6; index++)
and in your condition I would use:
if (person[index] == input) ...

A much cleaner way of doing this would be too use std::map provided by the C++ standard template library. Below is my take on what you're trying to achieve:
// phoneNumber.cpp
#include <iostream>
#include <map>
int main()
{
// delcare a map variable that maps people's names to phone numbers
std::map <std::string,std::string> lookUpPhoneNumber = {
{"Darryl", "678-281-7649"},
{"Jasmine", "818-933-1158"},
{"Brian", "212-898-2022"},
{"Duane", "361-345-3782"},
{"Ayana", "817-399-3750"},
{"Mia", "313-589-0460"},
{"Maya", "818-634-4660"}
};
// take input name
std::string inputName;
// user prompt
std::cout << "who are you looking for?: ";
std::cin >> inputName;
// look up name in map
if(lookUpPhoneNumber.find(inputName) != lookUpPhoneNumber.end()){
std::cout << "Phone num for " << inputName << " is: " << lookUpPhoneNumber[inputName] << "\n";
} else{
std::cout << "Name does not exist!\n";
}
return 0;
}
To compile and run, use the following command:
g++ -std=c++11 -o phoneNumber phoneNumber.cpp
./phoneNumber
Or check your compiler option to enable compiling with c++11 standard or higher.

Related

save values from strigng array in 2d int array?

I have been taking a voluntary computer science course at school share for 1 month and want to practice something. Task:
I am to store a series of numbers with symbols in a string array for the first time. The numbers are to be stored in a two-dimensional int array. But the symbols should look different on output. And the output should be done only using the values of the int array. The numbers are one-digit. There is no need to check if the user makes the input correctly.
This is how the program should look like when it is executed:
Input:
.1.2.3.|.4.5.6.|.7.8.9
-------|-------|-------
Output:
;1;2;3;//;4;5;6;//;7;8;9
=======//=======//=======
I know that you always have to proceed in small steps. I have made it so far that the input is output exactly the same again. I just can't get the solution, I have been sitting here for hours. How do I save the numbers I have saved to the string array to the 2d array? And how do I replace the symbols to look like the example?
My code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int ArrayTwo[3][2] = {0}; //From Task
string ArrayInput[2] = {""}; //From Task
cout << "Input:" << endl;
for (int i = 0; i < 2; i++)
{
cin >> ArrayInput[i];
}
cout << "Output" << endl;
for (int i = 0; i < 2; i++)
{
cout << ArrayInput[i] << endl;
}
system("pause");
return 0;
}
Probably it's simplest to iterate to simply iterate through the input string and convert anything that's a digit to a number:
#include <cctype>
...
void PrintInner(int (&inner)[3])
{
std::cout << ';';
for (auto element : inner)
{
std::cout << element << ';';
}
}
...
int ArrayTwo[3][3];
string ArrayInput[2];
...
auto readPos = ArrayInput[0].cbegin();
for (auto& inner : ArrayTwo)
{
for(auto& element : inner)
{
// skip non-digit chars
while(!std::isdigit(*readPos))
{
++readPos;
}
element = *readPos - '0'; // char codes of digits 0123456789 are next to each other
++readPos;
}
}
cout << "Output" << endl;
PrintInner(ArrayTwo[0]);
for (int i = 1; i != 3; ++i)
{
std::cout << "//";
PrintInner(ArrayTwo[i]);
}
...
Demo on godbolt
In case you're unfamiliar with this: for ( ... : ...) is a ranged for-loop; this sets the loop variable to the elements of the array in increasing order of indices.

Having problem in working with insert, delete and search in an string array at the same time

I was trying to implement insert, delete and linear search in an string type array in the same code. Delete and Linear search works fine here, but insertion is not running perfectly.
Here is the main function of my code.
#include<iostream>
#include <stdlib.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
int main(int argc, char ** argv)
{
int siz;
cout<<"How many elements:";
cin>>siz;
string student[siz];
for(int i=0; i<siz; i++)
{
cin>>student[i];
}
cout<<"Array:";
for(int i=0; i<siz; i++)
cout<<student[i]<<endl;
int choice;
cout <<"Enter your choice :";
cin>>choice;
switch(choice)
{
case 0:
exit(0);
break;
case 1:
st_insert(student,siz);
break;
case 2:
st_delete(student,siz);
break;
case 3:
st_search(student,siz);
break;
case 4:
cout<<"All elements\n:";
for(int i=0; i<siz; i++)
cout<<student[i]<<endl;
break;
default:
cout<<"Wrong choice please try again !!!";
}
return 0;
}
The insert function is
void st_insert(string demo[], int siz)
{
int pos;
cout<<"Enter a position number to insert:";
cin>>pos;
string item;
cout<<"Enter a new Element :";
cin>>item;
cout<<"After Inserting "<<item<<", the updated list is: "<<endl;
for (int i=siz-1; i>=pos; i--)
{
demo[i+1] = demo[i];
}
demo[pos] = item;
for (int i=0; i<siz+1; i++)
cout<<"\t"<<demo[i]<<endl;
}
Sample Output if I want to insert an item
Yes, there is a solution. Don't use non-standard VLAs and don't use Plain-Old Arrays that provide no bounds checking. The solution is to use a vector of strings, e.g. std::vector<std::string>. That way you can add or replace any element you like and the memory is handled automatically.
For example, let's just take a vector of strings initialized with four strings:
std::vector<std::string> student { "my", "dog", "has", "fleas" };
Now student.size() will tell you how many strings are contained in the vector and you can replace (with bounds checking) with student.at(pos) = "new string";
You can list all elements in your vector using a range-based for loop, e.g.
std::cout << "Array:\n\n";
for (const auto& s : student)
std::cout << s << '\n';
Since the vector of strings student contains all the information you will need to either replace an existing element or add a new element at the end, your function (which must be of a type to indicate success/failure of the operation) could be written to take a single parameter -- a reference to your vector of strings, e.g.:
bool st_insert(std::vector<std::string>& demo)
{
size_t pos;
std::string item {};
std::cout << "Enter a position number to insert: ";
if (!(std::cin >> pos))
return false;
std::cout << "Enter a new Element: ";
if (!(std::cin >> item))
return false;
if (pos >= demo.size())
demo.push_back(item);
else
demo.at(pos) = item;
std::cout << "\nAfter Inserting \""<< item <<"\", the updated list is:\n\n";
for (const auto& s : demo)
std::cout << s << '\n';
return true;
}
If you want a compilable example, with 0-exit or 1-st_insert as your menu choices, you could do:
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
bool st_insert(std::vector<std::string>& demo)
{
size_t pos;
std::string item {};
std::cout << "Enter a position number to insert: ";
if (!(std::cin >> pos))
return false;
std::cout << "Enter a new Element: ";
if (!(std::cin >> item))
return false;
if (pos >= demo.size())
demo.push_back(item);
else
demo.at(pos) = item;
std::cout << "\nAfter Inserting \""<< item <<"\", the updated list is:\n\n";
for (const auto& s : demo)
std::cout << s << '\n';
return true;
}
int main (void)
{
int choice;
std::string tmp;
std::vector<std::string> student { "my", "dog", "has", "fleas" };
std::cout << "Array:\n\n";
for (const auto& s : student)
std::cout << s << '\n';
std:: cout << "\nEnter menu choice: ";
if (!(std::cin >> choice)) {
std::cerr << "error: invalid integer value - choice.\n";
return 1;
}
switch(choice)
{
case 0:
exit(0);
break;
case 1:
if (!st_insert (student))
std::cerr << "error: unable to insert element.\n";
break;
default:
std::cout << "Wrong choice please try again !!!\n";
}
return 0;
}
Example Use/Output
Replace Exmaple:
$ ./bin/insert_str_item
Array:
my
dog
has
fleas
Enter menu choice: 1
Enter a position number to insert: 1
Enter a new Element: cat
After Inserting "cat", the updated list is:
my
cat
has
fleas
Add Example:
$ ./bin/insert_str_item
Array:
my
dog
has
fleas
Enter menu choice: 1
Enter a position number to insert: 40
Enter a new Element: now
After Inserting "now", the updated list is:
my
dog
has
fleas
now
(note: the st_insert() function was written so if the requested pos for the new string exceeds what the next string in the vector would be, it is simply added as the next string and the invalid position is discarded)
Now when you go to take input for your vector of strings, it is quite simple. just read your input into a temporary string and use the .push_back() member function to add the string to your vector of strings, e.g.
std::string tmp {};
std::cout << "enter a string: ";
if (std::cin >> tmp)
student.push_back(tmp);
(note: you must validate every user input before you use the value)
Adding Taking siz New Elements
From your example, if you did want to specify the number of new strings to enter, you could adjust the program as follows:
int main (void)
{
int choice;
size_t siz;
std::string tmp;
std::vector<std::string> student { "my", "dog", "has", "fleas" };
std::cout << "There are currently " << student.size() << " elements:\n\n";
for (const auto& s : student)
std::cout << s << '\n';
std::cout << "\nHow many elements would you like to add? ";
if (!(std::cin >> siz)) {
std::cerr << "error: invalid size-type input.\n";
return 1;
}
for (size_t i = 0; i < siz; i++) {
std::cout << "student[" << student.size() << "]: ";
if (std::cin >> tmp)
student.push_back(tmp);
}
std::cout << "\nCurrent strings:\n\n";
for (const auto& s : student)
std::cout << s << '\n';
std:: cout << "\nEnter menu choice: ";
if (!(std::cin >> choice)) {
std::cerr << "error: invalid integer value - choice.\n";
return 1;
}
switch(choice)
{
case 0:
exit(0);
break;
case 1:
if (!st_insert (student))
std::cerr << "error: unable to insert element.\n";
break;
default:
std::cout << "Wrong choice please try again !!!\n";
}
return 0;
}
Example Use/Output
$ ./bin/insert_str_item
There are currently 4 elements:
my
dog
has
fleas
How many elements would you like to add? 4
student[4]: my
student[5]: cat
student[6]: has
student[7]: none
Current strings:
my
dog
has
fleas
my
cat
has
none
Enter menu choice: 1
Enter a position number to insert: 5
Enter a new Element: frog
After Inserting "frog", the updated list is:
my
dog
has
fleas
my
frog
has
none
You will want to see std::vector and std::basic::string for full details of the use of std::vector and std::string. Also see: Why is “using namespace std;” considered bad practice? and C++: “std::endl” vs “\n”.
Look things over and let me know if you have further questions.
As rightly said by some authors , what is required by you should not be done by fixed memory allocation , instead dynamic memory allocation (example : vectors in c++) should be used. However since you wanted to try the fixed one still, you can do the following :
Declare a string array of a larger size, instead of the user input (siz). Let's say it to be of predefined size 1000. (You can notify user to have a array of size to be less).
Declare the siz variable as global and not local. Because when you come after doing any insertion / deletion operation your size should be more / less than it previously was.But if you are using it as local then the changes would not be reflected because of call by value.
EDITED code:
#include<iostream>
#include <stdlib.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
int siz=0;
void st_insert(string demo[])
{
int pos;
cout<<"Enter a position number to insert:";
cin>>pos;
string item;
cout<<"Enter a new Element :";
cin>>item;
cout<<"After Inserting "<<item<<", the updated list is: "<<endl;
for (int i=siz-1; i>=pos; i--)
{
demo[i+1] = demo[i];
}
demo[pos] = item;
siz++;
for (int i=0; i<siz; i++)
cout<<"\t"<<demo[i]<<endl;
}
int main(int argc, char ** argv)
{
cout<<"How many elements:";
cin>>siz;
string student[1005];
for(int i=0; i<siz; i++)
{
cin>>student[i];
}
cout<<"Array:";
for(int i=0; i<siz; i++)
cout<<student[i]<<endl;
int choice;
cout <<"Enter your choice :";
cin>>choice;
switch(choice)
{
case 0:
exit(0);
break;
case 1:
st_insert(student);
break;
case 4:
cout<<"All elements\n:";
for(int i=0; i<siz; i++)
cout<<student[i]<<endl;
break;
default:
cout<<"Wrong choice please try again !!!";
}
return 0;
}
Rest all seems fine to me.
Hope you got it. :)
In C++, arrays have a fixed sized and when passed as parameters what you are actually getting is a pointer to the first element in the array. In you code, you are trying to access demo[i+1] when size equals size-1; this generates an error because you are trying to access a memory location that isn't part of the array (demo[size]). When inserting an element in an array, you need to first allocate a new chunk of memory with the new size, then you copy each element over(including the new value), and finally delete the old chunk of memory which is now unused.

Creating a vector of structs, expression: vector subscript out of range

I am very new to c++ and currently trying to complete a few little challenges to get up to speed with the simpler aspects.
I'm trying to create an array (found info to suggest vectors are the same and better) of structs to hold data about 10 people. Each person has an "index" (to identify person1, person2, person3, etc..), a "num" (to store the collected data) and a "rank" (a variable which I intend to use to sort the people using the data collected)
The code doesn't show any errors before compiling, however, when the first piece of data is entered I get the following message:
"Debug Assertion Failed!
Program: C:\WINDOWS\SYSTEM32\MSVCP140D.dll
File: d:\program files\microsoft visual studio\community\vc\tools\msvc\14.12.25827\include\vector
Line: 1795
Expression: vector subscript out of range"
I have tried searching through multiple threads but I can't seem to work out why this problem is occurring.
My code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct person
{
int index; /*person number*/
int num; /*number of pancakes eaten*/
int rank; /*rank used for sorting people*/
};
vector<person> people; /*create a vector (array) of "person"'s*/
void getData()
{
cout << "You will be asked to enter data from 10 different people" << endl;
cout << "\n" << "The question is; 'How many pancakes did they eat for breakfast?'" << endl;
cin.get();
for (int i = 1; i <= 10; i++)
{
system("CLS");
int j;
cout << "Person " << i << " : ";
cin >> j;
person temp;
people.push_back(temp);
people[i].index = i;
people[i].num = j;
people[i].rank = i;
}
}
int main()
{
getData(); /*collect data for the people*/
system("CLS");
cout << "Data Collected : " << endl;
system("pause");
}
Thanks in advance for anyone who can help.
The problem is in your indexing. The index starts at 0 and not 1. So what happens is when you push the first element, it is stored at people[0]. Then you try to access people[1], since i = 1. Hence the subscript is out of range error.
You need to modify the code to be:
....
for (int i = 0; i < 10; i++)
{
system("CLS");
int j;
cout << "Person " << i << " : ";
cin >> j;
person temp;
people.push_back(temp);
people[i].index = i;
people[i].num = j;
people[i].rank = i;
}
....

C++ Replacing a character in an array without the use of C-String Library Functions

I was given a set of questions, basically asking me to recreate the utility of certain library functions such as strlen() and strcpy() without using them.
However, one of the questions has gotten me stumped. It's a function that replaces a character in a string with anything you choose.
Example :
Str : marix xdyssey
target : x
replacement : o
Output : mario odyssey
This is what I have right now
#include <iostream>
using namespace std;
int replace(char *s2, char target, char replacementChar);
const int MAX_SIZE = 128;
int main()
{
char str2[MAX_SIZE], target, replacement;
int change;
cout << "Enter your string : " << endl;
cin.getline(str2, MAX_SIZE);
cout << "What's your target?" << endl;
cin >> target;
cout << "What do you want to replace it with?" << endl;
cin >> replacement;
replace(str2, target, replacement);
}
int replace(char *s2, char target, char replacementChar)
{
int change = 0;
for(int i=0; s2[i]!='\0'; i++)
{
if(s2[i] == target)
{
swap(s2[i], replacementChar);
change++;
}
}
cout << "There were " << change << " change(s)." << endl;
cout << s2;
return change;
}
And even though "change" returned 2, I was given the output of "mario xdyssey".
Any advice or hints as to how to proceed would be greatly appreciated.
Change
swap(s2[i], replacementChar);
to:
s2[i] = replacementChar;
swap() exchanges the values of the two variables, so after the first replacement, replacementChar contains the same thing as target, so nothing gets updated.

filling a char array with a string? c++

I need to fill this array via user prompt. I was thinking to read in the user entry to a string and then assign that string to the array but that doesn't seem to be the right way to approach this. Could someone help me out?
The error I'm receiving reads "array type array[100] is not assignable"
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string.h>
using namespace std;
int main()
{
string theString;
char array[100]; // ARRAY MAX SIZE
int length = sizeof(array)-1;
char * ptrHead = array;
char *ptrTail = array + length - 1;
//USER PROMPTS & ARRAY FILL
cout << "Please enter a string to be reverse: " << endl;
cin >> theString;
array= theString;
//WHILE LOOP SWAPPING CHARACTERS OF STRING
while (ptrHead < ptrTail)
{
char temp = *ptrHead;
*ptrHead = *ptrTail;
*ptrTail = temp;
ptrHead++;
ptrTail--;
}
cout << array << endl;
return 0;
}
arrays are not assignable. You should use strcpy here:
But for this you'll have to convert theString to C like string.
strcpy(array, theString.c_str() );
Then adjust your ptrTail pointer too , like following :
int length = theString.size();
char *ptrTail = array + length - 1;
See Here
cin >> array; should put the input directly into the array, which I'm guessing is what you want
Also, there's a problem in your string reversal logic. You are reversing the entire array, not just the part that has been filled, which will put the filled portion at the end of the array. Consider using a function like strlen() to find out how long the actual input is.
You can copy the string to the array with strcpy or input the data directly to the array with cin >> array, but the better solution would be just not to use a char array, just use the string in your algorithm. That is also a better solution because you can overflow a fixed size char array
cout << "Please enter a string to be reverse: " << endl;
cin >> theString;
for (unsigned int i = 0; i <= theString.size() / 2; ++i)
swap(theString[i], theString[theString.size() - 1 - i);
cout << theString<< endl;
Edit
The same using pointers:
std::cout << "Please enter a string to be reverse: " << std::endl;
std::cin >> theString;
char* i = &theString[0];
char* j = &theString[theString.size() - 1];
for (; i < j; ++i, --j)
std::swap(*i, *j);
std::cout << theString << std::endl;