I wanted to reverse my array. Why this code gives garbage value? - c++

#include <iostream>
using namespace std;
int main(){
int n;
int a[n];
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
for(int i=n;i>=0;i--){
cout<<a[i]<<" ";
}
}
Input:- 4
1 2 3 4
Output 4199008 4 3 2 1

For starters the program has undefined behavior because the variable n is not initialized
int n;
So this declaration
int a[n];
is invalid. Moreover variable length arrays is not a standard C++ feature. Instead use the standard class template std::vector.
Also within this loop
for(int i=n;i>=0;i--) {
cout<<a[i]<<" ";
}
you are trying to access of non-existent element with the index n.
Also you are not reversing an array. You are trying to output an array in the reverse order.
Pay attention to that there are standard algorithms std::reverse and std::reverse_copy declared in the header <algorithm>.
Here is an example how your program with using your approach could look
#include <iostream>
#include <vector>
int main()
{
size_t n = 0;
std::cout << "Enter the size of an array ";
std::cin >> n;
std::vector<int> v( n );
std::cout << "Enter " << n << " elements: ";
for ( auto &item : v ) std::cin >> item;
std::cout << "The array in the reverse order\n";
for ( size_t i = v.size(); i != 0; )
{
std::cout << v[--i] << ' ';
}
std::cout << '\n';
return 0;
}
The program output might look like
Enter the size of an array 10
Enter 10 elements: 0 1 2 3 4 5 6 7 8 9
The array in the reverse order
9 8 7 6 5 4 3 2 1 0
If to use standard algorithms then your program can look the following way
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
int main()
{
size_t n = 0;
std::cout << "Enter the size of an array ";
std::cin >> n;
std::vector<int> v( n );
std::cout << "Enter " << n << " elements: ";
std::copy_n( std::istream_iterator<int>( std::cin ), n, std::begin( v ) );
std::cout << "The array in the reverse order\n";
std::reverse_copy( std::begin( v ), std::end( v ),
std::ostream_iterator<int>( std::cout, " ") );
std::cout << '\n';
return 0;
}
The program output might look the same way as shown above
Enter the size of an array 10
Enter 10 elements: 0 1 2 3 4 5 6 7 8 9
The array in the reverse order
9 8 7 6 5 4 3 2 1 0

a[n] will return the element after the last one. When you iterate in reverse order, start with i=n-1.

At the beginig of your program there is a mistake:
int n; // You declare n with no value
int a[n]; // You use is
cin>>n; // After you used it you get your value-
Now i can suppose that that was just an error while copying it because you give inputs and outputs
Input:- 4 1 2 3 4 Output 4199008 4 3 2 1
So forgeting about that, you declare an array of size n. Remember that the elemnts of the array will go from 0 to n-1. Now look at your second for loop
// the first element you acces is n and you stop at 1
// but the array goes from n-1 to 0
for(int i=n;i>=0;i--){
cout<<a[i]<<" ";
}
So you still get n values as an output but the first element that you access is outside of the array. Thats why you get a garbage value, that is a value that was left there.
A solution will be to change the for loop
for(int i=n-1;i>=-1;i--){
cout<<a[i]<<" ";
}

While reversing the array start the loop from n-1 that is i=n-1 (n is the no of elements in array). And run the loop till i>=0. If you will start loop from n it will read illegal index which is out of range and will give you garbage value.
for(int i=n-1; i>=0; i++){
cout<<arr[i]<<" ";}

Related

What is the difference in initializing vector v(n) between the following two cases

I have following piece of code,
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int input,n;
cin >> n;
vector<int> v(n);
for(int i=0;i<n;i++){
cin>>input;
v.push_back(input);
}
for(int i=0; i<v.size();i++){
cout << v[i] << endl;
}
cout << v.size() << endl;
return 0;
}
and
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int input,n;
vector<int> v(n);
cin >> n;
for(int i=0;i<n;i++){
cin>>input;
v.push_back(input);
}
for(int i=0; i<v.size();i++){
cout << v[i] << endl;
}
cout << v.size() << endl;
return 0;
}
for the following input, n=5, 1 2 3 4 5 , first program gives the output
0
0
0
0
0
1
2
3
4
5
10
and the second program gives the result
1
2
3
4
5
5
I donot understand why vector is initializing 0's in the first doubling the size but not in the second
Actually, neither of those are correct for what you want (I'm assuming here you want the five elements you input and nothing more - that may be an invalid assumption but it seems like a good bet to me).
In your first one, you have (comments added to explain what's happening):
int input,n; // n has arbitrary value.
cin >> n; // overwritten with 5.
vector<int> v(n); // initial vector has five zeros.
This means your vector will be created with five (assuming you input that for n) default-constructed entries. Then you go and insert five more, which is why you get five zeros followed by your actual data.
Your second one has:
int input,n; // n has arbitrary value.
vector<int> v(n); // initial vector of that arbitrary value (probably).
cin >> n; // overwritten with five but it's too late anyway.
This is actually undefined behaviour since you have no idea what n will be when you create a vector of that size. In your case, it appears to be zero but that's just a lucky coincidence.
Note the use of the word "probably" above. While it's likely that the vector will be created with some arbitrary number of entries, undefined behaviour means exactly that - you should not rely on it at all. By rights, it could quite easily delete all your files while playing derisive_laughter.wav through your sound system :-)
The most likely case however will be one of:
it'll work as you thought, because n is zero;
it'll have some arbitrary number of zeros at the start, similar to your first code snippet;
it'll cause an out-of-memory exception because n is ridiculously large; or
it'll cause an exception because n is negative.
In any case, you should generally either pre-allocate and just set the already-existing values:
vector<int> v(2);
v[0] = 7;
v[1] = 42;
or not pre-allocate, using push_back to expand the vector on demand:
vector<int> v;
v.push_back(7);
v.push_back(42);
Hope, one can write the 1st case of writing program in the question in the following way to get correct result
1
2
3
4
5
5
for the input given as in the question
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n;
cin>>n;
vector<int> v(n);
for(int i=0;i<n;i++){
cin>>v.at(i);
}
for(int i=0;i<v.size();i++){
cout << v[i] << endl;
}
cout << v.size() << endl;
return 0;
}

Store Matrix with integer from a text file into an array in c++

I have a file named matrices.txt that has two matrices that are 3 by 3.
They are:
1 2 3
4 5 6
7 8 9
1 2 3
4 5 6
7 8 9
I'm trying the read from this file and store it into an array proto_matrix to later split that into two matrices.
The problem I'm having is that I can't store the numbers in the array.
My code is
#include <iostream>
#include <fstream>
using namespace std;
void main()
{
int i = 0, j, k = 0, n, dimension;
cout << "Enter the dimension of square matrices (3 by 3 would be 3) \n";
cin >> n;
dimension = n * n;
int proto_matrix[2 * dimension];
// make array of two matrices combined, this will be split into two matrices
ifstream matrix_file("matrices.txt");
while(matrix_file)
{
matrix_file >> proto_matrix[i];
}
matrix_file.close();
}
I tried debugging the code and it seems like the no integer is stored in the array, just random numbers.
This:
int proto_matrix[2 * dimension];
is a Variable Length Array (VLA), which is not Standard C++, but is supported by some compiler extensions. If compile with g++ -pedantic main.cpp, you will surely get an error.
That means that you need to dynamically allocate your memory, if you had to use an array.
You really don't though, C++ offers std::vector, which can achieve what you want relatively easily. I say relatively, because you have two matrices in one file, which makes parsing the file a bit tricky. Usually we put the one matrix in one file, and the other matrix to another file.
A 2D array can be represented as a 2D vector.
You want two matrices, thus two 2D vectors.
For that reason, I will use an array of size 2 (fixed size!), where every element is going to be a 2D vector.
Moreover, I will keep track of which matrix I am reading from the file right now (the first or the second), and how many rows I have read currently, in order to populate the correct cell of the matrix.
index is going to be equal to 0 or 1, to index the array.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
int main()
{
int i = 0, j, k = 0, n, dimension;
cout << "Enter the dimension of square matrices (3 by 3 would be 3) \n";
cin >> n;
dimension = n * n;
vector< vector<int> > v[2];
v[0].resize(n);
v[1].resize(n);
// make array of two matrices combined, this will be split into two matrices
ifstream matrix_file("matrices.txt");
string line;
int rows_read = 0, cols_read = 0, index = 0;
while (std::getline(matrix_file, line))
{
std::istringstream iss(line);
int a, b, c;
if (!(iss >> a >> b >> c)) { break; } // error
// process tuple (a, b, c)
if(index == 0 && rows_read >= n)
{
rows_read = 0;
index = 1;
}
//cout<<"rows = " << rows_read << " " << index<<endl;
v[index][rows_read].push_back(a);
v[index][rows_read].push_back(b);
v[index][rows_read++].push_back(c);
}
matrix_file.close();
for(int i = 0; i < 2; ++i)
{
cout << "Printing matrix " << i << endl;
for(auto& matrix: v[i])
{
for(auto& number: matrix)
cout << number << " ";
cout << endl;
}
}
return 0;
}
Output:
Printing matrix 0
1 2 3
4 5 6
7 8 9
Printing matrix 1
1 2 3
4 5 6
7 8 9
PS: Unrelated to your problem, but What should main() return in C and C++? An int.
Based on my answer, I will post here a cleaner example, which achieves what your code tries to achieve: Read all the numbers in a 1D data structure (which will be split in two matrices somehow later).
So for that case, the code boils down to just this:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
int main()
{
int i = 0, j, k = 0, n, dimension;
cout << "Enter the dimension of square matrices (3 by 3 would be 3) \n";
cin >> n;
dimension = n * n;
// make array of two matrices combined, this will be split into two matrices
vector<int> proto_matrix;
ifstream matrix_file("matrices.txt");
string line;
while (std::getline(matrix_file, line))
{
std::istringstream iss(line);
int a, b, c;
if (!(iss >> a >> b >> c)) { break; } // error
proto_matrix.push_back(a);
proto_matrix.push_back(b);
proto_matrix.push_back(c);
}
matrix_file.close();
for(auto& number: proto_matrix)
cout << number << "\n";
return 0;
}
You could just read all the values into a flat container (such as std::vector) and do the re-arrangement at a later point. The following code may give you an idea:
#include <vector>
#include <fstream>
#include <iostream>
int main() {
std::vector<int> values;
std::ifstream fp("matrices.txt");
for (int value; fp >> value; ) {
values.emplace_back(value);
}
std::cout << "I read " << values.size() << " values:\n";
for (auto && value : values) std::cout << value << " ";
std::cout << "\n";
}
Result:
$ clang++ matrixread.cpp -std=c++17
$ ./a.out
I read 18 values:
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9
You don't increment i, thus always writing to the first element. It should be:
matrix_file >> proto_matrix[i++];

How to access elements of array and vector repeatedly in c++?

I have a vector of int V'
vector<int> V={2,4,5,6,7};
I want to iterate through vector such that if index is greater than size of vector it should return again some element in vector for example V.size() is 5 if I enter V[6] I need result to return 4,if I enter v[5] it should return 2.....
can I also do it with arrays??
Thanks in advance..
If you want accessing the values to "wrap around", then simply use the modulo operator when indexing.
That is to say: instead of V[i], use V[i % V.size()].
For array[]={2,4,5,6,7};
If you want to circle through array you could use index mod sizeofarray.
Let n be the index
//here size of array =5;
You could use array[n% 5] to acces elements.
so array[6] => array[6 % 5] => array[1]= 4
and same applies with vector.
Here's a solution that prompts for user input until the user inputs a number within the boundaries of the array...
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vec{1, 3, 5, 7, 9}; // size 5
int num = 0;
do {
cout << "Enter a number between 0 and " << vec.size() - 1 << ": ";
cin >> num;
} while (num < 0 || num >= vec.size());
cout << "The vector value is: " << vec[num] << endl;
return 0;
}

The vector of random integers cannot be printed, C++

I wrote a simple program to generate a vector of random numbers. I tried to print each element in the vector but the output doesn't seem correct. For example, I push_back 5 numbers but the vector.size() gives 10... I have no idea why. Please help.
#include <iostream>
#include <vector>
#include <time.h>
#include <cstdlib>
using namespace std;
int main()
{
srand(time(NULL));
vector<int> arr(5);
int i, val;
for (i=0; i<5; i++)
{
val = rand()%30;
cout << "value " << i << " is " << val << endl;
arr.push_back(val);
}
for (i=0; i<arr.size() ; i++){
cout << arr[i] << " " << arr.size() << endl;
}
return 0;
}
OUTPUT:
value 0 is 2
value 1 is 13
value 2 is 9
value 3 is 28
value 4 is 27
0 10
0 10
0 10
0 10
0 10
2 10
13 10
9 10
28 10
27 10
In line
vector<int> arr(5);
you already allocated 5 entries. You can access them without pushing back new elements. eg:
vector<int> arr(5);
arr[1];
is valid and won't crash.
Now if you do additional push_back you will extend existing vector, so it will change its size.
vector<int> arr(5);
This creates a vector of 5 elements.
arr.push_back(val);
This appends one new element to the vector. So the first time it is called, the vector will now contain 6 elements.
The vector constructor you are using, creates a vector with 5 values (equal to 0) already present in it. If you want to make the vector allocate space for 5 elements (as I am assuming - your plan). You can create a vector with a default constructor and then use the reserve method.
instead of
vector<int> arr(5);
It should read
vector<int> arr;
arr.reserve(5);

How do I add elements to an empty vector in a loop?

I am trying to create an empty vector inside a loop, and want to add an element to the vector each time something is read in to that loop.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
std::vector<float> myVector();
float x;
while(cin >> x)
myVector.insert(x);
return 0;
}
But this is giving me error messages.
You need to use std::vector::push_back() instead:
while(cin >> x)
myVector.push_back(x);
// ^^^^^^^^^
and not std::vector::insert(), which, as you can see in the link, needs an iterator to indicate the position where you want to insert the element.
Also, as what #Joel has commented, you should remove the parentheses in your vector variable's definition.
std::vector<float> myVector;
and not
std::vector<float> myVector();
By doing the latter, you run into C++'s Most Vexing Parse problem.
Use push_back:
while(cin >> x)
myVector.push_back(x);
The insert function takes an iterator as the first argument, indicating the position to insert.
Also, you need to get rid of the parentheses in the declaration of myVector:
std::vector<float> myVector;
If you want to use myVector.insert(),
use it like myVector.insert(myVector.end(), x). This will append x at the end of myVector.
You can insert x in the beginning by myVector.insert(myVector.begin(), x).
Another option is to use std::vector::emplace_back() instead of std::vector::push_back(). The makes some optimizations and doesn't take an argument of type vector::value_type, it takes variadic arguments that are forwarded to the constructor of the appended item, while push_back can make unnecessary copies or movements.
This is demonstrated in the std::vector::emplace_back documentation and here is a related question.
Usage example:
std::vector<int> myVector;
while (cin >> x) {
myVector.emplace_back(x);
}
The code below may answer your question and also brings some other examples regarding how to insert new elements in different position or index.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vector_of_integers{};
vector_of_integers.push_back(1); // O(1)
vector_of_integers.push_back(3); // O(1)
vector_of_integers.push_back(5); // O(1)
vector_of_integers.push_back(7); // O(1)
for (int i = 8; i <= 10; i++)
vector_of_integers.push_back(i);
// Printing out all the elements of vector of integers - Method 1
copy(vector_of_integers.begin(), vector_of_integers.end(), ostream_iterator<int>(cout, " ")); // 1 3 5 7 8 9 10
cout << endl << endl;
// Inserting '2' at index 1
vector<int>::iterator it{ vector_of_integers.begin() };
advance(it, 1);
vector_of_integers.insert(it, 2); // O(N+M) => M is size of elements to be inserted
// Printing out all the elements of vector of integers - Method 2
for (auto const& element : vector_of_integers)
std::cout << element << " "; // 1 2 3 5 7 8 9 10
cout << endl << endl;
// "it" no longer valid, get a new one
it = vector_of_integers.begin();
vector_of_integers.insert(it + 4, 6); // O(N+M) => M is size of elements to be inserted
// Printing out all the elements of vector of integers - Method 3
for (it = vector_of_integers.begin(); it != vector_of_integers.end(); it++)
std::cout << *it << ' '; // 1 2 3 5 6 7 8 9 10
cout << endl << endl;
// insert '4' 7 times at index 3
vector<int> new_vector_to_be_inserted(7, 4);
vector_of_integers.insert(vector_of_integers.begin() + 3, new_vector_to_be_inserted.begin(), new_vector_to_be_inserted.end()); // O(N+M) => M is size of elements to be inserted
// Printing out all the elements of vector of integers - Method 4
for (int i = 0; i < vector_of_integers.size(); i++)
cout << vector_of_integers.at(i) << ' '; // 1 2 3 4 4 4 4 4 4 4 5 6 7 8 9 10
cout << endl << endl;
return 0;
}