Printing contents of a vector [duplicate] - c++

This question already has answers here:
How do I print out the contents of a vector?
(31 answers)
Closed 5 years ago.
I am trying to get a feel for C++, and I want to either print the contents of a vector, or, to confirm my program is correct, I could add the contents of my vector and print the result.
Here is my code:
#include <iostream>
#include <vector>
using std::vector;
using std::cin;
using std::cout;
int main(){
int n;
vector<int> result;
cin >> n;
vector<int> numbers(n);
for(int i = 0; i < n; ++i){
cin >> numbers[i];
}
result = numbers;
cout << result;
return 0;
}
I found some solutions online for printing a vector, but I didn't understand what the code was doing, so I am hoping someone can help.

As you mentioned "I did not understand what the code is doing", let me briefly describe how to iterate through a container:
The long way:
vector<int> result = { 1,2,3 };
for (vector<int>::iterator it = result.begin(); it != result.end() ; it++) {
int i = *it;
cout << i << " ";
}
Each container provides an iterator, which you can think of a pointer moving forward along the elements of the container. begin() returns a pointer to the first element, end() returns a pointer to 1 past the last element. Dereferencing the iterator gives the actual value.
For above long way, with range-based for loops, C++ provides a shorthand notation with about the same meaning (i.e. it makes use of the iterator-concept but is less "clumsy" in notation):
for (auto i : result) {
cout << i << " ";
}
Try it out; hope it helps.

you can print the vector content by making a loop the print every index in the vector size
like
for(int i=0;i<numbers.size();i++){
cout<<numbers[i];
}
the loop will print every index until the end of the vector

Related

How to get a vector of strings from input?

I'm trying to get a vector of string from input to create a graph , but i don't know why in middle my code it crashes. please help me fix it. I use Visual Studio.
#include <iostream>
#include <vector>
#include <iterator>
void main(void)
{
{
using namespace std;
int8_t n{ 0 };
cout << "enter the size of graph : ";
cin >> n;
vector<string> graph(n);
string connectionsWith;
vector<string>::iterator i;
string::iterator e;
int p{ 0 };
for (i = graph.begin(); i != graph.end(); ++i)
{
cout << '\n' << "enter the vertices that are connected to " << p << " : ";
cin >> connectionsWith;
graph.push_back(connectionsWith);
p++;
}
p = 0;
for (i = graph.begin(); i != graph.end(); ++i)
{
cout << p << " is connected to " << *i;
p++;
}
}
}
In your constructor of graph, you allocate n string. Inside the loop you add on top of the constructed n strings, n more strings via push back. That potentially invalidates your iterators, as ChrisMM said, also not the most efficient way to implement such a scenario.
So as a solution, instead of
vector<string> graph(n);
do
vector<string> graph;
graph.reserve(n);
and iterate over the index, e.g. from 0 to n, and push back.
Especially in the first loop you are not dereferencing the iterator at all, which suggests that using index based loop would show your intent better.
life_steal pointed out the problem. I would like to add few information and other way to solve the problem.
int8_t n{ 0 };
vector<string> graph(n); // Here initialization happening with ASCII. If input is "1" then it would be "49". Consider changing int8_t to int if you unaware of that.
graph.push_back(connectionsWith); //Instead of this line Use: *i = connectionsWith; it directly assign the value.

User in a variable?

I am a beginner and I would like to ask you something.
We have an array whose size depends on value input by user in a variable ‘arraysize’. Look at below code and comments please, is it a correct way to achieve this said be behaviour?
int * myArray = NULL;
int arraySize;
cout << "Enter array size: ";
cin >> arraySize;
myArray = new int[arraySize];
delete [] myArray;
The earlier answer was a community wiki. Since you asked for an example, here's a more detailed answer.
A std::vector is a class belonging to the standard template library read in detail.
//since you used "using namespace std;" I'm omitting the "std::"
Declaration
vector< int > v; //creates a vector of integers
vector< double > vd; //vector of double values
This is quite similar to int a[/*any number*/].
Inserting values
v.push_back(5); //adds 5 to the end of the vector (or array of variable size)
With the above two lines you dont need to know in advance how many numbers you'll have to store.
One more sample code.
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> myvector;
int myint;
std::cout << "Please enter some integers (enter 0 to end):\n";
do {
std::cin >> myint;
myvector.push_back (myint);
} while (myint);
std::cout << "myvector stores " << int(myvector.size()) << " numbers.\n";
return 0;
}
This program reads values and saves to myvector till 0 is entered in input.
Iteration
std::vector<int>::size_type sz = myvector.size(); //even int works here
// assign some values:
for (unsigned int i=0; i<sz; i++) myvector[i]=i;
Deletion
v.pop_back(); //removes last element
Use std::vector as a C++ best practice.

Why are the iterators not compatible?

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <iomanip>
using namespace std;
vector<string>::iterator findString(vector<string> word, string x)
{
auto beg = word.begin();
for ( ; beg != word.end() && x != *beg; beg++);
return beg;
}
vector<int>::iterator convert(vector<string>::iterator &t, vector<string> &word, vector<int> &amount)
{
vector<int>::iterator count = amount.begin();
vector<string>::iterator beg = word.begin();
for (; beg != word.end() && beg != t; count++, beg++);
return count;
}
int main()
{
vector<string> word;
vector<int> amount;
string x;
cout << "Please enter words list:" << endl;
cin >> x;
word.push_back(x);
amount.push_back(1);
while (cin >> x)
{
vector<string>::iterator t = findString(word, x);
if (t != word.end()) //A: Error happens in this line.
{
vector<int>::iterator i = convert(t,word,amount);
(*i) ++;
}
else
{
word.push_back(x);
amount.push_back(1);
}
}
for (auto r : word)
cout << setw(4) << r;
cout << endl;
for (auto r : amount)
cout << setw(4) << r;
cout << endl;
return 0;
}
In this program I want to count the number of each word input.
I wrote a conversion function from string iterator to int iterator. But it still doesn't work and says the iterators are not compatible. Is there something wrong? Moreover, I'm confused why iterators can't be converted into the corresponding integers. And why there is 'ptrdiff_t', wouldn't it be easier if it's just 'int'?
It's the first time I use this website. And I'd be grateful if someone can answer my questions. Thanks.
-It's a run-time error, after inputting two strings. Debug assertion failed. File: vector, line 248. Expression: vector iterators incompatible. I ran it on VS2015.
-Error happens in line A.
I understand finally. Thanks everyone. Thank you so much and wish y'all a good day!
Your error doesn't have anything to do with strings or ints or conversions. It's because you're creating a new copy of vector<string> word every time you call findString, and so its returned iterator is an iterator of a different vector (it's an iterator into a copy). You have:
vector<string>::iterator findString(vector<string> word, string x)
{
...
}
And then later, where the error is:
vector<string>::iterator t = findString(word, x);
if (t != word.end()) //A: Error happens in this line.
And so findString is returning an iterator into a copy of word instead of word itself, and MS' vector implementation has an assertion failure when you try to compare it with an iterator from a different vector, because it figures you most likely made a mistake. Instead pass your vectors by reference, for example:
vector<string>::iterator findString(vector<string> & word, string x)
{
...
}
Note that word is now passed by reference, and so won't be copied.
That said, you should fix your error first as an exercise, of course, but after you've got your own code working, consider replacing findString with std::find (since it already exists). Also it seems you can simplify your code greatly by using a map<string,int> to maintain word counts. And a few other things.
Those two types are simply different and can't be converted one into the other. They are not "integers", they abstract a position in a container.
I think the actual problem you see is because your findString is returning an iterator relative to a copy of your words vector. When you compare that iterator to word.end(), the two iterators are relative to different containers, and the VC STL rightfully complains. Accept the vector by reference for a start.

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.

How to make a list C++ [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
So I have to make a program that stores input piece by piece, until -1 is input. An example of this input would be 1 1 1 0 3 5 3 -1. And -1 would not be recorded. Then it plays the list back to you, but bacwards, so output would be 3 5 3 0 1 1 1
To do this I need to make a list of objects, but I have no clue how to declare them, or how to add/remove items to them. how do I do this?
You need a place to store values that can grow as values are read.
The simpler is probably std::vector, but also std::list or std::deque as well as whatever bidirectional container will do the game.
Then you need a loop to get the values an save them into the container (the push_back method has that purpose), and another loop getting the values from the container from the end and printing them.
This can be done using iterators or using indexes, depending on the container and on your own specific needs.
This may be a possibility:
#include <vector>
#include <iostream>
template<class V, class S>
void read_numbers(V& v, S& s, N end)
{
N x=0;
while(x << s)
{
if(x==end) return;
v.push_back(x);
}
std::cerr << "error: bad reading" << std::endl;
}
template<class V, class S>
void write_numbers(const V& v, S& s)
{
for(auto i=s.rbegin(); i!=s.rend(); ++i)
std::cout << *i << ' ';
std::cout << std::endl;
}
int main()
{
std::vector<int> nums;
read_numbers(nums, std::cin, -1); }
write_numbers(nums, std::cout);
return 0;
}
For a list of unknown size, you can declare a vector class:
std::vector<int> myVector;
Then to add an element, use push_back:
// assign some integer to myInt
myVector.push_back (myInt);
http://www.cplusplus.com/reference/vector/vector/push_back/
If you need to use a list, then you could use std::list.
You can declare them like this:
std::list<int> myList;
You can read more about std::list here.
You can use it for inspiration.
#include <vector>
#include <iostream>
int main(int argc, char * argv[]) {
std::vector<int> numbers;
int number;
do {
std::cin >> number;
if (number != -1) {
numbers.push_back(number);
}
} while(number != -1);
for (std::vector<int>::reverse_iterator it = numbers.rbegin(); it != numbers.rend(); ++it) {
std::cout << *it << " ";
}
std::cin.get();
return 0;
}
As was suggested already, you could use std::vector. It resizes as you push more elements. If the requirement is strictly a linked list, then go for std::list.
As to the requirement of playing them in reverse order, just use reverse_iterator and go through the list printing them.
std::list<int> mylist;
// Insert the elements.
for (std::list<int>::reverse_iterator rIt = mylist.rbegin();
rIt != mylist.rend(); ++rIt) {
cout << *rIt;
}
There are basically two options:
You can use a pointer int *data and manually allocate memory to it with new[]. You'll need to continually reallocate the array as you find that the array is larger than you expected.
You can use one of the wonderful containers that c++ provides. I might suggest std::vector.
Here's an example of how you might implement this:
#include <iostream>
#include <vector>
int main() {
std::vector<int> data;
while (true) {
int number;
std::cin >> number;
if (!std::cin)
break;
if (number == -1)
break;
data.push_back(number);
}
for (int datum : data)
std::cout << datum << " ";
std::cout << "\n";
}