Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have written a small program that takes inputs as string which is stored in a vector.
Looping through the vector causes many empty strings being printed before actual output.
I have copied the sample lines below.
int main(){
int totalStrings;
string inputs;
vector<string> testCases(totalStrings);
cin>>totalStrings;
while(cin>>inputs)
testCases.push_back(inputs);
for(vector<string>::iterator it=testCases.begin();it!=testCases.end();++it)
printCustom(*it);
return 0;
}
I tried printing the size of the string in the printCustom function. I had hundreds of zero printed before the actual input
vector<string> testCases(totalStrings);
This line of code has two issues:
totalStrings is uninitialized and thus garbage,
vector(N) creates a vector of size N default-initialized elements, as though you had called resize rather than reserve on the vector.
What you wanted was:
std::cin >> totalStrings;
std::vector<std::string> testCases;
testCases.reserve(totalStrings);
Try the following:
cin>>totalStrings;
vector<string> testCases(totalStrings);
You have initialized totalStrings (as int) without a proper value, and you have used it to initialize the vector. This is bad times!!
Moreover, please check your indentations (a very good practice).
All the best.
To explain further (Please check the code, if required):
In your code, you wrote:
int totalStrings;
string inputs;
vector<string> testCases(totalStrings);
Point 1:
In the first line, you have not initialized totalStrings to anything. In such case depending on the computer, the vector can be initialized to any possible length. In my computer, if I do the following:
int totalStrings;
cout << totalStrings; // printing un-initialized totalStrings
string inputs;
vector<string> testCases(totalStrings);
The code prints zero, meaning totalStrings is, by magic, initialized to zero. But it may or may not be the case with your system.
Point 2:
Now when you initialize a vector with a predefined size you have provided space for values but there is no value, by default. And since you are using push_back method, you are enlarging the vector and adding to the end of the vector.
Implication of point 1 and point 2 in your final output;
Therefore, when you print (using the for loop and iterator) you will get as many zeros as the initial length (defined by totalStrings and the vector initialization); and after printing the initial vector it will print the strings that you have entered manually.
Please play with the following code to get a feeling. I hope this helps.
#include <string>
#include <vector>
#include <iostream>
using namespace std;
int main() {
int totalStrings;
cout << "Please enter initial vector length: ";
cin >> totalStrings;
vector<string > testCases(totalStrings);
string inputs;
cout << "Enter the strings into the vector [Enter -1 to finish]: ";
while(true) {
cin >> inputs;
if (inputs == "-1") { break; }
testCases.push_back(inputs);
cout << "Next? ";
}
for (vector<string>::iterator it = testCases.begin(); it != testCases.end(); ++it)
cout << ' ' << it->size();
return 0;
}
Related
My code is below. I want the user to be able to input any number of operands and then the code asks them to input an operand that number of times. I have that part figured out. How do I store each one of their operands without knowing how many they want in the first place?
for (int i = 0; i < numoperands; i++){
cout << "Input Operand: ";
cin >> ;
Do you need to have a seperate variable for each different input?
If not you can try defining an array outside the for loop then inside the for loop append to the array for every input the user have.
When you want to access the operands, just run another for loop for the length of the array and index it.
You need a bit more "building" blocks for your program to work :
loops, allow your code to run the same code multiple times (while and for loop)
stop condition, when will you stop with accepting input
conversion, from string to integer
strings, to hold input
Before you continue though I would recommend you learn a bit more C++ first. If you don't have any books this might be a good place to start: https://www.learncpp.com/
Example with explanation :
#include <iostream>
#include <string> // include standard library type for a string.
#include <vector> // a vector can hold values (or objects) and can grow at runtime
// DO NOT use : using namespace std;
// It is good to unlearn that right away https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice
int main()
{
std::string input; // a string to receive input in.
std::vector<int> values; // C++ does know about arrays, but they are fixed length,
// vector vector is allowed to grow
const std::string end_input{ "x" }; // const means you will only read from this variable
// the "x" is used to end the input
// start a do/while loop. Allows you to run the same code multiple times
do
{
// prompt the user what to do :
std::cout << "Enter a number ('"<< end_input << "' to end input) and press return : ";
// read input to the string so we can check its content
std::cin >> input;
// check input end condition
if (input != end_input)
{
int value = std::stoi(input); // stoi is a function that converts a string to an integer
values.push_back(value); // push back adds value at the end of the vector
}
} while (input != end_input); // if condition is not met, then program continues at do (and thus loops)
// the next lines output the content of the vector to show the input
std::cout << "\n"; // output a new line (avoid std::endl)
std::cout << "Your input was : \n";
bool print_comma = false;
for (int value : values) // loops over all values in the vector
{
if (print_comma) std::cout << ", ";
std::cout << value;
print_comma = true;
}
return 0;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
Using c++ 14.
I'm prompting the user for a string containing both letters and integers, and trying to "strip" the integers from the string itself via the string.erase() function.
The problem i'm facing is when there are 2 or more sequential numbers, than the function seems to erase the first but delete the latter.
Example:
input: H23ey Th2e3re St01ack O34verflow
output: H3ey There St1ack O4verflow
I can do it another way by using a new string, looping through the existing one and adding only what isalpha or isspace, but it seems messier.
code:
string digalpha {};
cout << "Enter string containing both numbers and letters: ";
getline(cin, digalpha);
for (size_t i {}; i < digalpha.size(); i++)
if (isdigit(digalpha.at(i)))
digalpha.erase(i,1);
cout << digalpha << endl;
cout << endl;
return 0;
In the first sentence you were writing that you are using C++14.
In "more modern" C++ the usage of algorithm is recommended. So normally you would not use C-Style For loops.
The standard approach that you can find everywhere, is a combination of erase with std::remove_it. You will find this construct in many many examples.
Please consider to use such a solution instead of a for loop.
You can even include the output in an algorithm using std::copy_if.
Please see:
#include <string>
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
std::string test1{ "H23ey Th2e3re St01ack O34verflow" };
std::string test2{ test1 };
// C++ standard solution for erasing stuff from a container
test1.erase(std::remove_if(test1.begin(), test1.end(), ::isdigit), test1.end());
std::cout << test1 << "\n\n";
// All in one alternative
std::copy_if(test2.begin(), test2.end(), std::ostream_iterator<char>(std::cout), [](const char c) { return 0 == std::isdigit(c); });
return 0;
}
If there's two digits next to each other, it skips the second digit. This happens because the index, i, keeps going up, even though everything got shifted over:
for (size_t i {}; i < digalpha.size(); i++)
if (isdigit(digalpha.at(i)))
digalpha.erase(i,1); //Here, i goes up anyway, skipping character after digit
To fix this, we just have to decriment i after erasing a digit:
for (size_t i {}; i < digalpha.size(); i++) {
if (isdigit(digalpha.at(i))) {
digalpha.erase(i,1);
i--;
}
}
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I'm trying to get a user-inputted string to be split up and stored in a vector character by character. However, when the string is inputted and entered, I get this error:
Debug Assertion Failed!
Program: C:\WINDOWS\SYSTEM32\MSVCP140D.dll
File: c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector
Line: 1234
Expression: vector subscript out of range
I've tried researching vectors to see if I'm implementing it correctly but from what I can see it appears I am.
Here is my code:
#include <iostream>
#include <string>
#include <cstdlib>
#include <time.h>
#include <vector>
using namespace std;
void rovarspraket(); //declaration because I like to put my functions after main()
int main() {
rovarspraket(); //function call
system("pause");
return 0;
}
void rovarspraket() { //the function
string sText; //string that will be inputted
vector<string> vText; //vector that sText will go into
cout << "Input text to be encoded to Rovarspraket: ";
cin.ignore();
getline(cin, sText); //gimme dat sText
cout << "\n\n"; //pretty formatting, just ignore
for (int i = 0; i < sText.length(); ++i) {
vText[i] = sText[i]; //slap that character into the vector
cout << vText[i] << endl; //just to test what was actually happening
}
}
Your question asks "vector of undefined size", but
std::vector<std::string> vText;
does not have an undefined size: it has a size of zero.
#include <iostream>
#include <vector>
#include <string>
int main() {
std::vector<std::string> v;
std::cout << v.size() << "\n";
}
has well defined behavior - it prints 0: http://ideone.com/JW2LDH
What is happening in your code is that you are performing accesses beyond the end of the current data:
std::vector<std::string> v;
v[0] = ""; // Undefined Behavior: v has size 0
There are several ways to add data to a vector:
std::vector::push_back
v.push_back("hello");
This grows the data size by one and default constructs the new element, then copies the argument into it.
std::vector::emplace_back (since c++11)
v.emplace_back("hello");
similar to push_back but instead of default-ctor+copy it simply in-place creates the new element.
std::vector::resize(N); // allocates and default-ctors elements
v.resize(5);
v[0] = "hello";
v[4] = "world";
v[5] = ""; // UB, beyond end of data
grows or shrinks the array size to N. In all cases of growth, it may cause a new allocation and a resulting copy of all existing elements into the new space.
To avoid this, you can use std::vector::reserve(N) to allocate space for upto N elements ahead of time - this can help the performance of push_back/emplace_back.
std::vector::insert(iterator, value);
v.insert(v.begin(), "hello"); // at front
v.insert(v.begin() + 1, "world"); // after 'hello'
std::cout << v[0] << v[1]; // "helloworld"
std::cout << v[2]; // UB, beyond end of data
Inserts elements at a given iterator position.
Sam Varshavchik said it already, I'd like to explain it a little bit more though. But basically your trying to assign the first element of a vector to something else, but the issue is that your vector is empty, so there's no element to assign! Use .push_back() to add an element to the end of the vector. So your "for" loop should look like this:
for (int i = 0; i < sText.length(); ++i) {
vText.push_back(sText[i]);
cout << vText[i] << endl;
}
When you initialize a vector, you're giving it a default space (I think a space of 8 objects were reserved).
If you pass a string short enough nothing bad might not happen, but if the string length is larger than the objects reserved in the vector, you're basically trying to assign something that exists (the char of the string) to something that doesn't exist (the space in that vector).
Some thing you can do is:
for (int i = 0; i < vText.size(); ++i) {
vText[i] = sText[i];
cout << vText[i] << endl;
} // So you never exceed vector's allocated space.
// Beware tho, that string might not be fully copied into the vector.
or (this one is the ideal)
for (int i = 0; i < sText.length(); ++i) {
vText.push_back(sText[i]);
cout << vText[i] << endl;
}
You can also initialize the vector with a huge gap of space, but it is a waste of resources:
vector<string> vText(200) // You'd have space for 200 strings of chars ("h" for example)
Vectors in STL are object representing a kind of "dynamic array". Thus, simply initialized, they do not reserve any memory for its data. If you know the size in advance (but for a reason, you do not want to use an array), you can first initialize the vector with:
std::vector<std::string> vect;
Then call reserve() on it to reserve a certain amount of element :
vect.reserve(4); // Reserve 4 "memory space" for elements
Don't forget that the only portable way to access the elements of the vector is to use an iterator (easy to do with the auto keyword in C++11), such as:
for (auto iter = vect.begin(); iter != vect.end(); iter++) {
*iter = valueToAssignToArray;
}
Otherwise, as suggested by others, you can simply use the push_back method to call the copy-constructor of the object you want to add to the vector (in this case, the copy-constructor of string, which means the string gets copied to the vector) or the emplace_back method which calls to constructor of the object directly (no need to initialize the object before adding it to the vector).
I have been fighting with this for awhile. I am trying to create a score results from 2 vectors, 1 vector being the actual answer and the other being the entered answer.
Essentially comparing:
for (i=1;i<=totalQ;i++){
cout<<"Enter question answer: ";
cin>>inputQ;
questions.push_back(inputQ);
}
to this:
for (i=1;i<=totalQ;i++){
cout<<"Enter your answer: ";
cin>>studentA;
answers.push_back(studentA);
}
I cant quite figure out how to compare the elements with each other to return how many are the same (correct answers).
initially i tried without using the second vector, and comparing the string from the second input to the questions vector by doing this:
for (i=1;i<=totalQ;i++){
cout<<"Enter your answer: ";
cin>>studentA;
if(studentA == questions[i]){
score=score+1}
}
but the compare statement kept causing the program to crash. After researching a bit i came to the conclusion that I wouldnt be able to compare the vector using [] so i decided to create a vector to compare the 2... which hasnt panned out.
How can i compare the 2 vectors to provide the amount of matching elements and indexes, or how could i compare an input to a vector element.
Both vectors are string vectors, and studentA was a string variable.
You could do it like this
#include <vector>
#include <iostream>
#include <string>
//#include <cstring>
using namespace std;
int main(int, char**)
{
int i;
int score = 0;
int totalQ = 3;
vector<string> questions;
vector<string> answers;
for (i=0;i<totalQ;i++)
{
string inputQ;
cout<<"Enter question answer: ";
cin>>inputQ;
questions.push_back(inputQ);
}
for (i=0;i<totalQ;i++)
{
string studentA;
cout<<"Enter your answer: ";
cin>>studentA;
answers.push_back(studentA);
}
for (i=0;i<totalQ;i++)
{
//if(strcmp(answers[i].c_str(), questions[i].c_str()) == 0)
if(answers[i].compare(questions[i]) == 0)
{
score++;
}
}
cout << "You got " << score<< " correct" << endl;
}
I've assumed that you store your answers as strings.
The things you need to remember are
To start your indexes from 0, this is how they are accessed in the vector using operator []. You wont need the <= in your loop and it wont crash as you wont overrun your vector by one.
To compare the strings in a loop you can use either the compare method of the string or good old fashioned strcmp.
use the std::find function, for example, assuming answers is the vector of correct answer, and answer is the entered answer:
if( std::find(answers.begin(), answers.end(), answer) != answers.end() ) {
score+=1;
}
by the way, your program crashes because your index starts from 1 and ends with size:
for (i=1;i<=totalQ;i++){
in C++ vector index starts from 0, so you it should be:
for (i=0;i<totalQ;i++){
Your for loop is not looping through the whole vector. Indices start at 0, and use < instead <= .in example 2 you forgot a semicolon. Use score++; instead of score = score+1. Accessing a vector of size N at index N causes your program to crash since indices start at 0
Just a heads up: My c++ programming skills and terminology is intermediate at best. So please be gentle ;).
I am working on a multi-sort algorithm for a college class. Originally, I built the program to take in an array of 20 integers, since that was as big as the .txt files were. The final lab is now asking to take in files that have 10, 100, 1000, 10000, 100000 and 1000000 different numbers. I originally used an ifstream inside a for loop to read in the ints. Now that I need to read a variable amount of ints from a file, I have run into issues with this code. I have extensively searched this site and Google to find an answer to this problem. I have tried dozens of different code snippets, to no avail. Here is the code I am currently running that works for 20 ints.
int i;
int A[20];
int length;
char unsortedFilename[200];
ifstream unsorted;
cout << "Please type the full name of the file you would like sorted.\n* ";
cin >> unsortedFilename;
unsorted.open(unsortedFilename);
length = (sizeof(A) / sizeof(*A));
for( i = 0; i < length; i++ )
{
unsorted >> A[i];
cout << A[i] << "\n";
}
insertionSort();
I do have other code mixed in there, but it's error checking, selection of duplicate number removal, etc. I would like it so that code like this would run "i" number of times, where "i" is actually the number of ints in the file. Also, as I mentioned earlier, I will need to input a file that has 1,000,000 numbers in it. I don't believe that an int array will be able to hold that many numbers. Is it going to be as easy as swapping all my ints over to longs?
Thanks for any help you could provide.
As suggested in the comments, use std::vector<int> instead of an array.
Instead of a for loop, use a while loop. Break out of the while loop when there are no numbers to read.
The while loop:
std::vector<int> A;
int item;
while ( unsorted >> item )
{
A.push_back(item);
}
You can sort the std::vector by using std::vector::iterator or simply access the data through the int* returned by A.data().
You can simply read all the numbers into a vector. Then use the vector as you would have used the array.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
int main()
{
std::string unsortedFilename;
std::cout << "Please type the full name of the file you would like sorted.\n";
std::cin >> unsortedFilename;
std::ifstream is(unsortedFilename);
std::istream_iterator<int> start(is), end;
std::vector<int> A(start, end);
std::cout << "Read " << A.size() << " numbers" << std::endl;
}
What you want is a vector.
try this,
int i;
vector<int> A;
int length;
string unsortedFilename;
ifstream unsorted;
cout << "Please type the full name of the file you would like sorted.\n* ";
cin >> unsortedFilename;
unsorted.open(unsortedFilename);
int temp;
for( i = 0; unsorted >> temp; i++ )
{
A.push_back(temp);
cout << A[i] << "\n";
}
insertionSort();
A vector is basically a dynamic array. It automatically grows as more space is needed. That way it doesn't matter if you have 10, 100, or even 100000 items, it'll automatically grow for you.
Also use a string for your file name, some file names are longer than 200 characters.
Good Luck!
will need to input a file that has 1,000,000 numbers in it. I don't believe that an int array will be able to hold that many numbers.
Sure it can. 1 Million ints is ~4Mb of memory, which is a trivial amount. You can even declare it static just as you do now int A[1000000];.
But real problem is that you're assuming a fixed length in your code, rather than determine the length from the input. I guess this is what your assignment is trying to teach you, so I won't show you the solution. But consider using ifstream::eof and make your sort accept the length as an argument...