Adding commas to numbers in an array C++ - c++

I am trying to add commas to a set of numbers in an array.
I have a program that will take in random numbers the length of which are determined by the user's input. These numbers are stored in a pointer array. I made another array to store the converted numbers from int to string. Now I am working on a function to add commas to them. I am having an issue with this function. infoArrayString is the converted numbers of user input from int to string. The issue is in the addCommas function
#include <iostream>
#include <string>
using namespace std;
void validNumber(int & x){
while (cin.fail()){
cout << "ERROR: must be a number, try again ->";
cin.clear();
cin.ignore(1000, '\n');
cin >> x;
}
}
void validNumberPointer(int *& x){
while (cin.fail()){
cout << "ERROR: must be a number, try again ->";
cin.clear();
cin.ignore(1000, '\n');
cin >> *x;
cout << endl;
}
}
void amount(int & userAmount, const int & MIN_INPUT, const int & MAX_INPUT)
{
/*
* Asks how many number they want
*/
cout << "How many numbers? -> ";
cin >> userAmount;
cout << endl;
/*
* check
*/
validNumber(userAmount);
while ((userAmount < MIN_INPUT) or (userAmount > MAX_INPUT)){
cout << "ERROR: number out of range" << endl;
cout << "Please enter numbers in range of " << MIN_INPUT << " to " << MAX_INPUT << " ->";
cin >> userAmount;
}
}
void getInfo(int *& infoArray, int & userAmount){
for(int i = 0; i < userAmount; i++){
cout << "Input number #" << i+1 << " ->";
cin >> *(infoArray+i);
cout << endl;
/*
* check
*/
validNumberPointer(infoArray);
while (*(infoArray+i) < 0){
cout << "ERROR: number out of range" << endl;
cout << "Please enter numbers in range of range -> ";
cin >> *(infoArray+i);
cout << endl;
}
}
}
void convertString(int *& infoArray, string *& infoArrayString, int & userAmount){
for(int i = 0; i < userAmount; i++){
*(infoArrayString +i) = to_string(*(infoArray+i));
}
}
void addCommas(string *& infoArrayString){
for(int i = 0; i < infoArrayString[i].length(); i++){
if(i%3 == 0 and i != 0){
infoArrayString[i] = infoArrayString[i] + ",";
}
}
}
void displayBoard(string *& infoArrayString, int & userAmount){
cout << "The sum of: " << endl;
for(int i = 0; i < userAmount; i++){
cout << *(infoArrayString++) << endl;
}
}
int main() {
const int MIN_INPUT = 2, MAX_INPUT = 11;
int userAmount = MIN_INPUT;
int * infoArray = NULL;
infoArray = new int [MAX_INPUT];
string * infoArrayString = NULL;
infoArrayString = new string [MAX_INPUT];
amount(userAmount, MIN_INPUT, MAX_INPUT);
getInfo(infoArray, userAmount);
convertString(infoArray,infoArrayString,userAmount);
addCommas(infoArrayString);
displayBoard(infoArrayString, userAmount);
}

If there is not specific reason you are using a raw array in C++ you may want to use a std::vector. They are easier to manipulate.
void int_to_string(std::vector<int>& integer_list,
std::vector<std::string>& string_list) {
// You can read integers/strings (with streams) into a
// container directly this function is for demo purposes.
for (auto& element : integer_list)
string_list.push_back(std::to_string(element));
}
You can then pass that vector of strings to a function that modifies each entry to have a comma.
void add_commas_to_strings(std::vector<std::string>& S) {
for (auto& element : S)
element += ',';
}
You may just want the commas for formatting. In that case you don't have to mutate the values of the vector.
If a csv style format is what you are after then you may be after something like this:
// Formats csv file style output.
void format_with_commas(std::vector<std::string>& string_list) {
int line_break = 0;
for (int i = 0; i < string_list.size(); ++i) {
if (line_break == 3) {
std::cout << "\n";
line_break = 0;
}
int is_end = line_break + 1;
if (is_end == 3) {
std::cout << string_list[i];
++line_break;
} else {
std::cout << string_list[i] << ", ";
++line_break;
}
}
}
Now if you really want the user to specify the length of a list perhaps try calling something like:
std::vector<int> user_defined_vector(std::vector<int>::size_type sz) {
return std::vector<int>(sz, 0);
}
The above can be ran like so:
#include <iostream>
#include <vector>
int main() {
std::vector<int> A{1, 2, 3, 4, 5, 6, 7, 8, 9};
std::vector<std::string> B;
int_to_string(A, B);
format_with_commas(B);
auto ten_element_vector_of_ints = user_defined_vector(10);
return 0;
}

Related

How to fix 'struct does not refer to a value'

in my project there are 2 structures, one of which relates to a binary tree, the second to students data
in ' int main ' I can’t access the add function GETDATA
' 'ZKR' does not refer to a value . ' (xcode)
I also can’t create a counter of the number of vertices of my tree
#include <iostream>
#include <ctime>
#include <cstring>
using namespace std;
struct ZKR {
char FACULTY[30];
int ACADEMIC_DEGREE;
char FIO[30];
};
struct point
{
char *data;
point *left;
point *right;
};
point* tree(int n, point* p)
{
point *r;
int nl, nr;
if (n == 0) { p = NULL; return p; }
nl = n / 2;
nr = n - nl - 1;
r = new point;
char s[50];
cout << "Значение: ";
cin >> s;
r->data = new char[strlen(s) + 1];
strcpy(r->data,s);
r->left = tree(nl, r->left);
r->right = tree(nr, r->right);
p = r;
return p;
}
void GETDATA(ZKR*M, int N)
{
cin.ignore();
for (int i = 0; i < N; i++)
{
cout << "\n";
cout << "FACULTY: ";
cin.getline(M[i].FACULTY, 30);
cout << "\n";
cout << "FIO: ";
cin.getline(M[i].FIO, 30);
cout << "\n";
cout << "ACADEMIC DEGREE: ";
cin >> M[i].ACADEMIC_DEGREE;
cin.ignore();
}
}
void treeprint(point *p, int &count) {
if (p != NULL) {
treeprint(p->left, count);
cout << p->data << " ";
treeprint(p->right, count);
if ((p->left == NULL) && (p->right == NULL))
count = count + 1;
}
}
int main()
{
setlocale(LC_ALL, "russian");
srand(time(NULL));
int n = 0, k = 0, count = 0;
point *beg = nullptr;
cout << "Enter the number of students" << endl;
int N;
cin >> N;
ZKR*M = new ZKR[N];
do
{
cout << "1. BUILD a binary tree\n";
cout << "2. SHOW a binary tree\n";
cout << "3. GETDATA\n";
cin >> k;
switch (k)
{
case 1:
cout << "Введите количество элементов" << endl;
cin >> n;
beg = tree(n, beg);
cout << endl;
break;
case 2:
treeprint(beg, count);
cout << endl;
cout << "Листьев в дереве: " << count << endl;
break;
case 3:
GETDATA(ZKR*M, N);
break;
}
} while (k != 4);
system("pause");
return 0;
}
I will be grateful for any help
This line is not syntactically correct:
GETDATA(ZKR*M, N);
Replace it with:
GETDATA(M, N);
M is a pointer to an object of type ZKR.

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

Need help on getting the smallest three numbers on an array

For this program a user must enter 10 contestants and the amount of second it took for them to complete a swimming race. My problem is that I must output the 1st, 2nd and 3rd placers, so I need to get the three smallest arrays (as they would be the quickest times) but I'm unsure on how to do it. Here is my code so far.
string names[10] = {};
int times[10] = { 0 };
int num[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int min1 = 0, min2 = 0, min3 = 0;
cout << "\n\n\tCrawl";
for (int i = 0; i < 10; i++)
{
cout << "\n\n\tPlease enter the name of contestant number " << num[i] << ": ";
cin >> names[i];
cout << "\n\tPlease enter the time it took for them to complete the Crawl style: ";
cin >> times[i];
while (!cin)
{
cout << "\n\tError! Please enter a valid time: ";
cin.clear();
cin.ignore();
cin >> times[i];
}
if (times[i] < times[min1])
min1 = i;
cout << "\n\n\t----------------------------------------------------------------------";
}
system("cls");
cout << "\n\n\tThe top three winners of the Crawl style race are as follows";
cout << "\n\n\t1st Place - " << names[min1];
cout << "\n\n\t2nd Place - " << names[min2];
cout << "\n\n\t3rd Place - " << names[min3];
}
_getch();
return 0;
}
As you can see, it is incomplete. I know how to get the smallest number, but its the second and third smallest that is giving me trouble.
your code is full of errors:
what do you do with min2 and min3 as long as you don't assign them?? they are always 0
try checking: cout << min2 << " " << min3;
also you don't initialize an array of strings like that.
why you use an array of integers for just printing number of input:
num? instead you can use i inside loop adding to it 1 each time
to solve your problem use a good way so consider using structs/clusses:
struct Athlete
{
std::string name;
int time;
};
int main()
{
Athlete theAthletes[10];
for(int i(0); i < 10; i++)
{
std::cout << "name: ";
std::getline(std::cin, theAthletes[i].name);
std::cin.sync(); // flushing the input buffer
std::cout << "time: ";
std::cin >> theAthletes[i].time;
std::cin.sync(); // flushing the input buffer
}
// sorting athletes by smaller time
for(i = 0; i < 10; i++)
for(int j(i + 1); j < 10; j++)
if(theAthletes[i].time > theAthletes[j].time)
{
Athlete tmp = theAthletes[i];
theAthletes[i] = theAthletes[j];
theAthletes[j] = tmp;
}
// printing the first three athletes
std::cout << "the first three athelets:\n\n";
std::cout << theAthletes[0].name << " : " << theAthletes[0].time << std::endl;
std::cout << theAthletes[1].name << " : " << theAthletes[1].time << std::endl;
std::cout << theAthletes[2].name << " : " << theAthletes[2].time << std::endl;
return 0;
}
I hope this will give u the expected output. But i suggest u to use some sorting alogirthms like bubble sort,quick sort etc.
#include <iostream>
#include<string>
using namespace std;
int main() {
int times[10] = { 0 };
int num[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int min1 = 0, min2 = 0, min3 = 0,m;
string names[10] ;
cout << "\n\n\tCrawl";
for (int i = 0; i < 10; i++)
{
cout << "\n\n\tPlease enter the name of contestant number " << num[i] << ": ";
cin >> names[i];
cout << names[i];
cout << "\n\tPlease enter the time it took for them to complete the Crawl style: ";
cin >> times[i];
cout<<times[i];
while (!cin)
{
cout << "\n\tError! Please enter a valid time: ";
cin.clear();
cin.ignore();
cin >> times[i];
}
if(times[i]==times[min1]){
if(times[min1]==times[min2]){
min3=i;
}else{min2 =i;}
}else if(times[i]==times[min2]){
min3=i;
}
if (times[i] < times[min1]){
min1 = i;
cout <<i;
}
int j=0;
while(j<i){
if((times[j]>times[min1])&&(times[j]<times[min2])){
min2 =j;
j++;
}
j++;
}
m=0;
while(m<i){
if((times[m]>times[min2])&&(times[m]<times[min3])){
min3 =m;
m++;
}
m++;
}
cout << "\n\n\t----------------------------------------------------------------------";
}
cout << "\n\n\tThe top three winners of the Crawl style race are as follows";
cout << "\n\n\t1st Place - " << names[min1];
cout << "\n\n\t2nd Place - " << names[min2];
cout << "\n\n\t3rd Place - " << names[min3];
return 0;
}
There is actually an algorithm in the standard library that does exactly what you need: std::partial_sort. Like others have pointed out before, to use it you need to put all the participant data into a single struct, though.
So start by defining a struct that contains all relevant data. Since it seems to me that you only use the number of the contestants in order to be able to later find the name to the swimmer with the fastest time, I'd get rid of it. Of course you could also add it back in if you like.
struct Swimmer {
int time;
std::string name;
};
Since you know that there always will be exactly 10 participants in a race, you can also go ahead and replace the C-style array by a std::array.
The code to read in the users then could look like this:
std::array<Swimmer, 10> participants;
for (auto& participant : participants) {
std::cout << "\n\n\tPlease enter the name of the next contestant: ";
std::cin >> participant.name;
std::cout << "\n\tPlease enter the time it took for them to complete the Crawl style: ";
while(true) {
if (std::cin >> participant.time) {
break;
}
std::cout << "\n\tError! Please enter a valid time: ";
std::cin.clear();
std::cin.ignore();
}
std::cout << "\n\n\t----------------------------------------------------------------------";
}
Partial sorting is now essentially a one-liner:
std::partial_sort(std::begin(participants),
std::begin(participants) + 3,
std::end(participants),
[] (auto const& p1, auto const& p2) { return p1.time < p2.time; });
Finally you can simply output the names of the first three participants in the array:
std::cout << "\n\n\tThe top three winners of the Crawl style race are as follows";
std::cout << "\n\n\t1st Place - " << participants[0].name;
std::cout << "\n\n\t2nd Place - " << participants[1].name;
std::cout << "\n\n\t3rd Place - " << participants[2].name << std::endl;
The full working code can be found on coliru.
This is not a full solution to your problem, but just meant to point you into the right direction...
#include <iostream>
#include <limits>
#include <algorithm>
using namespace std;
template <int N>
struct RememberNsmallest {
int a[N];
RememberNsmallest() { std::fill_n(a,N,std::numeric_limits<int>::max()); }
void operator()(int x){
int smallerThan = -1;
for (int i=0;i<N;i++){
if (x < a[i]) { smallerThan = i; break;}
}
if (smallerThan == -1) return;
for (int i=N-1;i>smallerThan;i--){ a[i] = a[i-1]; }
a[smallerThan] = x;
}
};
int main() {
int a[] = { 3, 5, 123, 0 ,-123, 1000};
RememberNsmallest<3> rns;
rns = std::for_each(a,a+6,rns);
std::cout << rns.a[0] << " " << rns.a[1] << " " << rns.a[2] << std::endl;
// your code goes here
return 0;
}
This will print
-123 0 3
As you need to know also the names for the best times, you should use a
struct TimeAndName {
int time;
std::string name;
}
And change the above functor to take a TimeAndName instead of the int and make it also remember the names... or come up with a different solution ;), but in any case you should use a struct similar to TimeAndName.
As your array is rather small, you could even consider to use a std::vector<TimeAndName> and sort it via std::sort by using your custom TimeAndName::operator<.

How to pass a pointer to an array from main to a function?

Basically, I'm trying to set the size of my array according to an input (numArraySize will be asked for from the user). I created an array pointer in main and want to pass this pointer to the functions.
#include <iostream>
using namespace std;
// Algorithm for Insertion Sort
int numArraySize;
void inputNums(int numArray[])
{
cout << "Enter a bunch of numbers: " ;
for(int x=0; x<numArraySize; x++)
{
cin >> numArray[x];
}
}
void outputNums(int numArray[])
{
for(int x=0; x<numArraySize; x++)
{
cout << numArray[x];
if(x != numArraySize-1)
{
cout << " - ";
}
}
}
void insertionSort(int numArray[])
{
int num;
int i;
for(int j=1; j<numArraySize; j++)
{
num = numArray[j];
i = j-1;
while(i>=0 && numArray[i] > num)
{
numArray[i+1] = numArray[i];
i--;
}
numArray[i+1] = num;
}
}
int main()
{
int *numbers = new int[numArraySize];
int choice;
cout << "1) Insertion Sort" << endl;
cout << "Enter your choice: " << endl;
cin >> choice; // Input choice for which algorithm to use
if(choice == 1)
{
cout << "Enter size of the array: ";
cin >> numArraySize;
inputNums(numbers); // Insert numbers
insertionSort(numbers); // Use algorithm to sort then output
outputNums(numbers);
}
cout << endl;
return 0;
}
EDIT:
Ok i fixed the error. I changed:
"int numArraySize=1;"
and the position of
"int *numbers = new int[numArraySize];"
The problem was that i had to initialize the numArraySize anyways. That causes error apparently. And the second problem was i have to input numArraySize before i initialize
"int *numbers" in the main function.
#include <iostream>
using namespace std;
// Algorithm for Insertion Sort
int numArraySize=1;
void inputNums(int numArray[])
{
cout << "Enter a bunch of numbers: " ;
for(int x=0; x<numArraySize; x++)
{
cin >> numArray[x];
}
}
void outputNums(int numArray[])
{
for(int x=0; x<numArraySize; x++)
{
cout << numArray[x];
if(x != numArraySize-1)
{
cout << " - ";
}
}
}
void insertionSort(int numArray[])
{
int num;
int i;
for(int j=1; j<numArraySize; j++)
{
num = numArray[j];
i = j-1;
while(i>=0 && numArray[i] > num)
{
numArray[i+1] = numArray[i];
i--;
}
numArray[i+1] = num;
}
}
int main()
{
int choice;
cout << "1) Insertion Sort" << endl;
cout << "Enter your choice: " << endl;
cin >> choice; // Input choice for which algorithm to use
if(choice == 1)
{
cout << "Enter size of the array: ";
cin >> numArraySize;
int *numbers = new int[numArraySize];
inputNums(numbers); // Insert numbers
insertionSort(numbers); // Use algorithm to sort then output
outputNums(numbers);
}
cout << endl;
system("pause");
return 0;
}
Thanks for your helps :)
To pass an array to a function, you can simply use int *array:
void outputNums(int *numArray)
{
for(int x=0; x<numArraySize; x++)
{
cout << numArray[x];
if(x != numArraySize-1)
{
cout << " - ";
}
}
}
Please note that it would be better to use a standard container like a vector.
When you are allocating the memory for the array in line
int *numbers = new int[numArraySize]
, you still haven't received the desired size for the array in variable numArraySize.

Logic error, number passed by reference significantly higher

Below I have pasted some code I wrote. The problem I am having is when turnmessage passes a number to found() (by reference) it is somehow increased drematically. For example if 3 is passed in I receive 3 million.
(the following is in the file projectmain.cpp)
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include "project1.h"
using namespace std;
project1 game;
string str(int number){
stringstream ss;
ss << number;
string result = ss.str();
return result;
}
void project1::setNames(){
string name;
cout<< "Player one, enter your name: ";
cin >> name;
playerOneName = name;
cout<< "Player two, enter your name: ";
cin >> name;
}
void project1::resetBoard(){
for(int i = 0; i < 3; i++){
RowOne[i] = str(i + 1);
RowTwo[i] = str(i + 4);
RowThree[i] = str(i + 7);
}
int used[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1};
turn = 1;
}
void project1::printBoard(){
for(int i = 0; i < 3; i++){
cout << " | " << RowOne[i] << " | ";
}
cout << endl;
for(int i = 0; i < 3; i++){
cout << " | " << RowTwo[i] << " | ";
}
cout << endl;
for(int i = 0; i < 3; i++){
cout << " | " << RowThree[i] << " | ";
}
cout << endl;
}
string project1::PlayerOneName(){
return playerOneName;
}
string project1::PlayerTwoName(){
return playerTwoName;
}
bool project1::found(int& number){
cout << " your number after pass: " << number;
int i = 0;
bool found = false;
while(i < 9 && found == false){
cout << used[i];
if(used[i] == number)
found = true;
i++;
}
return found;
}
void project1::turnmessage(){
int number = -1;
bool found;
do{
if(turn == 1)
cout << PlayerOneName();
else
cout <<PlayerTwoName();
cout << " it's your turn!" << endl << "Enter the number you wish to use: ";
cin >> number;
number--;
bool found = game.found(number);
if (found == true)
cout << "Sorry, that has already been used. Please try again.";
}while(found == true);
}
int main(){
game.setNames();
game.resetBoard();
game.printBoard();
game.turnmessage();
return 0;
}
(the following is in the file project1.h)
#include<string>
#include<iostream>
using namespace std;
class project1{
public:
void setNames();
void resetBoard();
void printBoard();
void turnmessage();
string PlayerOneName();
string PlayerTwoName();
bool found(int&);
private:
int playerOneScore;
int playerTwoScore;
string playerOneName;
string playerTwoName;
string RowOne[3];
string RowTwo[3];
string RowThree[3];
int used[9];
int turn;
};
I think the issue is here, in resetBoard:
int used[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1};
This creates a local variable called used that's equal to the array of -1's, rather than changing the used data member to hold all -1's. To fix this, try replacing this code with the following:
for (int i = 0; i < 9; i++) {
used[i] = -1;
}
There might be other issues there, but this is certainly suspicious.
Hope this helps!
number is not being changed to some large value in project1::found it is your output from this std::cout that is confusing you:
while(i < 9 && found == false){
cout << used[i];
if you change it to this, it will be obvious what is going on:
while(i < 9 && found == false){
cout << std::endl << used[i];
^^^^^^^^^
of you could add an std::endl here as well:
cout << " your number after pass: " << number << std::endl ;