Unable to print the reverse of a user-filled partial array - c++

For an assignment, we were to fill an array with user-defined characters that stops filling once the user enters a full stop ".". Part of the assignment is to print out the characters entered in the array in reverse, but what I have seems to just print nothing.
First time asking, so apologies if it's a silly question. Thanks in advance.
#include <iostream>
using namespace std;
//Function declarations
bool fillArray(char charArray[], int arraySize, int& numberUsed);
void outputInReverse(const char charArray[], int& numberUsed);
int main() {
const int arraySize = 100;
char charArray[arraySize] = { };
int numberUsed = 0;
//Function calls
cout << "\nFILLING ARRAY....\n";
fillArray(charArray, arraySize, numberUsed);
cout << "\nARRAY OUTPUT....\n";
outputInReverse(charArray, numberUsed);
}
//Function definitions
bool fillArray(char charArray[], int arraySize, int& numberUsed) {
char inputChar;
int index = 0;
const char sentinel = '.';
bool sentinelEntered = false;
bool arrayFull = false;
int count = 0;
//Take user input
for (int i = 0; i < arraySize; i++) {
if ((!sentinelEntered)) {
cout << "Enter up to " << arraySize << " character values. Enter full stop to end. " << "Enter char " << (i + 1) << ": " << endl;
cin >> inputChar;
charArray[index] = inputChar;
//How many entries made
numberUsed = i;
count++;
if ((inputChar == sentinel)) {
sentinelEntered = true;
cout << "Number of entries: " << (count - 1) << endl;
return count;
}
}
}
if (numberUsed == arraySize) {
arrayFull = true;
return arrayFull;
}
return sentinelEntered;
return count;
}
// Reverse
void outputInReverse(const char charArray[], int& numberUsed) {
for (int i = numberUsed; i > 0; i--) {
cout << "Output in reverse: " << charArray[i] << endl;
}
}
FILLING ARRAY....
Enter up to 100 character values. Enter full stop to end. Enter char 1:
a
Enter up to 100 character values. Enter full stop to end. Enter char 2:
b
Enter up to 100 character values. Enter full stop to end. Enter char 3:
c
Enter up to 100 character values. Enter full stop to end. Enter char 4:
d
Enter up to 100 character values. Enter full stop to end. Enter char 5:
e
Enter up to 100 character values. Enter full stop to end. Enter char 6:
.
Number of entries: 5
ARRAY OUTPUT....
Output in reverse:
Output in reverse:
Output in reverse:
Output in reverse:
Output in reverse:

Not sure what you are trying to return from fillArray(), but since its a bool type, assuming you are trying to return if the array is empty or not. Observe added comments to see corrections.
int main() {
const int arraySize = 100;
//corrected
char charArray[arraySize] = { NULL };
int numberUsed = 0;
//Function calls
cout << "\nFILLING ARRAY....\n";
fillArray(charArray, arraySize, numberUsed);
cout << "\nARRAY OUTPUT....\n";
outputInReverse(charArray, numberUsed);
return 0;
}
bool fillArray(char charArray[], int arraySize, int& numberUsed) {
char inputChar;
int index = 0;
const char sentinel = '.';
bool sentinelEntered = false;
bool arrayFull = false;
int count = 0;
//Take user input
for (int i = 0; i < arraySize; i++) {
if ((!sentinelEntered)) {
cout << "Enter up to " << arraySize << " character values. Enter full stop to
end. " << "Enter char " << (i + 1) << ": " << endl;
cin >> inputChar;
//corrected: shifted here so before '.' can enter into array we return
if ((inputChar == sentinel)) {
sentinelEntered = true;
cout << "Number of entries: " << (count) << endl;
//correction: update numberUsed before returning and no of
//elements = count
numberUsed = i;
return count;
}
//correction: array index should not be "index" but i
charArray[i] = inputChar;
//How many entries made
numberUsed = i;
count++;
}
}
if (numberUsed == arraySize)
return true;
return false;
}
void outputInReverse(const char charArray[], int& numberUsed) {
for (int i = numberUsed-1; i >= 0; i--) {
cout << "Output in reverse: " << charArray[i] << endl;
}
}

Related

c++: searching an array

I am writing a program that's supposed to search an array that is filled by user input and return different output depending on whether or not another integer given by the user is in that array. the output is the index of the element.
e.g., suppose my array is {1, 2, 3}. using search(), if I enter 2, it should tell me that 2 is in the array and that its index value is 1.
But for some reason, this function only works correctly if I enter the very first element. This means that if I search for 1 in the array above, it will tell me that the index value is 0 like it's supposed to, but it won't do that for other elements.
My code is below. What am I doing wrong here?
#include <iostream>
using namespace std;
const int DECLARED_SIZE = 20;
void fillArray(int a[], int size, int& numberUsed);
int search(const int a[], int numberUsed, int target);
int search2(const int a[], int numberUsed, int target);
int main() {
int size;
cout << "Enter the array size: ";
cin >> size;
int arr[size], listSize, target;
fillArray(arr, size, listSize);
char ans;
int result;
do {
cout << "Enter a number to search for: ";
cin >> target;
cout << endl << endl;
result = search(arr, size, target);
if (result == -1) {
cout << target << " is not on the list." << endl << endl;
cout << "Search again? (y/n): ";
cin >> ans;
cout << endl << endl;
}
else {
cout << target << " is stored in array position " << result << "." << endl << endl;
cout << "Search again? (y/n): ";
cin >> ans;
cout << endl << endl;
}
} while ((ans != 'n') && (ans != 'N'));
cout << "End of program." << endl;
return 0;
}
void fillArray(int a[], int size, int& numberUsed) {
cout << "Enter up to " << size << " non-negative whole numbers." << endl;
cout << "Mark the end of the list with a negative number." << endl;
int next, index = 0;
cin >> next;
while ((next >= 0) && (index < size)) {
a[index] = next;
index++;
cin >> next;
}
numberUsed = index;
}
//searches an array that is filled by the user
//this is where i think i am struggling
int search(const int a[], int numberUsed, int target) {
int index = 0;
bool found = false;
while ((!found) && (index < numberUsed)) {
if (target == a[index]) {
found = true;
}
else {
index++;
}
if (found) {
return index;
}
else {
return -1;
}
}
return 0;
}
If you look at your search function you will see that it always returns at the bottom of the while loop. That's why you only find the first number. What you should do is return if you find the number but carry on if you don't. Like this (with some other simplifications of your code)
int search(const int a[], int numberUsed, int target) {
for (int index = 0; index < numberUsed; index++) {
if (target == a[index]) {
return index;
}
}
return -1;
}
In your while loop in your search function, you're doing:
if (found) {
return index;
} else {
return -1;
}
Which means if you didn't find your input, it immediately returns -1 instead of trying the next index. You should only return when you've visited all other indexes.

Organizing names by last name with three of the same surnames (C++)?

I have an assignment to sort a list of names alphabetically by last name. However, there are three names with the same surname and I can't get the first names to alphabetize with the surnames. Have to code own bubble sort or other sorting algorithm. I chose bubblesort because it's one of the only ones we've learned so far. Any help is appreciated. Everything works except the correct assortment.
Here is my code:
// my name
// Program 6
// This program will show a list of names in a variety of orders.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const int size = 25;
void showContacts_FNLN(string fnameArray[], string lnameArray[], int size);
void showContacts_LNFN(string lnameArray[], string fnameArray[], int size);
void reverseContacts_FNLN(string fnameArray[], string lnameArray[], int size);
void reverseContacts_LNFN(string fnameArray[], string lnameArray[], int size);
void searchLasname(string lnameArray[], string fnameArray[], int size);
void searchFirname(string fnameArray[], string lnameArray[], int size);
void bubbleSort(string lnameArray[], string fnameArray[], int size);
int main(int argc, const char * argv[])
{
int count = 0;
int ans;
ifstream nameData;
string lnameArray[size];
string fnameArray[size];
string lname, fname;
nameData.open("names.txt");
while(nameData >> fname >> lname)
{
fnameArray[count] = fname;
lnameArray[count] = lname;
count ++;
}
bubbleSort(lnameArray, fnameArray, size);
while(ans != 9)
{
cout << "What would you like to do?" << endl;
cout << "1) display contacts by first name and last name" << endl;
cout << "2) display contacts by last name and first name" << endl;
cout << "3) display contacts by first name and last name in reverse order" << endl;
cout << "4) display contacts by last name and first name in reverse order" << endl;
cout << "5) search for contact by last name" << endl;
cout << "6) search for contact by first name" << endl;
cout << "9) exit" << endl;
cout << "Enter: ";
cin >> ans;
cout << endl;
switch(ans)
{
case 1: showContacts_FNLN(fnameArray, lnameArray, size); // shows contacts in FN-LN order
break;
case 2: showContacts_LNFN(lnameArray, fnameArray, size); // LN-FN order
break;
case 3: reverseContacts_FNLN(fnameArray, lnameArray, size); // reversed FN-LN order
break;
case 4: reverseContacts_LNFN (fnameArray, lnameArray, size); // reversed LN-FN order
break;
case 5: searchLasname(lnameArray, fnameArray, size); // searches based on LN
break;
case 6: searchFirname(fnameArray, lnameArray, size); // searches based on FN
break;
case 9: cout << "Goodbye!" << endl;
break;
}
}
nameData.close();
return 0;
}
void showContacts_FNLN(string fnameArray[], string lnameArray[], int size)
{
for(int i=0; i<size; i++)
{
cout << fnameArray[i] << " " << lnameArray[i] << endl;
}
cout << endl;
}
void showContacts_LNFN(string lnameArray[], string fnameArray[], int size)
{
for(int i=0; i<size; i++)
{
cout << lnameArray[i] << ", " << fnameArray[i] << endl;
}
cout << endl;
}
void reverseContacts_FNLN(string fnameArray[], string lnameArray[], int size)
{
for(int i=(size-1); i>=0; i--)
{
cout << fnameArray[i] << " " << lnameArray[i] << endl;
}
cout << endl;
}
void reverseContacts_LNFN(string fnameArray[], string lnameArray[], int size)
{
for(int i=(size-1); i>=0; i--)
{
cout << lnameArray[i] << ", " << fnameArray[i] << endl;
}
cout << endl;
}
void searchLasname(string lnameArray[], string fnameArray[], int size)
{
int c = 0;
string slnam;
cout << "Enter a last name: ";
cin >> slnam;
for(int i=0; i<size; i++)
{
if(slnam==lnameArray[i])
{
cout << lnameArray[i] << ", " << fnameArray[i] << endl;
c++;
}
}
if (c == 0)
{
cout << "There is no match.";
cout << endl;
}
cout << endl;
}
void searchFirname(string fnameArray[], string lnameArray[], int size)
{
int c = 0;
string sfnam;
cout << "Enter a first name: ";
cin >> sfnam;
for(int i=0; i<size; i++)
{
if(sfnam==fnameArray[i])
{
cout << fnameArray[i] << " " << lnameArray[i] << endl;
c++;
}
}
if (c==0)
{
cout << "There is no match." << endl;
}
cout << endl;
}
void bubbleSort(string lnameArray[], string fnameArray[], int size)
{
string tmp, tmp2;
//int count=0;
for( int i = 1; i <= size - 1; i++ )
{
for( int j = 0; j < size - i; j++ )
{
//count++;
if( lnameArray[j] > lnameArray[j+1] )
{
tmp = lnameArray[j];
lnameArray[j] = lnameArray[j+1];
lnameArray[j+1] = tmp;
}
if(lnameArray[j] == lnameArray[j+1])
{
if(fnameArray[j] > fnameArray[j+1])
{
tmp = lnameArray[j];
lnameArray[j] = lnameArray[j+1];
lnameArray[j+1] = tmp;
tmp2 = fnameArray[j];
fnameArray[j] = fnameArray[j+1];
fnameArray[j+1] = tmp2;
}
}
}
}
//cout << "count = " << count << endl;
}
Here you go:
void bubbleSort(string lnameArray[], string fnameArray[], int size)
{
for( int i = 0; i < size - 1; i++ )
{
for( int j = 0; j < size - i - 1; j++ )
{
string name1 = lnameArray[j] + fnameArray[j];
string name2 = lnameArray[j + 1] + fnameArray[j + 1];
if(name1.compare(name2) > 0)
{
string tmp = lnameArray[j];
lnameArray[j] = lnameArray[j + 1];
lnameArray[j + 1] = tmp;
tmp = fnameArray[j];
fnameArray[j] = fnameArray[j + 1];
fnameArray[j + 1] = tmp;
}
}
}
}
Instead of having another 'if' for those that have similar last names, I combined the last name and the first name instead then used it for comparison.
I also noticed in your code in for( int j = 0; j < size - i; j++ ) that you forgot to add - 1 after size - i. Once j == size - i - 1 (assuming that i == 0 currently) then you use j + 1 to access an index, this will cause a segmentation fault since you're accessing an index beyond its range.
Your sort doesn't work because you change the position of the last names only (except for the case where two last names are equal.)
You should use a struct to store this information together in one array. Then you can simplify your code a lot:
struct Person {
Person() = default;
Person(string firstname, string lastname) : firstname(std::move(firstname)), lastname(std::move(lastname)) {}
string firstname;
string lastname;
};
void showContacts_FNLN(Person personArray[], int size) {
for (int i = 0; i < size; i++) {
cout << personArray[i].firstname << " " << personArray[i].lastname << endl;
}
cout << endl;
}
void bubbleSort(Person personArray[], int size) {
for (int i = 1; i <= size - 1; i++) {
// The condition must size - i - 1 because otherwise personArray[j+1] is faulty
for (int j = 0; j < size - i - 1; j++) {
if (personArray[j].lastname > personArray[j+1].lastname
|| (personArray[j].lastname == personArray[j+1].lastname &&
personArray[j].firstname > personArray[j+1].firstname)) {
auto tmp = std::move(personArray[j]);
personArray[j] = std::move(personArray[j+1]);
personArray[j+1] = std::move(tmp);
}
}
}
}
int main(int argc, const char * argv[]) {
int count = 0;
ifstream nameData;
Person personArray[size];
string lname, fname;
nameData.open("names.txt");
while(nameData >> fname >> lname) {
personArray[count] = Person(fname, lname);
count++;
}
nameData.close();
bubbleSort(personArray, size);
showContacts_FNLN(personArray, size);
return 0;
}
I removed some non-essential parts from this example to keep it very short but you should get the idea. (Note that my code makes use of C++11 move semantics, if this confuses you, just remove them.)
Some more suggestions:
Do not use using namespace std;. (The internet will tell you why.)
If you can, use std::array, which eliminates the need to always pass the size of the arrays and allows you to use a C++11 range for loop.

Array search and unique value addition

(Sorry if this is formatted terribly. I've never posted before.)
I've been working on a program for class for a few hours and I can't figure out what I need to do to my function to get it to do what I want. The end result should be that addUnique will add unique inputs to a list of its own.
#include <iostream>
using namespace std;
void addUnique(int a[], int u[], int count, int &uCount);
void printInitial(int a[], int count);
void printUnique(int u[], int uCount);
int main() {
//initial input
int a[25];
//unique input
int u[25];
//initial count
int count = 0;
//unique count
int uCount = 0;
//user input
int input;
cout << "Number Reader" << endl;
cout << "Reads back the numbers you enter and tells you the unique entries" << endl;
cout << "Enter 25 positive numbers. Enter '-1' to stop." << endl;
cout << "-------------" << endl;
do {
cout << "Please enter a positive number: ";
cin >> input;
if (input != -1) {
a[count++] = input;
addUnique(a, u, count, uCount);
}
} while (input != -1 && count < 25);
printInitial(a, count);
printUnique(u, uCount);
cout << "You entered " << count << " numbers, " << uCount << " unique." << endl;
cout << "Have a nice day!" << endl;
}
void addUnique(int a[], int u[], int count, int &uCount) {
int index = 0;
for (int i = 0; i < count; i++) {
while (index < count) {
if (u[uCount] != a[i]) {
u[uCount++] = a[i];
}
index++;
}
}
}
void printInitial(int a[], int count) {
int lastNumber = a[count - 1];
cout << "The numbers you entered are: ";
for (int i = 0; i < count - 1; i++) {
cout << a[i] << ", ";
}
cout << lastNumber << "." << endl;
}
void printUnique(int u[], int uCount) {
int lastNumber = u[uCount - 1];
cout << "The unique numbers are: ";
for (int i = 0; i < uCount - 1; i++) {
cout << u[i] << ", ";
}
cout << lastNumber << "." << endl;
}
The problem is my addUnique function. I've written it before as a for loop that looks like this:
for (int i = 0; i < count; i++){
if (u[i] != a[i]{
u[i] = a[i]
uCount++;
}
}
I get why this doesn't work: u is an empty array so comparing a and u at the same spot will always result in the addition of the value at i to u. What I need, is for this function to scan all of a before deciding whether or no it is a unique value that should be added to u.
If someone could point me in the right direction, it would be much appreciated.
Your check for uniqueness is wrong... As is your defintion of addUnique.
void addUnique(int value, int u[], int &uCount)
{
for (int i = 0; i < uCount; i++){
if (u[i] == value)
return; // already there, nothing to do.
}
u[uCount++] = value;
}

Getting errors in my char array function?

#include <iostream>
using namespace std;
const int SIZE = 20;
char correctAnswers(char [], int);
char userAnswers(char [], int);
void compareArray(char[] , char [], int [], int, int &);
int main(){
char correct[SIZE];
char userArray[SIZE];
int result[SIZE];
int element;
correctAnswers(correct, SIZE);
cout << "Please enter the student's answers for each of the questions." << endl;
cout << "Press Enter after typing each answer." << endl;
cout << "Please enter only an A, B, C, or D for each question." << endl;
userAnswers(userArray, SIZE);
compareArray(correct, userArray, result, element);
cout << "Array 1 and Array 2 are different at" << element<<" positions: " << " ";
for(int i = 0; i < element; i++)
cout << result[i] << " ";
return 0;
}
char correctAnswers(char correct[], int SIZE){
correct[SIZE] = {'B','D','A','A','A','B','B','A','C','D','B','B','D','A','D','D','A','B','D','A'};
}
char userAnswers(char userArray[], int SIZE){
userArray[SIZE];
for(int i = 0; i < 20; i++){
cout << "Question " << (i+1) << ":";
cin >> userArray[i];
while(userArray[i] != 'A' || userArray[i] != 'B' || userArray[i] != 'C' || userArray[i] != 'D'){
cout << "Invalid input. Choose A,B,C or D." << endl;
cin >> userArray[i];
}
}
}
void compareArray(char correct[], char userArray[], int result[], int &element){
int right = 0, wrong = 0;
element = 0;
for(int i = 0; i < SIZE; i++){
if(userArray[i] == correct[i]){
right = right + 1;
}
else
wrong = wrong + 1;
}
if(right >= 15){
cout << "You Passed!";
}
else
cout << "You Fail.";
cout << "Correct answers = " << right << endl;
cout << "Incorrect answers = " << wrong << endl;
for(int i = 0; i < SIZE; i++){
if(userArray[i] != correct[i]){
result[element] = i+1;
element++;
}
}
}
I'm getting 3 errors and can't figure out why. In my char correctAnswers function, I get an error saying "cannot convert from 'braced-init-list' to 'char" and that the initializer contains too many elements. Also, in my last function it tells me function does not take four elements?
correct in correctAnswer is an array of char, so correct[SIZE] is a particular element of that array (although located past the end of the array), which you are trying to assign an array of characters to.
Even if you removed [SIZE], you'd still have a problem, because you are trying to use an initializer (which, as the same suggests, is for initializing) to make an assignment.
Don't understand what you mean about the last function at all.

c++ arrays and functions and counters

My code is done and working. But i cant figure out how to count the number of attempts made by the user and invalid account numbers that were entered. I am supposed to do this in main starting after cin >> accountNum. After the user enters 9999 to quit, it is supposed to display the number of attempts made and the number of invalid charge account numbers that were entered. When i run it i get 0 for number of attempts and -1 for invalid numbers entered.
#include <iomanip>
#include <iostream>
#include <fstream>
using namespace std;
void getAccountNumbers(int[], int);
void displayAccountNumbers(int[], int);
void selectionSort(int[], int);
int binarySearch(const int[], int, int);
int main()
{
int accountNum;
int results;
int attempts = 0;
int invalidNumbers = 0;
const int ARRAY_SIZE = 18; // Array size
int numbers[ARRAY_SIZE]; // Array with 18 elements
int count = 0;
//ifstream inputFile;
getAccountNumbers(numbers, ARRAY_SIZE);
cout << "Original Order" << endl;
displayAccountNumbers(numbers, ARRAY_SIZE);
selectionSort(numbers, ARRAY_SIZE);
cout << "Sorted List" << endl;
displayAccountNumbers(numbers, ARRAY_SIZE);
cout << "********************" << endl;
cout << "Enter an Account number or 9999 to quit" << endl;
cin >> accountNum;
if(accountNum == 9999)
{
cout << "Thank You!" << endl;
}
while(accountNum != 9999)
{
results = binarySearch(numbers, ARRAY_SIZE, accountNum);
if(results == -1)
{
cout << "That number was not found" << endl;
invalidNumbers = results++;
}
else
{
cout << "That number is valid " << endl;
}
attempts = results++;
cin >> accountNum;
}
cout << "Number of attempts: " << attempts << endl;
cout << "Invalid numbers entered: " << invalidNumbers << endl;
system("pause");
return 0;
}
void getAccountNumbers(int nums[], int size)
{
ifstream inputFile;
int count = 0;
//Open the file
inputFile.open("charges.txt");
while(count < size && inputFile >> nums[count])
count ++;
//Close the file
inputFile.close();
}
void displayAccountNumbers(int nums[], int size)
{
for(int count = 0; count < size; count++)
cout << nums[count] << "\t";
cout << endl << endl;
}
void selectionSort(int nums[], int size)
{
int startScan, minIndex, minValue;
for(startScan = 0; startScan < (size - 1); startScan++)
{
minIndex = startScan;
minValue = nums[startScan];
for(int index = startScan + 1; index < size; index++)
{
if(nums[index] < minValue)
{
minValue = nums[index];
minIndex = index;
}
}
nums[minIndex] = nums[startScan];
nums[startScan] = minValue;
}
}
int binarySearch(const int nums[], int size, int value)
{
int first = 0, //First element
last = size - 1, // Last element
middle, // Midpoint
position = -1; //Position of search value
bool found = false;
while(!found && first <= last)
{
middle = (first + last) / 2; //Midpoint
if(nums[middle] == value)
{
found = true;
position = middle;
}
else if(nums[middle] > value) // Value is in lower half
last = middle - 1;
else
first = middle + 1; // Value is in upper half
}
return position;
}
Your problem is in the lines where you are trying to add to invalidNumbers and attempts. The ++ postfix operator adds one to the number before it. You needn't say invalidNumbers = results++;; you merely need invalidNumbers++;, and the same applies for attempts. What your code was doing was setting invalidNumbers (and attempts) to the value of results and then adding one to results instead.