Is there a way to define a global variable by user input?
Lets say I use
#include...
#define N 12
double array[N][N];
void main();...
But I would like the user to be able to choose what N is.
Do I have to have N as a local variable or is there a way around this(without macros)?
I've a pretty small program but with a lot of different variables that need the N value.
Alternatively,
is there a way I could send a group of variables into a function without having to explicitly write them out every time.
for example
myfunction(var1,var2,var3...)
and instead write something like
myfunction(Allvariables)
Thanks a lot for Your answers!
This is a great forum.
int* data;
int main()
{
int n;
// get n from the user.
data = new int[n];
// use data.
.
.
delete[] data;
}
or just forget pointers for ever and use vector!
std::vector<int> data;
data.push_back(55);
// just push_back data!
=======================================================================
EDIT ::
If you want to use Edouard A. way :)
#include <iostream>
#include <sstream>
#include <vector>
int main(int argc, char* argv[])
{
std::vector<double>::size_type dataSize = 0;
std::stringstream convertor(argv[1]);
{
if(argc > 1)
{
convertor >> dataSize;
if(convertor.fail() == true)
{
// do whatever you want here in case
// the user didn't input a number.
}
}
}
std::vector<double> data(dataSize);
// use the vector here.
return 0;
}
I prefere to use lexical_cast in this case, but I am not sure if you have Boost.
#include <iostream>
#include <vector>
#include <boost/lexical_cast.hpp>
int main(int argc, char* argv[])
{
typedef std::vector<double>::size_type vectorSize;
if(argc < 2)
{
// err! The user didn't input anything.
}
vectorSize dataSize = boost::lexical_cast<vectorSize>(argv[1]);
std::vector<double> data(dataSize);
// use the vector here.
return 0;
}
1/ Yes but you need dynamic memory allocation. The program parameters are passed as argc and argv to the main function
int main(int argc, char **argv)
argc is the number of parameters
argv is the array of null terminated strings representing these arguments
argv[0] is the program itself.
2/You can either use variadic function va_start & the like, or functions overriding, or group your data in a structure and pass that to the function
No, that can't be done this way. You need to use dynamic (runtime) memory allocation (new[]). To perform static (compile-time) memory allocation the compiler needs to know the memory block size at compile time.
I'm not really sure what you're trying to do with myFunction but it sounds like you want to look at either creating a struct or pass a std::vector
Make a class (or struct) AllVariables and pass that in.
You don't say whether you want N defined at run time or compile time. If you want it defined at compile time, you can define N as a compiler command line arguement.
Related
#include<iostream>
#include<vector>
using namespace std;
int main(int argc,char** argv){
int n;
if(argc>1)
n=argv[0];
int* stuff=new int[n];
vector<int> v(100000);
delete stuff;
return 0;
}
When I try to run this code snippet I got an error invalid conversion from char * to int fpermissive. I can not figure out what does this error indicate. If any one have any idea please help me to find out its meaning.
Thank you in advance.
argv is a pointer to a pointer to a character which in short you can assume as pointer to strings and you assign an element of that directly to n.
n is a character array.
First convert n to an integer by atoi() which you can find in stdlib.h
I guess in C++ it is cstdlib.
You can't assign a char* pointer to anintvariable, unless you type-cast it, which is not what you need in this situation. You need to parse thechar*string using a function that interprets the *content* of the string and returns a translated integer, such as [std::atoi()](https://en.cppreference.com/w/cpp/string/byte/atoi), [std::stoi()`](https://en.cppreference.com/w/cpp/string/basic_string/stol), etc.
Also, you are not initializing n if the user runs your app without entering a command-line parameter. And the first user-entered parameter is stored in argv[1], argv[0] contains the calling app's path/filename instead.
Also, you need to use delete[] instead of delete. Rule of thumb - use new and delete together, and new[] and delete[] together. Or prefer to not use them directly at all (use std::vector, std::make_unique<T[]>(), etc instead).
Try something more like this:
#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;
int main(int argc,char** argv){
int n = 0; // <-- initialize your variables!
if (argc > 1)
n = atoi(argv[1]); // <-- [1] instead of [0]! and parse the string...
int* stuff = new int[n];
vector<int> v(100000);
delete[] stuff; // <-- use delete[] instead of delete!
return 0;
}
I want to initialize an array with user defined size, but what know is- I've to declare an array of maximum size and then work on number of elements given by user in this process huge memory wastes. Is there any way to declare an array of size given by user.
I did this but compiler showed error.
int a=0;
std::cout<<"Enter size of array";
std::cin>>a;
const int b=a;
int ary[b];
I'm using Turbo C++IDE
The issue with your code is that you are declaring what is called a variable length array which is not part of C++ (though it is valid C code). See this for an explanation as to why.
You can achieve what you are trying to do in a few different ways though:
You could dynamically allocate an array using a user provided size:
#include <iostream>
#include <memory>
int main(int argc, char** argv)
{
std::size_t a =0;
std::cout<<"Enter size of array";
std::cin>>a;
std::unique_ptr<int[]> arr(new int[a]);
//do something with arr
//the unique ptr will delete the memory when it goes out of scope
}
This approach will work but may not always be ideal, especially in situations where the size of the array may need to change frequently. In that case I would recommend using a std::vector:
#include <iostream>
#include <vector>
int main(int argc, char** argv)
{
std::size_t a =0;
std::cout<<"Enter size of array";
std::cin>>a;
std::vector<int> arr(a);//arr will have a starting size of a
//use arr for something
//all of the memory is managed internally by the vector
}
You can find the reference page here.
You can use new keyword while declaring a dynamic array
int main()
{
int array_size;
std::cin >> array_size;
int *my_array = new int[array_size];
delete [] my_array;
return 0;
}
You should delete the array allocated with new.
You can also use vector for dynamic allocation of memory in c++. Read here for examples on vector
In a program I am currently working on I have a template function included in a separate .h file that reads in five columns of data from a .txt file. The data is passed to the main program and in this instance I only care about the array title "MISC_DATA". I am trying to determine the largest value in the array "MISC_DATA" and have written another function that the data has to be passed to, in order to determine this. However, the compiler is telling me that it does not recognize the function call "Maximum_Value". I am pretty sure that it is having problems with the variable MISC_DATA included in the routine call and not the function itself. Either it does not recognize MISC_DATA as an array or I have the syntax wrong. I'm only including the important snippets of code to make it more readable. The Read_Five_Columns functions works fine, it is the function "Maximum_Value", which is not being recognized by the compiler because of how the pointer array MISC_DATA is written in the main program. For clarification the variable MISC_DATA in the function call is a float which contains the array and the variable "size_Mis" is an integer which contains the array size. Any thoughts would be appreciated.
int main(int argc, const char * argv[]) {
#include "Use_RNG.h"
#include "Read_Columnar_File.h"
#include <fstream>
#include <iostream>
std::vector<std::string> str3;
std::vector<int> str4;
std::vector<char> str5;
std::vector<int> str6;
unsigned long size_Mis;
std::vector<float> MISC_DATA; // Reads in Misc. spending data
char File1[8];
strcpy(File1, "Misc.txt");
Read_Five_Columns(File1,MISC_DATA,str3,str4,str5,str6);
str3.clear(); str4.clear(); str5.clear(); str6.clear();
size_Mis = MISC_DATA.size();
float value;
value = Maximum_Value(MISC_DATA,size_Mis);
end_time = clock();
std::cout << std::endl << "Total Time: " << (end_time-start_time)/CLOCKS_PER_SEC << std::endl;
return 0;
}
int Maximum_Value(float *array,int array_size)
{
float max = 0;
for(int i =10; i < array_size-1; i++)
{
if(array[i] > max) max = array[i];
}
return max;
}
There are four problems I see here.
int main(int argc, const char * argv[]) {
#include "Use_RNG.h"
#include "Read_Columnar_File.h"
#include <fstream>
#include <iostream>
All of this stuff is in the wrong order. You should not include system header files into function bodies, and typically you include standard library stuff before other stuff. Fix it to read like this:
#include <fstream>
#include <iostream>
#include "Use_RNG.h"
#include "Read_Columnar_File.h"
int main(int argc, const char * argv[]) {
Secondly, you don't declare Maximum_Value before you use it. You need to either move the definition of this function before the definition of main() or you need to add a prototype before main():
int Maximum_Value(float *array,int array_size);
int main(int argc, const char * argv[]) {
Then, you attempt to pass an std::vector<float> as a float* which does not work:
value = Maximum_Value(MISC_DATA,size_Mis);
However, because the storage for vectors is guaranteed to be contiguous and laid out like an array, you can pass a pointer to the first member safely:
value = Maximum_Value(&MISC_DATA[0],size_Mis);
Finally, you return int from Maximum_Value when you should probably be returning float.
If possible I would suggest leveraging std::max_element, which is part of the standard <algorithm> header:
// If you don't have C++11 then use std::vector<float>::iterator instead of auto.
auto max = std::max_element(MISC_DATA.begin(), MISC_DATA.end());
Now max is an iterator to the largest element, so *max would be the largest float itself.
(If the input range was empty, then max will be equal to MISC_DATA.end(), so the equivalent to your function would be value = max == MISC_DATA.end() ? 0f : *max;.)
I'm making a new app for my lab and I must take form terminal some arguments, and I want to copy the **args value into a string, and after that I must match the args for execute some foreplay operation.
I try to build this code to copy the **argv value into string var but this is the error:
No source available for "std::string::operator=() at 0x44c1dc"
The code is this:
int main(int argc, char **argv)
{
string args[argc-1];
int j=0;
for(int i=2; i<argc-1;i++)
{
j=0;
while(argv[i][j]!='\0')
{
args[i]=args[i]+argv[i][j];
j++;
}
}
return 0;
}
I would propose this solution:
std::vector<std::string> args;
std::copy(argv + 1, argv + argc, std::back_inserter(args));
References:
std::copy
std::back_inserter
To explain it a little, this copies from argv[1] (I don't care about argv[0] as it's the "command" and usually irrelevant for argument handling) into the vector. We stop copying at argv[argc] which is one beyond the end of the actual arguments (which is how "end" iterators work).
std::back_inserter creates a special iterator that is used to insert ad the end of containers.
Fastest and shortest solution with range constructor:
std::vector<std::string> args(argv + 1,argv + argc);
Make things as clear as you can. (Will help those 3am debugging sessions in your laboratory).
int main(int argc, char **argv)
{
std::vector<std::string> args(argc);
for (int i = 0; i < argc; ++i){
args[i] = argv[i];
}
// rest of code here.
}
Yes I know I waste args[0], but do you really care about that? The indexing is so much clearer if you do it this way, args has the same indexing conventions as argv (which all us old cats are used to), and you don't get a whole lot of edge cases when you only pass the program name.
There are a few mistakes in your code, which also causes the odd problems. Also you're overcomplicating things quite a bit.
Here's what I'd do, this will require one additional header, <vector>, for the STL container, but it will make things a lot easier (since you shouldn't rely on being able to create arrays with dynamic lengths (also note that your array length might be 0, if there are no arguments given!))
int main(int argc, char **argv) {
std::vector<const std::string>> params; // This is the container that will take all arguments.
// Iterate over all arguments provided
// (skipping the very first, since that's the executable itself)
for (int i = 1; i < argc; i++)
// Add the argument to the vector
// (this will construct a new std::string and add it to the end).
params.push_back(argv[i]);
// You're now able to access the arguments passed:
// params.size() will return the number of arguments.
// params[i] will return the i-th argument, starting at 0.
return 0;
}
int main(int argc, char **argv)
{
string args[argc];
int j=0;
for(int i=2; i<argc;i++)
{
args[i-2].assign(argv[i]);
}
return 0;
}
first, you can't use a dynamic argument in a static expression.
you must use either new to create a string array, or, better yet, use a vector (or any other container you like).
second, there is no point in copying the values one character by another. copy the entire string.
here is a sample code that will work:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef vector<string> svec;
int main(int argc,char **argv)
{
svec strings;
if(argc>1)
{
cout <<"arguments:"<<endl;
for(int i=1;i<argc;i++)
{
strings.push_back(argv[i]);
}
}
for(auto i:strings)
{
cout << i;
}
return 0;
}
D.
EDIT #1
So I think my solution is to pass the class around through the functions, si then I have to get the size values in main and pass them into the class. So how would I create a multidimensional array within the class based on 2 int values? This is what I have, but I get the error "`ii' cannot appear in a constant-expression "
class tempHolder{
public:
bool C1[col1][row1];
tempHolder(){
}
tempHolder(int i, int ii){
int* C1 = new bool[i][ii];
}
}
So my program has a multidimensional array, but I'm using global variables (which I know is bad style) to declare the size of the array. The problem is that I also pass this array to functions and I use it in a class, like the code below...
#include <iostream>
using namespace std;
const int row1 = 12;
const int col1 = 32;
class tempHolder{
public:
bool C1[col1][row1];
void operator=(bool C2[col1][row1]){
for(int i=0;i<row1;i++)
for(int ii=0;ii<col1;ii++)
C1[i][ii] = C2[i][ii];
}
};
void printTable(bool CC[][row1], int, bool);
int main(int argc, char *argv[]) {
col1=5; //error
bool C1[col1][row1];
So I want to be able to change the values of row1 and col1 right at the beginning of main, which would then change the array size for the entire program. If I declare the global variables like above, then the program compiles, but since they are constants, I won't be able to change them. I can't use a #define because those are not changeable at all. So what can I do to resize the array for the entire program?
You cannot simply change the size of the array by simply changing the dimensions at runtime - you need to allocate the memory dynamically with new. Best is usually to use the STL containers - they have their length property built in and can be easily resized.
The size of the arrays is set before main begins, when the program is compiled.
So, even if col1 only changes once at startup, it still must be a proper non-const variable.
You likely want std::vector to implement a variable-sized array. Note that vector<bool> is a specially-optimized class which uses one bit, not one byte, per Boolean value. You might try using vector<char> instead if there are problems or performance is poor.
#include <iostream>
using namespace std;
int row1 = 12;
int col1 = 32;
typedef vector< vector< bool > > bit_array_2d;
class tempHolder{
public:
bit_array_2d C1;
void operator=( bit_array_2d const &C2 ){
C1 = C2;
}
};
int main(int argc, char *argv[]) {
col1=5; // OK
bit_array_2d C1( col1, vector< bool >( row1 ) );
A more advanced approach, if there are only a few potential sizes to select from, is to use template-parameterized C arrays.