I'm using a matrix of characters by defining a vector of vectors of chars the following way.
std::vector<std::vector <char> > CharMap;
std::vector <char> temp(sizeY, '.');
std::vector <std::vector <char> > temp2(sizeX, temp);
CharMap = temp2;
This has been working fine so far, but now I need to expand the innermost vectors during runtime and something is going wrong.
cout << (int) CharMap[0].size();
CharMap[0].push_back( '.' );
cout << (int) CharMap[0].size();
CharMap[0] is a vector of chars. This code compiles with no problem. When it runs, the size of the vector simply doesn't change. All I'm trying to do here is increase the size by 1, but the ouput is the same on both couts. Why isn't the size increasing?
Inside the actual code I will increase the size of all CharMap[i], iterating overi. But right now even this simplified version isn't working.
A quick test program seems to work as expected:
#include <vector>
#include <iostream>
int main() {
std::vector<char> temp(17, '.');
std::vector<std::vector<char> > map(10, temp);
for (int i=0; i<map.size(); i++) {
std::cout << "Before addition, size = " << map[i].size();
map[i].push_back('.');
std::cout << ", after addition, size = " << map[i].size() << "\n";
}
return 0;
}
I suppose you could try that and see what it produces with your compiler -- it's barely possible it won't, in which case you've apparently discovered a bug. If it does work, then the problem is apparently in some code you haven't shown us.
Related
#include <iostream>
#include <vector>
int main()
{
unsigned int numVec;
unsigned int input;
std::cout << "Enter Number of Vectors: ";
std::cin >> numVec;
std::vector<int>* Vec;
for (unsigned int i = 0; i < numVec; i++)
{
std::cout << "Enter Vector Value " << i << ": ";
std::cin >> input;
Vec->push_back(input);
}
std::cout << std::endl;
for (unsigned int i = 0; i < Vec->size(); i++)
{
std::cout << "Value at Index (" << i << ") " << Vec->at(i) << std::endl;
}
std::cout << std::endl;
return 0;
}
I am trying to learn how Vectors work as it is a topic that i have withheld learning for a very long time for no apparently reason.
My above code will compile and run however once i put in a number to store in the Vector it will crash.
The program did work before when i was just using a vector without the pointer but just for learning reasons i wanted to try it with a pointer, I am just wondering what am i doing wrong with this code and if someone could possibly flame me for doing something or give me some good advice on what i am doing wrong in this situation so i can learn for future reference.
Replace
std::vector<int>* Vec;
with
std::vector<int> vec;
and replace the pointer to member operator -> with the member selection operator ..
Only on rare occasions do you need to use dynamic storage for a std::vector instance, as that class does an excellent job of managing the memory for you. Currently you are not allocating any memory for your vector, and the behaviour of your code is undefined.
If you must use a pointer then write
std::vector<int>* vec = new std::vector();
and don't forget to call delete vec; when you're done. Consider using std::unique_ptr &c. so the delete is taken care of automatically.
My above code will compile and run however once i put in a number to store in the Vector it will crash.
What vector?
You never created a vector.
You only created a pointer, one which (a) is uninitialised, and (b) does not point to anything, let alone a (c) vector.
My name is Matt. I'm new to StackOverflow and am fairly new to C++. Currently working my way through C++ Primer by Lippman.
I'm doing an exercise in the book, and task is to read integers in to the vector, and then multiply those integers by doing first and last, second and second to last, third and third last etc.
I did it myself without looking anything up, or else I'd barely learn if I just copied... my program compiles and acts as expected. My question is: did I do this correctly? is there a more efficient way of doing it?
I not only want to learn how to make working code, but I want to do it correctly. Thank you in advance!
#include <iostream>
#include <string>
#include <vector>
#include <cctype>
using std::cout; using std::cin; using std::vector; using std::endl;
using std::string;
int main()
{
vector<int> numbers;
int usernum = 0;
cout << "Enter some numbers: ";
while (cin >> usernum)
{
numbers.push_back(usernum);
}
unsigned maxElement = numbers.size() - 1;
unsigned minElement = 0;
for (auto i : numbers)
{
cout << numbers[minElement] << " * " << numbers[maxElement] << " = " << numbers[minElement] * numbers[maxElement] << "\n";
++minElement;
--maxElement;
}
return 0;
}
In a comment, you said:
I've noticed it doesn't actually work as fully expected. It goes through vector and multiplies everything twice as maxElement goes right through to beginning, and minElement goes through to end. Not sure how to stop it once it's only done the operation on each one time.
If you don't want to repeat the multiplications, you need to change the for loop a bit.
for ( ; minElement <= maxElement; ++minElement, --maxElement)
{
cout << numbers[minElement] << " * " << numbers[maxElement] << " = " << numbers[minElement] * numbers[maxElement] << "\n";
}
PS
When you use this logic, you'll need to make sure that minElement and maxElement are of a signed type. Otherwise, you will run into problems if numbers has only one element.
The first thing that feels strange for me is the namespaces you are using.
Instead of doing: using namespace std::vector; you can fairly just do using namespace std; because you call std::vector anyways: vector<int> numbers;***. This applies to any "used" namespace you work with. Just do using namespace std; once and for all.
***I am unsure that std::vector/std::cout/... is even a namespace. std - is a namespace. std::vector should be a class under std namespace:
namespace std
{
template<typename T> class vector<T> {...};
}
How come it "acts as expected". I do not get an idea of this loop: while(cin >> usernum). How do you know when the user input is finished from that point? For a first glimpse (did not compile/run it myself) I expect it either:
not compile
crash at runtime or having undefined behaviour
run the while-loop infinitely
Use this instead:
for (int i = 0, end_of_vector = numbers.size(); i < end_of_vector/2; i++)
{
cout << numbers[i] << " * " << numbers[end_of_vector - 1 - i] << " = " << numbers[i] * numbers[end_of_vector - 1 - i] << "\n";
}
Reasons:
In this case you do not need any special variables to store first and last vector indexes.
You iterate only through a half of an array.
Using for (auto i : numbers), is is expected to use i as an element of numbers vector. But you do not do this, instead, you use numbers as is. Thus, this for-loop is ambiguous
I have finished writing a program that included reversing, expanding and shifting arrays using the pointer requirement asked by the professor. Everything compiles but the answer from the expand function does not return what I wish: adding 0s after the old user input array which asks for the size of the array and the numbers you wish to put into the array. I think my problem may lie from the fact that I include a pointer on something that might not have a reference in the program. Below is my code:
// *numPtr refers to my old user input array and int tamaño is the size of the array
void expandArray(int *numPtr, int tamaño) {
int *nuevoArray = new int[tamaño *2];
for (int i = 0; i<tamaño; i++) {
nuevoArray[i] = numPtr[i];
}
for (int i = tamaño; i < (tamaño*2); i++) {
nuevoArray[i] = 0;
}
std::cout << nuevoArray << " ";
}
As I said, my theory of the code not compiling the way I wish is because I use the *nuevoArray and it has no reference in my main code, but then again, I am just a beginner with C++. I was thinking of just doing a vector, but I think I would not follow the pointer requirements placed by the professor.
If you want to print the contents of nuevoarray, just use a for loop like this:
for (int i = 0; i < (tamaño*2); i++) {
std::cout << nuevoArray[i] << " ";
}
std::cout << "\n";
Also, since you are using new[] to create the array, you should not forget to delete[] it!
you can print your array by using
for (int i = 0 ; i < tamano * 2 ; ++i) {
std::cout << nuevoArray[i] << " ";
}
std::cout << std::endl;
or in c++11
for (auto i : nuevoArray) {
std::cout << i << " ";
}
std::cout << std::endl;
PS: The std::endl will return to the start of the new line and flush the cout buffer.
Your code does appear to be allocating a larger array and correctly copying data from numPtr into the new array and also correctly filling the remainder of the new array with zeros.
You don't explicitly say what you expect this function to output, but I'm guessing you expect it to print out the contents of the new array, and that you believe there's a problem because instead of that, you're seeing it print something like "0x7fb46be05d10".
You're not correctly printing the array out. Instead you're printing the memory address of the first element out. If you want to see the contents, then you need to loop over the elements of the array and print each one out individually.
Here's a function showing one way of doing that:
#include <algorithm>
#include <iterator>
void printArray(int *arr, int n) {
std::copy(arr, arr + n, std::ostream_iterator<int>(std::cout, " "));
}
Now you can replace the line std::cout << nuevoArray << " "; in your existing code with printArray(nuevoArray, tamaño*2);
(Also it sounds like whoever is teaching you C++ should take a look at this presentation from the recent C++ conference, CppCon 2015: Stop Teaching C)
I've done some self learning in the past with c++ online but gave up, till I bought a textbook on it and giving it another go. In my past research, I never read anything on vector arrays (or maybe I did and don't remember, who knows).
Anyway it says like regular arrays, vector arrays can be created for any data type and I'm trying to get a char vector array going and I'm running into some compile errors take a look.
I want an array of 26 that houses all the letters in the alphabet capitalized. So 65 to 91 I think. If there is and easier way to initialize the array with the letter I'm interested in learning that way.
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector <char> vchChar(26, 65);
for (int iii = 0; iii < vchChar.size(); iii++ )
{
for (int jjj = 65; jjj < 91; jjj++)
{
vchChar(iii) = jjj;
cout << "vchChar(" << iii+1 << ") is:\t" << vchChar(iii) << endl;
}
//cout << "vchChar(" << iii+1 << ") is:\t" << vchChar(iii) << endl;
}
return 0;
}
Originally I had square brackets instead of the parenthesise, fixed that and had hoped it would work but that got a whole set of new problems when I tried changing them in the cout statements. When I had them in square brackets it printed out in the terminal fine no compile errors. So now I have the cout statements like
cout << "vchChar(" << iii+1 << ") is:\t" << vchChar[iii] << endl;
I thought vector arrays where incremented by one from the element before it. But all I got when I printed vchChar into the terminal where all 'A's. So I tried playing around with another for loop to assign them by one from the element before it. I got some different outputs then I'd desired, and cant find the right algorithm to do it.
I'll keep at it, but an answer on this post is just as good for me. I have little idea what I'm doing so post everything you've got, but keep in mind that I probably wont have any idea what you're talking about :S. I've probably left something out because I've change the code a bit when troubleshooting, so if there are any question ask, and thank for your time.
I do not see any sense in your code. If I have understood correctly what you need is the following
#include <iostream>
#include <vector>
#include <numeric>
int main()
{
std::vector<char> vchChar(26);
std::iota( vchChar.begin(), vchChar.end() , 'A' );
for ( char c : vchChar ) std::cout << c << ' ';
std::cout << std::endl;
return 0;
}
Or you can write it even the following way
#include <iostream>
#include <vector>
#include <numeric>
int main()
{
std::vector<char> vchChar( 'Z' - 'A' + 1 );
std::iota( vchChar.begin(), vchChar.end() , 'A' );
for ( char c : vchChar ) std::cout << c << ' ';
std::cout << std::endl;
return 0;
}
If your compiler does not support standard algorithm std::iota and the range-based for statement then you can write
#include <iostream>
#include <vector>
#include <numeric>
int main()
{
std::vector<char> vchChar( 'Z' - 'A' + 1 );
for ( char c = 'A'; c <= 'Z'; ++c ) vchChar[c - 'A'] = c;
for ( std::vector<char>::size_type i = 0; i < vchChar.size(); ++i )
{
std::cout << "vchChar[" << i << "] is:\t" << vchChar[i] << std::endl;
}
return 0;
}
Take into account that it is a bad idea to use magic numbers as 65 or 91. For example if the program will run in an IBM mainframe then the result will be unexpected because there is another coding system, that is EBCDIC instead of ASCII.
As for statement
vchChar(iii) = jjj;
then it is invalid. Expression vchChar(iii) means a call of the operator function with one argument that is not defined in class std::vector.
You have at least the following issues in your code:
Setting a vector element is not done by myVector(index), but myVector[index], so basically the operator[]. In this special case, however, you can just push them in a row to the back.
You are trying to print one element of the array with vchChar(iii), but you should use the .at(index) method.
It is not crucial, but in this special case, you could use the iterator pattern to go through the vector rather than dealing with the indexing. Even if you do not do that, it is needless to use iii and jjj for variable names instead of the regular i and j.
I would prefer to use size_t or the vector<char>::size_type for the loop counters as you compare one of them against the vector size.
You are setting the elements more than once because you have a nested loop.
You are needlessly constructing the vector differently than the default.
You are using hard coded integers rather than actual characters.
Therefore, your correct code would look like this:
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector <char> vchChar;
for (char c = 'A'; c <= 'Z'; ++c)
vchChar.push_back(c);
for (vector<char>::size_t i = 0; i < vchChar.size(); ++i)
cout << "vchChar(" << i+1 << ") is:\t" << vchChar.at(i) << endl;
return 0;
}
Disclaimer: this is just compilation and runtime fix. I have not dealt with use case and design issues. There are better solutions as I partially mentioned them, but I decided to make your code with the least impact.
You do not need nested loops.
{
vector<char> vchChar;
for (char letter = 'A'; letter <= 'Z'; ++letter) {
vchChar.push_back(letter);
}
for (int i = 0; i < (int) vchChar.size(); ++i) {
cout << vchChar[i];
}
}
I have so far been able to use 1-d vectors, adding or removing elements with push/pop back.
However, when trying to fill out a 2-d vector which is supposed to represent a matrix, I run into problems. I haven't been able to use these functionalities with my 2-d vector. When the code does compile and run I get the bits asking for dimension and then it asks for the first element [1,1], for any value entered I get "Segmentation fault: core dumped". I have no idea what is going on and have been trying to modify bits of my code but to no great success, the internet has also been rather useless in giving an easy guide on how to fill out these damn things...
Thank you so much!
Here is my code
#include <iostream>
#include <vector>
using namespace std;
vector<vector<double> > readMatrix();
int main()
{
vector<vector<double> > matrix1 = readMatrix();
vector<vector<double> > matrix2 = readMatrix();
}
vector<vector<double> > readMatrix()
{
cout << "Entering a matrix" << endl;
cout << "Number of Lines : ";
int numberOfLines;
cin >> numberOfLines;
cout << "Number of Columns :";
int numberOfColumns;
cin >> numberOfColumns;
vector<vector<double> > matrix;
int i(0);
int j(0);
while(i<=numberOfLines && j<=numberOfColumns)
{
cout << "[" << i+1 << "," << j+1 << "] =" ;
int value;
cin >> value;
matrix[i].push_back(value);
cout << endl ;
j++;
if(j==numberOfColumns)
{
j=1;
i++;
}
}
return matrix;
}
Declare the matrix like this:
vector<vector<double> > matrix (y, vector<double> (x, 0));
Now you have an y*x matrix. If you want to use push_back you have to declare the x-vector when starting on a new row.
When you do vector<vector<double> > matrix; you initialize a vector of vectors, both of size 0 (that's the default), so when you do matrix[i].push_back(value) even when i==0 you access memory which you hasn't been allocated. it's better if you do pre-allocate memory like this:
vector<vector<double> > matrix(numberOfLines,vector<double>(numberOfColumns));
And then you don't need to push back or anything, you just do matrix[i][j]=whatever.
In C++ you can use the vector constructor to automatically define the size:
vector<vector<double> > matrix(numberOfLines, vector<double>(numberOfColumns, 0));
With vectors, for loops are better than while loops because the size is always known. I suggest you iterate over the vector rows and columns with these (and remove your push_back statements.)
you need to do something like:
matrix.resize( ... );
.
.
.
matrix[i].push_back( ... );
The problem here is that you don't have a two dimensional vector. You have a vector, of vectors, of doubles. You need to put some vectors in the first vector, calling resize() as above is one way. You could also pass an initial size to the constructor, you could push the vectors on one by one - though that could carry performance issues.