how can I pass an array pointer to a function - c++

#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
typedef vector <double> record_t;
typedef vector <record_t> data_t;
int sorted(int *data,int max_record_size)
{
}
int main()
{
// Here is the data we want.
data_t data;
// Here is the file containing the data. Read it into data.
ifstream infile( "sort.txt" );
infile >> data;
// Complain if something went wrong.
if (!infile.eof())
{
cout << "Fooey!\n";
return 1;
}
infile.close();
// Otherwise, list some basic information about the file.
cout << "Your CSV file contains " << data.size() << " records.\n";
unsigned max_record_size = 0;
for (unsigned n = 0; n < data.size(); n++)
if (max_record_size < data[ n ].size())
max_record_size = data[ n ].size();
cout << "The largest record has " << max_record_size << " fields.\n";
int i;
for (i=0; i <= max_record_size; i++)
{
cout << "your data contains " << data[ 0 ][ i ] << ".\n";
int temp[max_record_size];
sorted(&data,max_record_size);
//cout << "Your sorted data contains" << sorted [0] [i] << ".\n";
}
cout << "Good bye!\n";
system("PAUSE");
return 0;
}
cannot convert data_t*' toint*' for argument 1' toint
sorted(int*, int)'
Im trying to pass the pointer of my data which should be an array containing my list of numbers to my sort function what exactly am I doing wrong and can you please explain in detail so I can understand it, thanks!

You don't have an array. An array in C (or C++) would be just a list of integers, and you could pass it like you did.
However, you have a vector (and I'm guessing record_t ends up being an int). vector<>s behave a lot like arrays, but they are not, they are actual objects.
What you probably want to do is write your function as
int sorted(data_t& data, int max_record_size)
and your call simply as
sorted(data,max_record_size);

data_t is a vector<vector<double>>. This is not even close to an array of ints. You just need to write a function that handles data_t and not ints.
If the function is supposed to sort data then you should use std::sort, and to do that you'll need to write a comparison function that can compare two elements of data in order to see which one should come before the other in the sorted result.
Here's an example of providing such a comparison function using a lambda with lexicographical_compare.
sort(begin(data),end(data), [](record_t const &lhs,record_t const &rhs) {
return lexicographical_compare(begin(lhs),end(lhs),begin(rhs),end(rhs));]
});

Try passing a reference to the original vector. Why?
You still want to work with the original vector without making a copy
You can't pass a null reference, so the argument is always valid
You're not doing any pointer arithmetic, so be safe and use a reference
int sorted(data_t& data, int max_record_size)
{
}
Pass your data_t structure like this:
sorted(data, max_record_size);
Now you have access to the data_t structure inside your sorted function.
Also
You know that your code is not going to compile?
unsigned max_record_size and int temp[max_record_size] are invalid. If you're going to allocate an array on the stack, you need to use a constant size.
There is no overload on the >> operator in the istream class that handles vector<vector<double>>, so this statement is broken as well: infile >> data;

Related

How to return an array from a function in c++ [duplicate]

This question already has answers here:
Return array in a function
(20 answers)
Closed 4 years ago.
I'm really confused on the theory behind this. Not sure how to return the array from my isAscending function so i can print out in the main.
#include <iostream>
#include <string>
using namespace std;
// Implement printArray here
void printArray(int array[], int n){
for (int i = 0; i < n; ++i )
cout << array[i] << endl;
};
// Implement isAscending here
int isAscending(int array[], int n){
for(int i = 0; i <= n; ++i){
for(int j = 0; j <= n; ++j){
if(array[i] > array[j+1]){
int temp = array[j+1];
array[j+1] = array[j];
array[j] = temp;
}
}
}
return printArray(array, n);
};
// DO NOT CHANGE MAIN FUNCTION BELOW
int main() {
int myarray[100];
cout << "Enter number of integers : ";
int n;
cin >> n;
cout << "Enter " << n << " integers" << endl;
for (int i = 0; i < n; i++)
cin >> myarray[i];
cout << "Contents of array : ";
printArray(myarray, n);
cout << "Output of isAscending: " << isAscending(myarray, n) << endl;
}
Should I use pointers to pass the elements in the array i am stuck.
The short answer is you don't. When you pass an array to a function, you're actually just passing a pointer to the first element (the array decays to a pointer when you pass it as an argument). This means that if you modify the array in the function, you're modifying the original array and not a copy. Therefore, your isAscending() function will bubble sort the array you called it on and it does not need to return anything.
Just a side note, it seems like the assignment simply wants you to check if an array is ascending, instead of sorting it. In that case, isAscending() should return a bool.
If you need a function to return an array, you can't just pass a pointer to the first element since the array goes out of scope as soon as the function returns. You could dynamically allocate the array, but that just creates a bunch of new problems. Another way might be to return the pointer to the first element of the array passed to it as an argument like this, but there isn't much point in doing that since the caller already has access to the array.
The best way would be to use something like std::array or std::vector, which you can return by value just like any other variable. I would also recommend getting a good book.
(I provided this answer besides flagging as a duplicate since I thought the answer of the duplicate question was not complete enough and might mislead someone into trying to return a pointer to a local array)

How to take inputs from array and input it into an equation in C++?

My goal is to try and create a program that takes in grades in percents and multiply it with their weight value (either in decimal form or percent form). The equation is basically:
Overall grade = (grade1*weightInDecimal1)+(grade2*weightInDecimal2)+(grade3*weightInDecimal3)+...
or
Overall grade = (grade1*weight%1)+(grade2*weight%2)+(grade3*weight%3)+...
Is there a way to store the inputs and then recall it later in the code? Or possibly a more efficient way?
I also want to try and make a dynamic array. I want to make a program that asks the user for how many assignments they have and makes an array based on that. That way it's not stuck at 4 assignments
#include <string>
#include <iostream>
using namespace std;
int main() {
int numbers[4][2];
for(int i=0;i<4;i++)
{
cout<<"Grade #"<<i<<endl;
cin>>numbers[i][0];
cout<<"Weight for grade #"<<i<<":"<<endl;
cin>>numbers[i][1];
}
for (int i = 0; i<4; i++)
{
cout << "|" << numbers[i][0]*numbers[i][1]<< "|";
}
system ("PAUSE");
return 0;
}
This is what structs are for
#include <string>
#include <iostream>
#include <array>
using namespace std;
struct entry {
int grade;
int weight;
int gradeWeight; //grade*weight
};
int main() {
array<entry,4> numbers;
for(int i=0;i<numbers.max_size();i++)
{
cout<<"Grade #"<<i<<endl;
cin>>numbers[i].grade;
cout<<"Weight for grade #"<<i<<":"<<endl;
cin>>numbers[i].weight;
}
for (int i = 0; i<numbers.max_size(); i++)
{
numbers[i].gradeWeight = numbers[i].grade*numbers[i].weight;
cout << "|" << numbers[i].gradeWeight << "|";
}
system ("PAUSE");
return 0;
}
This way you can also increase the amount of numbers by just increasing the array size.
As pointed by others, if you ask the user for how many assignments they have, std::array is a wrong container because it's dimension is fixed at compile time.
As others, I discurage the use of direct memory allocation but the use of std::vector to manage it.
I just suggest the use of reserve() (method of std::vector), when you know how many assignments.
The following is a full example using, instead a couple of std::vector of int, a single std::vector of std::pair<int, int>
#include <utility>
#include <vector>
#include <iostream>
int main()
{
int valG, valW;
std::size_t dim;
std::vector<std::pair<int, int>> vec;
std::cout << "How many grade/weight couples? ";
std::cin >> dim;
vec.reserve(dim);
for ( auto i = 0U ; i < dim ; ++i )
{
std::cout << "Grade #" << i << "? " << std::endl;
std::cin >> valG;
std::cout << "Weight for grade #" << i << "? " << std::endl;
std::cin >> valW;
vec.emplace_back(valG, valW);
}
for ( auto const & p : vec )
std::cout << '|' << (p.first * p.second) << '|';
std::cout << std::endl;
return 0;
}
There are many reasons to avoid using arrays (dynamic or otherwise). See for example Stroustrup's FAQ entry What's wrong with arrays? As Greg suggests in the comments you will most likely write better quality code if you use a container like std::vector.
If you can calculate or input the size of your container before allocating it you can (if you wish) pass that size to the constructor ...
auto syze{ 0 };
auto initialValue{ 0 };
// calculate or input syze
. . .
// dynamically allocate an "array"
// of ints and an "array" of floats
std::vector<int> grades(syze, initialValue);
std::vector<float> weights(syze, initialValue);
On the other hand if you prefer to use a container that dynamically grows to hold data as it arrives you can do that too...
// dynamically allocate an empty "array"
// of ints and an empty "array" of floats
std::vector<int> grades;
std::vector<float> weights;
while (...condition...)
{
std::cin >> g; // input a grade ...
std::cin >> w; // ... and a weight
// grow the containers by adding
// one item at the end of each
grades.emplace_back(g);
weights.emplace_back(w);
}
Update
I should have pointed out how to calculate the result from the two vectors. You can calculate your overall grade with just one more line of code by using std::inner_product from the STL's <numeric> header. Note that in the code below the last argument is 0.0 (rather than just 0) so that std::inner_product returns a double rather than an int. That avoids any risk of float values being truncated to int (and avoids some pretty ugly warnings from the compiler).
auto overallGrade = std::inner_product(grades.begin(), grades.end(), weights.begin(), 0.0);

Basic c++ function using vectors

I'm doing some exercises with vectors. I created a function that fill a vector with defined size but when I tried to make it n size, the vector apparently is filled with trash memory, it shows: 0x23fe20, and my code crash when I try to use the vector.
#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
using namespace std;
int cargavn(int vec[]) // fill vector
{
int i, t;
cout << "vector size: ";
cin >> t;
for(i = 0 ; i <= t-1; i++)
{
cout << "v["<< i <<"]=";
cin >> vec[i];
}
return (1);
}
int main()
{
int vec[10]; // the vector, size here wont matter
cargavn(vec); // call fill vector n positions
cout << vec; // to test if the vector is well filled
system("PAUSE");
}
you are exprecting cout << vec to somehow pretty print the vector. It wont, it just prints its address
You need to loop over the contents and print each element
for(int i =0 ; i < 10 ; i++)
{
cout << vec[i];
}
Here's how it would look using modern C++:
#include <iostream>
#include <vector>
using namespace std;
void cargavn(vector<int> &vec)
{
int t;
cout << "vector size: ";
cin >> t;
for(int i = 0; t > 0; ++i, --t)
{
cout << "v["<< i <<"]=";
int v;
cin >> v;
vec.push_back(v);
}
}
ostream &operator<<(ostream &s, vector<int> const &vec)
{
s << '{';
bool first = true;
for (int v : vec)
{
if (!first)
{
s << ", ";
}
s << v;
first = false;
}
return s << '}';
}
int main()
{
vector<int> vec;
cargavn(vec);
cout << vec;
system("PAUSE");
return 0;
}
Things to understand about this version compared to yours:
Unnecessary includes are ommitted.
Prefer C++ containers like vector over C style arrays.
Use dynamically sized containers when they need to hold an arbitrary number of values provided by the user instead of fixed-size containers that break when the user enters too much data. See the rule of 0, 1, infinity.
When all control paths of a function return the same value, then the returned value is pointless and can be omitted. Particularly if none of the callers even bothers to check the return value. I suspect you had the intention of using the return value to indicate some kind of unexpected error. This is a C-style approach to error handling. C++ uses exceptions to deal with unexpected errors.
Overload operator<< to extend the stream insertion operator to decide how containers and your own custom types should be formatted. The standard library doesn't provide any such insertion operator for vector because there isn't any universally agreed upon way to decide how a vector of values should be formatted. So you decide this for yourself.
It is good form for main to return a value, even though this is not technically required.

passing array as parameter to a function

this script is supposed to output array values that were inputted by the user into array "store." I am trying to store all the char array values into string temp. I get the error on line 12: "[Error] invalid conversion from 'char*' to 'char' [-fpermissive]." Would appreciate any help!
Edit: so I fixed the declaration and now at least it compiles, but the answer I get on my cmd is all jumbled up. Why is this so? The cmd only correctly couts the first string but after the space, it messes up.
#include <iostream>
#include <cstdlib>
using namespace std;
void coutArray(char[], int);
int main()
{
char store[50];
cout << "enter text: " << endl;
cin >> store;
coutArray(store, 50);
system("pause");
return 0;
}
void coutArray(char store[], int max)
{
string temp = "";
int i = 0;
while (i < max)
{
temp += store[i];
i++;
}
cout << temp << endl;
}
Using input from all answerers I finally got the fixed code:
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
void coutArray(char[], int);
int main()
{
char store[50] = {0};
cout << "enter text: " << endl;
cin.getline(store, 50);
coutArray(store, 50);
system("pause");
return 0;
}
void coutArray(char store[], int max)
{
string temp = "";
int i = 0;
while (i < max && store[i]!=0)
{
temp += store[i];
i++;
}
cout << temp << endl;
}
Thanks everyone. i learned a lot!!!
When you get an input using "cin" your input automatically ends with 0 (NULL).
You just need to add one little piece of code to your while statement.
instead of this :
while (i < max)
use this :
while (i < max && store[i]!=0)
Now it will stop when the input string is finished and won't print any garbage existed in the array beforehand.
To show that cin does add terminating zero, i initialized the array to 46, and put a breakpoint after the cin
so I fixed the declaration and now at least it compiles, but the answer I get on my cmd is all jumbled up. Why is this so?
Not sure what you mean by jumbled up. But since you did not tell us what you typed its hard to know it looks like it worked to me:
> ./a.out
enter text:
Plop
Plop�ȏU�
Notice that since my input is only 4 characters long. This means that a lot of the characters in the array still have undefined (ie random values). This is why I am seeing junk. To get past this initialize the array to have all 0 values.
char store[50] = {0};
Even bettern use a C++ object than handles longer strings.
std::string store;
std::getline(std::cin, store);
Note: passing arrays to functions by value is not a good idea. On the other end they have decayed to pointers and thus do not act like arrays anymore (they act like pointers whose semantics are similar but not identical).
If you must pass an array pass it by reference. But I would use a C++ container and pass that by reference (it is much safer than using C constructs). Have a look at std::string
The declaration of the function is wrong. Should be void coutArray(char *, int);
Look at the Implicit Conversion rules to understand what the compiler can do and what it cannot to do for you.
The issue with your program was that you were probably entering in less characters than the maximum size of the buffer. Then when you passed the maximum size as the parameter to coutArray, you assigned unfilled slots in the char array to temp. These unfilled slots could contain anything, as you have not filled them up to that point.
Your program is still correct, but what would be better would be to use read so that the number of bytes you specify is the minimum number of bytes that can be entered:
std::cin.read(store, 50);
Even better solution would be to use std::string:
std::string store;
std::cin >> store;
// or for the entire line
std::getline(std::cin, store);
It also follows that your coutArray should be changed to:
void coutArray(std::string);
// ...
void coutArray(std::string str)
{
std::cout << str << std::endl;
}
Look at this way
template<typename T, size_t N>
void MyMethod(T (&myArray)[N])
{
//N is number of elements, myArray is the array
std::cout<<"array elements number = "<<N<<endl;
//put your code
string temp;
temp.resize(N+1);//this is for performance not to copy it each time you use += operator
int i = 0;
while (i < max)
{
temp += store[i];
i++;
}
cout << temp << endl;
}
//call it like this
char arr[] = "hello world";
MyMethod(arr);

How to get the size of the used space in an array? (NOT sizeof); c++

#include<iostream>
using namespace std;
int main()
{
char arr[200];
while(1) {
cin >> arr;
int i = sizeof(arr);
cout << "The arr input is "<< arr
<< " and the size of the array is "<< i << endl;
}
return 0;
}
For the input of 34,
This code outputs :The arr input is 34 and the size of the array is 200
while I want it to get the size of the used space of the array . So for The last input i want it to output :The arr input is 34 and the size of the array is 2
Can someone tell me how?
Maybe you want strlen(arr) here. It must be null terminated, otherwise the cout << arr would not have worked.
You would need to #include <cstring>
There's no automatic way to do what you want in the general case - you'll need to keep track somehow, either with your own counter, or by seeding the array with an 'invalid' value (that you define) and search for to find the end of the used elements (that's what the '\0' terminator character in a C-style string is).
In the example code you posted, the array should receive a null terminated C-style string, you can use that knowledge to count the number of valid elements.
If you're using C++ or some other library that has some more advanced data structures, you may be able to use one that keeps track of this kind of thing for you (like std::vector<>).
the size of the used space of the array
There is no such thing. If you have an array of 200 chars, then you have 200 chars. Arrays have no concept of "used" and "unused" space. It only works with C-strings because of the convention that those are terminated by a 0 character. But then again, the array itself cannot know if it is holding a C-string.
in a less involved manner, you can just count through each character till you hit a null with just a while loop. It will do the exact same thing strlen() does. Also, in practice, you should do type checking with cin, but i'll assume this was just a test.
#include <iostream>
using namespace std;
int main()
{
char arr[200];
int i;
while(1) {
cin >> arr;
i=0;
while (arr[i] != '\0' && i<sizeof(arr))
i++;
cout << "The arr input is "<< arr
<< " and the size of the array is "<< i << endl;
}
return 0;
}
Just for completeness, here is a much more C++ like solution that is using std::string instead of a raw char array.
#include <iostream>
#include <string>
int
main()
{
while (std::cin.good()) {
std::string s;
if (std::cin >> s) {
std::cout
<< "The input is " << s
<< " and the size is " << s.length()
<< std::endl;
}
}
return 0;
}
It doesn't use an array, but it is the preferable solution for this kind of problem. In general, you should try to replace raw arrays with std::string and std::vector as appropriate, raw pointers with shared_ptr (scoped_ptr, or shared_array, whatever is most appropriate), and snprintf with std::stringstream. This is the first step to simply writing better C++. You will thank yourself in the future. I wish that I had followed this advice a few years ago.
Try it
template < typename T, unsigned N >
unsigned sizeOfArray( T const (&array)[ N ] )
{
return N;
}