Define Global variables from File input C++ - c++

I have to define a global array in my C++ code the size of which has to be read from a file. I am using the below code
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
string inputfile = "input.txt";
ifstream infile(inputfile.c_str());
infile>>N; // N = size of Array
int array[N];
// ------some code here-----
int main(){
int N;
cout << N<<endl;
return 0;
}
But if I place the 3 lines
string inputfile = "input.txt";
ifstream infile(inputfile.c_str());
infile>>N; // N = size of Array
inside the main loop this code works. Unfortunately I cant put it inside any function because I need to initialise a global array from variable N.
I have asked many people and searched different places but I cant seem to be able to figure this out. Thanks for your help.

The size of an array has to be a constant expression, i.e. known at compile-time.
Reading a value from a file is an inherently dynamic operation, that happens at run-time.
One option is to use dynamic allocation:
int array_size()
{
int n;
ifstream infile("input.txt");
if (infile>>n)
return n;
else
throw std::runtime_error("Cannot read size from file");
}
int* array = new int[array_size()];
However it would be better to replace the array with std::vector<int> which can be resized dynamically.

Use a global pointer. Define
int* array;
in the global space before your main procedure. Then later, in a loop or not, say
array = new int[N];
to allocate your array. Just remember to also say
delete[] array;
before you exit your main or re-allocate array

int array[N]; - N should be know at compile-time.
Instead, use int array[]=new int[N]; /*some code using array*/ delete[] array;
int *array;
int main(){
ifstream infile("input.txt");
unsigned N;
infile>>N;
array=new int[N];
//using array...
delete[] array; //when no longer needed.
//don't use array after this line
//unless it's array=new int[] instruction
//or you know what you're doing.
}

Related

C++ printing array results

I was able to fix some of the errors. Now I am just getting 3.
1. control reaches end of non-void function at } before the
void displayIntegerArray(int *arrayPtr,int arraySize) function.
2. expected expression at delete[];.
3. expected expression at return 0;.
#include <iostream>
#include <iomanip>
using namespace std;
// Function prototypes
void populateIntegerArray(int *arrayPtr, int arraySize);
void displayIntegerArray(int *arrayPtr, int arraySize);
void findMaximumInteger(int *arrayPtr, int arraySize);
//method to populate array
void populateIntegerArray(int *arrayPtr,int arraySize)
{
for(int i=0;i<arraySize;i++)
{
cout<<"Enter value for array element:"<<i<<":";
cin>>arrayPtr[i]; //reading value
}
}
void findMaximumInteger(int *arrayPtr,int arraySize)
{
int maximum = arrayPtr[0];
{
for(int i=0;i<arraySize;i++)
{
if(maximum<arrayPtr[i])maximum=arrayPtr[i];
}
cout<<"Maximum integer in array is: "<<maximum<<endl;
}
}
void displayIntegerArray(int *arrayPtr,int arraySize)
{
for(int i=0;i<arraySize;i++)
{
cout<<&arrayPtr[i]<<": arrayPtr["<<i<<"] = "<<setw(15)<<arrayPtr[i]<<endl;
}
}
int main()
{
int arraySize;
// Read array size
cout<<"Enter desired array size:";
cin>>arraySize;
// Print array
cout<<"arrayPtr = "<<arraySize<<endl;
populateIntegerArray( arrayPtr, arraySize);
displayIntegerArray(arrayPtr, arraySize);
findMaximumInteger( arrayPtr, arraySize);
cout<<"DELETING array at arrayPtr = "<<arrayPtr<<endl;
delete[];
return 0;
}
In main function:
There is undeclared variable; arrayPtr.
So you have to declare it and allocate memory for it dynamically.
int* arrPtr = new int[arraySize];
You also have to provide the delete [] operator the arrayPtr to free the memory allocated.
Finally main function will be like that:
int main()
{
int arraySize;
// Read array size
cout<<"Enter desired array size:";
cin>>arraySize;
int *arrayPtr=new int[arraySize];
// Print array
cout<<"arrayPtr = "<<arraySize<<endl;
populateIntegerArray( arrayPtr, arraySize);
displayIntegerArray(arrayPtr, arraySize);
findMaximumInteger( arrayPtr, arraySize);
cout<<"DELETING array at arrayPtr = "<<arrayPtr<<endl;
delete[] arrayPtr;
return 0;
}
So there are a couple of things that ain't quite right with your program my dude, but they mainly stem from you not creating a arrayPtr in main. If you don't create something to point to a chunk of memory then your program wont know where the array is.
https://www.cplusplus.com/doc/tutorial/pointers/
The next problem is that, because you never created the pointer to the memory, you also forgot to create the space for the memory. If the array was the same size every time your program ran and was reasonably small then you could just allocate the space on the stack. However you don't so you need to allocate the memory dynamically. This means that you need to ask your operating system for the memory and get back its location. This can be done with the new[] operator. Then when you are done using the memory you tell the program to de-allocate it with the delete[] operator. (If you don't then memory will keep being marked as used despite your program ending. This is called a memory leak.)
https://www.cplusplus.com/doc/tutorial/dynamic/
Next you aren't actually displaying the location of the array. You want to print the new arrayPtr variable to see the location.
Lastly your post is a bit hard to work with. The formatting is a bit inconstant and that makes it significantly harder to read. Luckily your program was simple enough that it isn't too time consuming to read through and figure out what is going wrong. However, as your programs get more complex and larger, many people won't be willing to look through your whole program and find your bugs for you. Try to narrow down where you think the error is coming from and post: some context, the relevant chunk of code, and the exact error messages.

Error when trying to print out array in a loop using cout

#include <cstdio>
#include <iostream>
int main (){
int n;
std::cin>>n;
int*a;
for (int i=0;i<n;i++){
std::cin>>a[i];
}
for(int i=0;i<n;i++){
std::cout<<a[i];
}
return 0;
}
I just started working on a problem and I wanted to check if I knew how to read and array and make a sample output array. When I include the second loop program crashes as soon as I enter n and the first number With the following message
3 1
Process returned -1073741819 (0xC0000005) execution time : 4.943 s
Press any key to continue.
int *a; is a pointer to an integer, it is just a pointer to some memory, it has no memory allocated on its own. Since you are dereferencing this pointer a[i] without setting it up first, your compiler should even give you some warning telling that you are using a variable that has not been initialized.
0xC0000005 error code in Windows means access violation. In this case, you are trying to write to some memory which you don't have access to.
You need to allocate memory before you can read or write to it.
If you know beforehand how many entries you will have, you can do static memory allocation, if you don't, then you need to do dynamic memory allocation.
For instance, if you knew that you would need only 20 entries at max, you could easily swap int *a; for int a[20];.
But since you are only getting to know how many entries there will be when the program runs, then you need to go for dynamic memory allocation: int *a = new int[n];.
So your code should be
#include <cstdio>
#include <iostream>
int main (){
int n;
std::cin>>n;
int *a = new int[n];
for (int i=0;i<n;i++){
std::cin>>a[i];
}
for(int i=0;i<n;i++){
std::cout<<a[i];
}
delete[] a; // Release allocated memory.
return 0;
}
You need to allocate memory for a, otherwise the behaviour of the program is undefined. Writing
int* a = new int[n];
would to it, followed by delete[] a; when you're all done (put this just before return 0;).
Alternatively, use a std::vector<int> a(n); and all the memory allocation will be taken care of for you.
Try : int a[20]; rather than int *a;
Your a doesn't point to any valid memory, resulting in undefined behaviour.
What you need is an std::vector :
#include <vector>
int n;
std::cin>>n;
std::vector<int> numbers;
for (int i=0;i<n;i++){
int val;
std::cin>>val;
numbers.push_back(val);
}
for(int i=0;i<n /* or numbers.size()*/ ;i++){
std::cout<< numbers[i];
}
This takes care of dynamic allocation for you so that you don't have to do the dirty stuff yourself.
There are a few issues with your code. Primarily, you request the number 'n' then need to allocate enough space to store that many integers.
The best way to do that is to use vector. You can create this with:
std::vector< int > numbers( n );
You can also create it allocating the memory but waiting until you have data:
std::vector< int > numbers;
numbers.reserve( n );
You also should probably validate your input, for example your input stream (cin) will be invalid if the user enters something that is not an integer, and the original 'n' should be positive if you are going to try to create a vector of that size, and you may need to set a limit or you will suffer a bad_alloc. If you do not mind suffering a bad_alloc you should catch that exception and print an error such as "There is insufficient space to allocate as many numbers".
Of course if you enter a high number like 10 million, you may find the compiler is able to allocate that many but your user will get bored in your loop when you ask him to enter integers 10 million times.
You do not need <cstdio> as a header. You will need <vector> and <iostream>.
int* is a pointer to int, not an array.
To create an array of int, example: int a[100]; - where 100 is the size
Moreover, you should use a std::vector<int> instead:
vector<int> vec;
for (int i = 0; i != n; ++i) {
int temp;
cin >> temp;
vec.emplace_back(temp);
}

Make array in cpp

I am trying to make a new array in my project
the code is:
#include <iostream>
using namespace std;
void makeArray( int *& arrayPtr, int size );
int main( )
{
int * arrPtr;
int size =10;
makeArray( arrPtr, size );
for(int j=0;j<size;j++)
{
cout<<arrPtr[j]<<endl;
}
}
void makeArray( int *& arrayPtr, int size )
{
int arr[size-1];
for(int i=0;i<size;i++)
{
arr[i]=0;
}
*&arrayPtr=*&arr;
}
According to the requirements i need to use the above "makeArray" method inorder to make the array.
When i run the code the output is garbage values not zero.....
any help will be appreciated
thank you
The way you are creating the array is on the stack, which means that it will not exist after the makeArray function finishes.
You will need to allocate the array on the heap.
So:
int arr[size-1];
should be:
int *arr = new int[size-1];
Also, I think you mean to do this in makeArray():
arrayPtr = arr;
Instead of:
*&arrayPtr=*&arr;
Which compiles but is more complex and is functionally the same thing in this context.
But you may prefer just returning an int* instead of taking a reference to the pointer.
Then when you are done using the array in main(), and set it to NULL just in case you accidentally use it again, like this:
for(int j=0;j<size;j++)
{
cout<<arrPtr[j]<<endl;
}
delete [] arrPtr;
arrPtr = NULL;
Why are you declaring a parameter as 'int *& arrayPtr'? Do you just need a pointer to an array? You should use 'int *arrayPtr' instead.
To answer your question, the problem is that you are declaring an array in the function makeArray's stack. Upon the completion of a function, that function's stack is destroyed, so you're passing the address of junk data. To avoid this, use dynamic memory allocation instead.
EDIT: Also, you should use memset instead of a for loop to zero an array. It's much faster.
The "arr" which you allocate in "makeArray()" is local. and when the functione is over the array is release. When you back to main you get garbage.
What you want to do, is to use the "new" operator to allocate this new array to be used in all program, unless you will free this memory by "delete".
so you can set your makeArray() to:
int* makeArray(int size )
{
int *arr = new[size];
for(int i=0;i<size;i++)
{
arr[i]=0;
}
return arr;
}
the in you main you need to initialize your arry by:
int * arrPtr = makeArray(10);
just don't forget to release this memory after you finsh:
delete[] arrPtr ;

Why i can't watch the expression a[1][1] after declare it by a[n][n] in c++?

my code:
#include <iostream>
using namespace std;
int main() {
int n=5;
int a[n][n];
a[1][1]=5;
return 0;
}
I got this error when trying to watch the expression a[1][1] in eclipse on line 6:
Failed to execute MI command:
-data-evaluate-expression a[1][1] Error message from debugger back end:
Cannot perform pointer math on
incomplete types, try casting to a
known type, or void *.
i guess it's returned from gdb? however, i don't know why i can't watch that value? Isn't "a" is a normal multi-dimensional array?
For some odd reasons this isn't valid C++ unless you make it
const int n = 5;
Otherwise the array size is formally unknown until runtime.
C++ doesn't suppose variable length array (VLA). So your code is not standard conformant code.
It will not compile if you compile it with g++ -pedantic. The array size must be constant expression. But in your code, its not.
So write:
const int n=5; //now this becomes constant!
int a[n][n]; //the size should be constant expression.
Lets try the above code, as its completely Standard conformant code now.
why not better do it a dynamic 2d array? In that case you do not have to make the n constant, and you can determine the size dynamically.
int **arr, n;
arr = new int * [n]; // allocate the 1st dimension. each location will hole one array
for (i=0; i<n; i++)
{
arr[i] = new int [n]; // allocate the 2nd dimension of one single n element array
// and assign it to the above allocated locations.
}
Now you can access the aray as arr[i][j]
To free to the reverse
for (i=0; i<n; i++)
{
delete [] arr[i]; // first delete all the 2nd dimenstion (arr[i])
}
delete [] arr; // then delete the location arays which held the address of the above (arr)

C++: How to read dynamic data elegantly into a struct?

Lets say i store headers in some file, but some part of the header is dynamic length, something like this it would look:
struct HeaderTest {
int someparam;
int more;
int arrsize; // how big array, read arrsize elements into arr:
int arr[arrsize]; // not valid
};
Is there some elegant way for reading dynamic data into a struct?
Instead of having arr and arrsize variables in your struct, you can define your struct like this:
struct HeaderTest
{
int someparam;
int more;
std::vector<int> data;
}
No arr, no arrsize. Just use std::vector, and std::vector::size(). That is elegant!
And if you want to read binary data from a file, then you can write like this:
struct HeaderTest
{
int someparam;
int more;
int size;
char *data;
}
Otherwise, go with the first struct!
An Advice:
Reading your comments everywhere, I feel that I should suggest you to get a good book, and study it first. Here is list of really good books:
The Definitive C++ Book Guide and List
Well, if you don't want to use a container class (not sure why you wouldn't) you can declare arr as a pointer to int and leave it to the client to initialize the pointer to a valid memory location as well as correctly initialize arrsize.
That said, you should just use a vector. Why make things more difficult than they need to be?
This answer is more C than C++, but, you can easily make use of realloc() to resize a buffer to be as large as you need it. As demonstrated in this pseudo code.
struct HeaderTest {
int someparam;
int more;
int arrsize;
int arr[];
};
HeaderTest* pkt = (HeaderTest*)malloc(sizeof(HeaderTest));
read(&pkt,sizeof(pkt));
pkt = (HeaderTest*)realloc(pkt,sizeof(HeaderTest)+sizeof(pkt->arr[0])*pkt->arrsize);
read(pkt->arr,sizeof(int)*pkt->arrsize);
I don't think there is a very elegant way. You should probably make that dynamic member a pointer, then read all other members first, allocate memory for the last one, and then read the remainder of the data.
Since you're in C++, you can nicely encapsulate this in a class so that you don't have to worry about this detail in your code anymore. Also, as other have said, a std::vector would be a more C++-like approach than a simple pointer and manually allocated memory. It would also be more resistant to memory leaks.
No one was able to give you the solution you wanted, but I have devised it for you.
This function takes a C-string filename, opens the file and reads the contents for you. It returns an int*, which can be assigned to t.container. Enjoy.
int* read(char* filename)
{
// open file
ifstream f;
f.open(filename, ios::binary);
// get file size
f.seekg (0, ios::end);
int length = f.tellg();
f.seekg (0, ios::beg);
// allocate new int*
length = (length -(sizeof(int)*2)) / sizeof(int);
int* buf = new int[length];
for(int i = 0; i < length; ++i)
{
// create byte array to hold bytes
unsigned char* temp = new char[sizeof(int)];
stream.read((char*)temp, sizeof(int));
// convert byte array to int
for(int j = 0; j < sizeof(int); ++j)
{
buf[i] = buf[i] + (temp[j] << (j*8));
}
delete[] temp;
}
f.close();
return buf;
}