I am getting error from cin >> theGift.m_wrap[i].m_pattern; part. I am new to C++. How do I store the patterns that the user enters? For example:
Enter wrapping pattern #1: Spots
Enter wrapping pattern #2: Stripes
Enter wrapping pattern #3: Zigzags
also, how would I access these?
struct Wrapping {
char m_pattern[MAX_WRAP];
};
struct Gift {
char m_description[MAX_DESC + 1];
double m_price;
int m_units;
int m_wrapLayers = 0;
Wrapping* m_wrap = new Wrapping[m_wrapLayers];
};
bool wrap(Gift& theGift){
if (theGift.m_wrapLayers == 0) {
cout << "Wrapping gifts..." << endl;
do {
cout << "Enter the number of wrapping layers for the Gift: ";
cin >> theGift.m_wrapLayers;
}while ((theGift.m_wrapLayers <= 0) && cout << "Layers at minimum must be 1, try again." << endl);
for (int i = 0; i < theGift.m_wrapLayers; i++) {
cout << "Enter wrapping pattern #" << i + 1 << ": ";
cin >> theGift.m_wrap[i].m_pattern;
}
return true;
}else {
cout << "Gift is already wrapped!" << endl;
return false;
}
}
Wrapping* m_wrap = new Wrapping[m_wrapLayers];
This line heap-allocates an array of zero elements because m_wrapLayers is zero at the moment this allocation happens. You never reallocate the array, so attempting to access any element of this array is undefined behavior since no elements exist.
You should be using std::vector which is a dynamically-sized container that does all of the following for you:
Makes a memory allocation to hold elements.
Reallocates when attempting to add an element to a full vector, copying over the old values.
Copies itself properly.
Deallocates memory when it's destroyed.
Right now you only do the first step, and you make an allocation that can't hold anything.
Vectors also know how many elements they hold, so you don't need to track that separately.
Additionally, you should use std::string instead of character arrays for strings. std::string is much like a vector of chars; it will grow as necessary.
I would redefine your types like this:
struct Wrapping {
std::string m_pattern;
};
struct Gift {
std::string m_description;
double m_price;
int m_units;
std::vector<Wrapping> m_wrap;
};
Then your code to populate the vector goes like this:
int layers;
do {
cout << "Enter the number of wrapping layers for the Gift: ";
} while ((!(cin >> layers) || layers <= 0) && cout << "Layers at minimum must be 1, try again." << endl);
for (int i = 0; i < layers; i++) {
cout << "Enter wrapping pattern #" << (i + 1) << ": ";
theGift.m_wrap.emplace_back();
cin >> theGift.m_wrap.back().m_pattern;
}
Related
I would like to pass dynamic arrays to functions and receive user input. Currently I'm using the following code:
#include <iostream>
using namespace std;
struct make
{
int part;
int graph;
int like;
};
int z;
int *p = new int [z];
void inpart( make x[],int *fig)
{
cout << "Input part\n";
cin >> x[*fig].part;
}
void ingraph(make x[],int *tig)
{
cout << "Input graph\n";
cin >> x[*tig].graph;
}
void inlike(make x[],int *gig)
{
cout << "Input like\n";
cin >> x[*gig].like;
}
int main()
{
cout << "Input array count\n";
cin >> z;
make p[z];
for (int i=0; i < z; i++)
{
inpart(p,&z);
ingraph(p,&z);
inlike(p,&z);
}
for (int i=0; i < z; i++)
{
cout << "the result is\n";
cout << p[z].part << ", ";
cout << p[z].graph << ", ";
cout << p[z].like << "\n";
}
}
My input 1,1,1 for all the structure objects should output 1,1,1. However, the answer I receive is 1,0,2. Why?
Firstly, you shouldn't trying to initialize a static buildin array in run-time:
Your implementation is wrong here:
cout<< "Input array count\n";
cin>>z;//initialized in run-time
make p[z]; // wrong, need to be allocated with new
make* example = new make[z]; // Ok!
Secondly, you're trying to read and write out of bounds of the created array. It's Undefined behaviour. When you're creating an array with size N, chunk of the memory will be allocated to which you can have access by index. In your case from 0 to z or [0,z), excluding z. To sum up, your cycle should look like this:
for (int i = 0; i < z; i++) {
inpart(p,&i);
ingraph(p,&i);
inlike(p,&i);
}
Actually u've made a lot of mistakes in your code, but I feel like you will understand this later when continue learning.
I'm trying to dynamically allocate an array from a structure. I've look on a couple of other pages on stackoverflow and tried some some code, but none seems to work for my case. The closest I've found to what I'm doing is here:
C++ dynamic memory allocation with arrays in a structure
For some reason when I use this line of code:
cin >> testsPtr[i].students;
I get the error in the title. I've also tried using:
cin >> testsPtr[i]->students;
How can I have the user enter the data for my program?
Here are the specifications for the programming challenge:
Modify the program of Programming Challenge 1 to allow the user to enter name-score pairs. For each student taking a test, the user types a string representing the name of the student, followed by an integer representing the students score. Modify both the sorting and average-calculating functions so they take arrays of structures, with each structure containing the name and score of a single student. In traversing the arrays, use pointers rather than array indices.
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
void averageScore(double*, int);
void sort(double*, int);
int numScores;
struct studentScores {
double *scores;
string *students;
};
cout << "How many test scores will you be entering?" << endl;
cin >> numScores;
studentScores *testsPtr = new studentScores[numScores];
for (int i = 0; i < numScores; i++) {
cout << "What is the #" << i + 1 << " students name?" << endl;
cin >> testsPtr[i].students;
for (int j = 0; j < numScores; j++) {
cout << "Please enter test score #" << j + 1 << endl;
do {
cin >> testsPtr[j].scores;
if (testsPtr[i].scores < 0) {
cout << "A test score can't be less than 0. Re-enter test score #" << i + 1 << endl;
}
} while (testsPtr[i].scores < 0);
}
}
cout << endl;
/*sort(testsPtr.scores, numScores);
cout << endl;
averageScore(testScores, numScores);
cout << endl;*/
for (int i = 0; i <= numScores; i++) {
cout << testsPtr->students << " test scores are: " << endl;
for (int j = 0; j <= numScores; j++) {
cout << testsPtr->scores;
}
}
delete[] testsPtr;
testsPtr = nullptr;
return 0;
}
Dereference pointer before reading value:
cin >> *(testsPtr[i].students);
But before you have to create object string and reference pointer to it:
testsPtr[i].students = new string;
The fix to your problem is to change your cin line to this cin >> *(testsPtr[i].students); this is because testsPtr[i].students is a pointer so you have to use the deference pointer. Make sure you correctly initialize the members.
Hope this helps.
I do not get arrays, Im sure there are easier ways to make this program but I must do it the teacher's way and I am lost.
This is the assigment:
I do not get how I should go about these arrays. most confusing thing I seen by far.
What I would like is a guide or help on how i should program these arrays or how I should program arrays period. Not asking to do the rest for me, I already know how to do most of this, its just the arrays I like to know how to do.
This is my current program:
#include<iostream>
using namespace std;
void getPoints(int pPossible[], double pEarned[], int numItems, int limit);
int sumArray(double
void getpoints(int pPossible[], double pEarned[], int numItems, int limit)
{
int count;
while (limit == limit)
{
cout << "Input grade points for a category in the gradebook: " << endl
<< "How many items available in the category?: ";
cin >> numItems;
cout << endl;
if(numbItems > limit)
{
cout << "The Value exceeds the maximum number of items." << endl;
continue;
}
break;
}
count=1;
for(count=1; count<numItems; count++)
cout << "Enter points then points possible for Item " << count << ": ";
cin << pEarned[count] << pPossible[count];
return 0;
}
C++ array indexes are zero-based, so you should use zero for the initial value in the for loop. Also, you're missing the braces for the for loop body; as it is, it will run the cout line numItem-1 times and the cin line just once.
Another thing: the operators in the for's cin line should be >>, not <<. You want input here, not output.
Finally, like #ebyrob said, make numItems a reference parameter (it would be clearer for the caller to use a pointer instead, but the assignment asked for a reference parameter).
void getpoints(int pPossible[], double pEarned[], int& numItems, int limit)
{
//Read number of items
while (true)
{
cout << "Input grade points for a category in the gradebook: " << endl
<< "How many items available in the category?: ";
cin >> numItems;
cout << endl;
if(numItems >= limit)
{
cout << "The Value exceeds the maximum number of items." << endl;
continue;
}
break;
}
//Read earned and possible for each item
for(int count=0; count<numItems; count++)
{
cout << "Enter points then points possible for Item " << count << ": ";
cin >> pEarned[count] >> pPossible[count];
}
return 0;
}
#include <iostream>
#include <string>
using namespace std;
struct FriendInfo
{
string name;
int last_day;
};
FriendInfo GrowArray(FriendInfo friend_list,int sizing);
int main()
{
int initial_friends;
cout << "How many friends would you like to add--> ";
cin >> initial_friends;
FriendInfo friends[initial_friends];
for (int i = 0; i < initial_friends;i++)
{
cout << "What is your friend's name?--> ";
cin >> friends[i].name;
cout << "When was the last time you talked to " << friends[i].name << " ?--> ";
cin >> friends[i].last_day;
}
for (int i = 0; i < initial_friends;i++)
cout << friends[i].name << " " << friends[i].last_day << "\n";
cout << "What would you like to do now?\n1. Add another friend?\n2. Update one of yourfriends?\n3. Sort friends by day?4. Quit.\n--> ";
int option;
cin >> option;
while (option != 4)
{
if (option == 1)
{
friends = GrowArray(friends,initial_friends);
cout << "What is your new friend's name?--> ";
cin >> friends[initial_friends].name;
cout << "When was the last time you talked to " << friends[initial_friends].name << " ?--> ";
cin >> friends[initial_friends].last_day;
}
}
}
FriendInfo GrowArray(FriendInfo friend_list, int sizing)
{
FriendInfo new_list[sizing + 1];
for (int i = 0;i < sizing;i++)
{
new_list[i].name = friend_list[i].name;
new_list[i].last_day = friend_list.last_day;
}
return new_list;
}
This program put structures into an array that hold a friend's name, and the last day they talked to them. One of the options later on is to add another friend. The function GrowArray takes the initial array with the friends and the days, makes another array with an extra spot and copies the original array into the new one. But when I use the function I get this error --> error: could not convert '(FriendInfo*)(& friends)' from 'FriendInfo*' to 'FriendInfo'. What's wrong?
You can't reassign friends like that since it's not a pointer, it's an array.
Even if you could, what you're doing isn't safe since GrowArray just creates a new array on the stack which will be destroyed when the function returns.
You should either use new and delete to create and destroy the arrays (you can then then pass them around as pointers), or preferably, use std::vector which handles all this stuff for you.
this is my code about bubble sort.
#include "stdafx.h"
#include <iostream>
#include <cstdlib>
using namespace std;
void swap(int &a, int &b) {
int * x = &a;
int * y = &b;
int tmp = * x;
* x = * y;
* y = tmp;
}
int main()
{
// INPUT
int size;
int i=0;
int A[80];
cout << "How many number in your list A ? ";
cin >> size;
for(i=0;i<size;i++) {
cout << " A[" << i << "] = " ;
cin >> A[i];
}
// PRINT LIST
cout << "This is your list number: ";
cout << endl;
for(int i=0; i<=size -1;i++) {
cout << A[i] << " ";
}
// WHILE LOOP , continue if swapped;
bool swapped = true;
int pass=0;
while(swapped == true) {
swapped = false;
// Increase Pass
pass++;
cout << endl << endl << "Pass " << pass << ":";
// Loop size - Pass;
for( i=1; i<=size - pass;i++) {
// check if X > Y
if(A[i-1] > A[i]) {
// true, doing swap
swap(A[i-1], A[i]);
// set swapped to continue next loop
swapped = true;
}
// Print list again after sort;
cout << endl;
for(int i=0; i<=size -1;i++) {
cout << A[i] << " ";
}
}
}
// PRINT after sort;
cout << endl << endl << "Your list after sort: ";
for(int i=0; i<=size -1;i++) {
cout << A[i] << " ";
}
cout << endl;
system("pause");
return 0;
}
On this code,i must enter number of amount (size), and then enter each of A[i].
But I want to improve this code, can i don't need to enter amount (size), and just cin the the whole A?
Like:
Please enter your list number: 5 1 4 2 8 [enter]
And I get the whole A[];
Just a idea after see first answer. I see, Vector can automatic resize, but if I change into vector, will have any way to enter 1 line ? I just got an idea, I enter a string of number: 1 2 3 4 5, then I enter. do C++ have any function to split by space, and then return back to an array or a vector ? in PHP, I just use $array = explode(" ",$string); >_<
Thanks your help, tried to read many article >_<
What you should use instead of an array, is a vector. Arrays require you to know in advance how many elements will be stored, and if this number is unknown, you have to employ some rather involved memory copying once you need to exceed their predetermined capacity. Vectors do this for you under the hood.
Here's an example that basically performs what you ask, using a vector:
std::vector<int> intList;
std::string inputStr;
std::cin >> inputStr;
std::string subStr;
for ( std::string::iterator _it = inputStr.begin(); _it != inputStr.end(); ++_it )
{
if ( *_it == ',' )
{
intList.push_back( atoi( subStr.c_str() ) );
subStr.clear();
}
else
subStr.push_back( *_it );
}
if ( subStr.size() > 0 )
intList.push_back( atoi( subStr.c_str() ) );
Now intList is populated with the integers you have entered, so long as each is separated by a comma.
The easiest way to do what you want to do is to have some sort of termination marker that it is the end of the array. For example, you could use the word "done" or the number -999 to indicate the end. Then instead of a for loop to read in, you would have a do...while loop like
do
{
std::string foo;
cin >> foo;
...
} while (foo != "done");
Note that you are probably going to want to change the A[] variable from a regular array to a std::vector. Then it will store it will expand automatically and store its own size for your output. Otherwise you would have to keep another variable to store how many elements were put in(and your user could not enter more than 80 elements).