Pushing back a vector gives absurd results (C++) - c++

Hello so I've seen some other posts about it but they never seem to solve my issue, or I just can't understand it with my peanut sized brain.
If I input something, and push it back to the vector, it would always have some stupidly absurd number(s)
For those who want context or in case it's outside of what I think is the problem, here's the full code:
#include <iostream>
#include <string>
#include <array>
#include <algorithm>
#include <vector>
using namespace std;
void stringToVec(string input, vector<int> output)
{
int e = 0;
string temp;
//cout << "size: " << input.size() << '\n';
for(int i = 0; i < input.size(); i++)
{
if(input[i] != ' ')
{
temp += input[i];
}
else if(input[i] == ' ')
{
int num = stoi(temp);
output.push_back(num);
temp = ""; // clear temp
}
}
}
int main()
{
int a, b;
string numsIn1, numsIn2;
cin >> a;
cin >> ws;
getline(cin, numsIn1);
numsIn1 += ' ';
int nums1[a];
// =======================
cin >> b;
cin >> ws;
getline(cin, numsIn2);
numsIn2 += ' ';
int nums2[b];
// =======================
vector<int> output;
stringToVec(numsIn1, output);
stringToVec(numsIn2, output);
int e = 0;
for(int i = 0; i < a; i++)
{
output.push_back(nums1[i]);
}
for(int i = 0; i < b; i++)
{
output.push_back(nums2[i]);
}
sort(output.begin(), output.end());
//int dyfslashj[3] = {3, 2, 1};
for(int i = 0; i < a + b; i++)
{
cout << output[i] << ' ';
}
return 0;
}
Here's the line thats most likely to be the problem. For example if I input the number "3 4 2" the vector would be like "5234523452345 32452 34523", or some absurd value
void stringToVec(string input, vector<int> output)
{
int e = 0;
string temp;
//cout << "size: " << input.size() << '\n';
for(int i = 0; i < input.size(); i++)
{
if(input[i] != ' ')
{
temp += input[i];
}
else if(input[i] == ' ')
{
int num = stoi(temp);
output.push_back(num);
temp = ""; // clear temp
}
}
}

maybe there are something wrong with your "cin". I can see you used cin and getline. But getline will read at the first line.No matter it have been "cin".you can try to use some strings as parameter to the function to see whether it's correct or not

Related

How can I get around the use of VLAs?

I have made some code and need to make the length of an array the same as a user input:
#include <iostream>
#include <string>
using namespace std;
void abrev(string word) {
int lastChar = word.length();
if (lastChar > 10) {
cout << word[0];
cout << lastChar - 2;
cout << word[lastChar - 1] << endl;
} else {
cout << word << endl;
}
}
int main() {
int n;
cin >> n;
string words[n];
for (int i = 0; i <= n - 1; i++) {
cin >> words[i];
}
for (int i = 0; i <= n - 1; i++) {
abrev(words[i]);
}
return 0;
}
I don't really know what I could possibly do, I have no ideas. I was using a compiler that just side steps this problem, so I didn't realize it until I submitted this code to codeforces.com, in which I got these errors:
Can't compile file:
program.cpp
program.cpp(20): error C2131: expression did not evaluate to a constant
program.cpp(20): note: failure was caused by a read of a variable outside its lifetime
program.cpp(20): note: see usage of 'n'
program.cpp(23): warning C4552: '>>': operator has no effect; expected operator with side-effect
Also I don't think the last error has anything to do with it, if you could help with that to that would be awesome!
Thankful for any help!
It's mostly duplicated, to resolve the error, it's easy to fix it with std::vector
Since the function abrev doesn't change the argument, it's better to use a const reference.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void abrev(const string& word) {
int lastChar = word.length();
if (lastChar > 10) {
cout << word[0];
cout << lastChar - 2;
cout << word[lastChar - 1] << endl;
} else {
cout << word << endl;
}
}
int main() {
int n;
cin >> n;
std::vector<std::string> words(n);
for (int i = 0; i <= n - 1; i++) {
cin >> words[i];
}
for (int i = 0; i <= n - 1; i++) {
abrev(words[i]);
}
return 0;
}

How to move word in a circular motion in a string?

I have a string that contains X words (between each word there is a space) I have to move the words in a circular motion to the left according to the number that the user inserts. For example:
"hi my name is aviv and",
the user entered 2. "name is aviv and hi my" I'm looking for legality that repeats itself but I can not find.
Thanks for the guidance. Most importantly, I can not use built-in libraries
Update:
I see there are examples with libraries, I can not use any library.
So what I've done so far.
I wrote a function that gets a string and a number from the user, to move left.
Before sending the string to the function I try to calculate the number of characters I need to move.
My output is - "name is avivhi my"
Regarding the function:
When it gets a string without spaces it works great.
This is my code:
int main()
{
char str[] = "hi my name is aviv";
char str2[] = "hi my name is aviv";
int CountSpace = 0, CountWord = 0;
int Size = 18, flag = 0;
int MoveLeft, Index = 0;
for (int i = 0; str[i] != '\0'; i++)
{
if (str[i] == ' ')
{
CountSpace++;
}
}
CountWord = CountSpace + 1;//Understand how many words there are in a string.
cin >> MoveLeft;
if (MoveLeft >= CountWord)//
{
MoveLeft = (MoveLeft - ((MoveLeft / CountWord) * CountWord));//the size of movment;//To reduce the amount of moves if there is such a possibility
}
for (int i = Size - 1; i >= 0; i--)
{
if (str[i] == ' ')
{
flag++;
}
if (flag == MoveLeft)
{
Index = Size - 1 - (i + 1);//That's the amount of characters I have to move
break;
}
}
MoveLeft = Index;
//This code belongs to the function that accepts a string and the amount to move the characters
for (int i = 0; i < Size; i++)
{
if (i + MoveLeft < Size)
{
str[i] = str2[i + MoveLeft];
}
else
{
str[i] = str2[(i + MoveLeft) - Size];
}
}
cout << "Move Left: " << MoveLeft << endl << str << endl << str2 << endl;
return 0;
}
Here's a hint:
vector<string> words = Your_Code_To_Split_Input_Into_Words();
int count = words.size();
int shift = Your_Code_To_Read_Users_Input();
// print the sentence with the rotation specified by shift
for (int i = 0; i < count; i++)
{
int shifted_index = (i + shift) % count; // modulo math implements circular rotation
string spacing = (i == 0) ? "" : " "; // add a space before each word, except first word
cout << spacing << words[shifted_index];
}
cout << endl;
One possible answer, i highly recommend using vectors instead of regular arrays, it's easy and more dynamic, but i didn't use it because you said you can't use built-in libraries.
#include <iostream>
#include<string>
using namespace std;
int main() {
string a[10000];
int counter = 0;
string b = "hi my name is aviv and";
string temp = "";
int userNum = 2;
for(int i=0;i<b.length() ; i++){
if(b[i]!=' '){
temp+=b[i];
}
else if(b[i]==' ' && temp.length()){
a[counter]= temp;
temp = "";
counter++;
}
}
if(temp.length()){
a[counter] = temp;
}
for(int i=userNum;i<=counter+userNum;i++){
cout<<a[i%(counter+1)]<<endl;
}
}
If you can make use of std::rotate() from <algorithm>, this is much easy to do with that. Parse the words using std::stringstream and store to std::vector. Then apply the shif directly to the vector.
Sample Output: https://www.ideone.com/rSPhPR
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
int main()
{
std::vector<std::string> vec;
std::string str = "hi my name is aviv and";
std::string word;
std::stringstream sstr(str);
while(std::getline(sstr, word,' '))
vec.emplace_back(word);
int shift;
std::cout << "Enter the Shift: ";
std::cin >> shift;
std::rotate(vec.begin(), vec.begin() + shift, vec.end());
for(const auto& it: vec)
std::cout << it << " ";
return 0;
}
Here's a snippet :
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
#define MaxWords 10
int main()
{
stringstream ss;
ss.str("hi my name is aviv and");
string str[MaxWords];
int i;
for (i =0; std::getline(ss, str[i],' ');i++ )
{
cout << str[i] << " ";
}
int n;
cout << "\nEnter pos to split : ";
cin >> n;
for (int j = n; j <= i; j++)
{
cout << str[j] << " ";
}
for (int j = 0; j < n; j++)
{
cout << str[j] << " ";
}
cout << endl;
return 0;
}
Output:

bubble sort crashing program c++

So I've been working on a project for class and everything was going swimmingly, until I had to sort the information by last name in ascending order. To elaborate further, in my program I am supposed to take file input, apply it into whatever kind of variables I see fit, calculate their grades by comparing their answers against an answer key, and then sort the entries by last name. Without further ado here is my code! (be gentle)
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <algorithm>
const int TEST_SIZE = 10;
using namespace std;
struct StudentInfo
{
int id;
string fName;
string lName;
char testAnswers[10];
int totalPoints = 0;
int avg = 0;
char letterGrade;
};
void inputInfo(char[], StudentInfo[]);
void calcGrade(char[], StudentInfo[]);
void bubbleSort(StudentInfo[]);
void outputInfo(StudentInfo[]);
int main()
{
StudentInfo studentInfo[10];
string temp;
char answerKey[10];
inputInfo(answerKey, studentInfo);
calcGrade(answerKey, studentInfo);
bubbleSort(studentInfo);
outputInfo(studentInfo);
return 0;
}
void inputInfo(char answerKey[], StudentInfo studentInfo[])
{
cout << "Please enter the 10-question answer key: \n";
for(int i = 0; i < TEST_SIZE; i++)
{
cout << "Question " << i+1 << "\n";
cin >> answerKey[i];
}
ifstream inFile("student.txt");
for(int i = 0; i < TEST_SIZE; i++)
{
inFile >> studentInfo[i].id;
inFile >> studentInfo[i].fName;
inFile >> studentInfo[i].lName;
for(int j = 0; j < TEST_SIZE; j++){
inFile >> studentInfo[i].testAnswers[j];
}
}
}
void calcGrade(char answerKey[], StudentInfo studentInfo[])
{
for(int i = 0; i < TEST_SIZE; i++)
{
for(int j = 0; j < TEST_SIZE; j++)
{
if(studentInfo[i].testAnswers[j] == answerKey[j])
{
studentInfo[i].totalPoints += 5;
}
studentInfo[i].avg = studentInfo[i].totalPoints * 2;
if(studentInfo[i].avg >= 90)
{
studentInfo[i].letterGrade = 'A';
}
else if(studentInfo[i].avg >= 80)
{
studentInfo[i].letterGrade = 'B';
}
else if(studentInfo[i].avg >= 70)
{
studentInfo[i].letterGrade = 'C';
}
else if(studentInfo[i].avg >= 60)
{
studentInfo[i].letterGrade = 'D';
}
else
{
studentInfo[i].letterGrade = 'F';
}
}
}
}
void bubbleSort(StudentInfo studentInfo[])
{
StudentInfo temp;
int i;
int j;
for(i = 0; i < (TEST_SIZE-1); i++)
{
for(j = 0; j < TEST_SIZE; j++)
{
if(studentInfo[j].lName < studentInfo[j-1].lName)
{
temp = studentInfo[j];
studentInfo[j] = studentInfo[j-1];
studentInfo[j-1] = temp;
}
}
}
}
void outputInfo(StudentInfo studentInfo[])
{
cout << setprecision(1) << fixed;
cout << "Student ID\tStudent Name\tAnswers\tTotal Pts\tAverage\t Letter Grade" << endl;
for(int i = 0; i < TEST_SIZE; i++)
{
cout << studentInfo[i].id << "\t";
cout << studentInfo[i].lName << " ";
cout << studentInfo[i].fName << "\t";
for(int j = 0; j < TEST_SIZE; j++)
{
cout << studentInfo[i].testAnswers[j];
}
cout << "\t" << studentInfo[i].totalPoints << "\t";
cout << studentInfo[i].avg << "\t";
cout << studentInfo[i].letterGrade << "\n";
}
}
I've tried everything within my meager abilities, but my program always crashes. Assumedly during the bubble sort since it works fine without that section. If someone could enlighten me as to where I erred I would be very grateful. Sorry for any inconvenience that I've caused.
What happens here
temp = studentInfo[j];
studentInfo[j] = studentInfo[j-1];
studentInfo[j-1] = temp;
when j==0? You access out of bounds. You're better off using std::swap from <algorithm> like
std::swap(studentInfo[j], studentInfo[j+1]);
making sure that you run j until TEST_SIZE - 1. Or write the "manual" swap but with j exchanged by j+1.

Can't return dynamic string from a function

I was writing some code challenge from reddit about encrypting strings and I came up with something like this:
#include <iostream>
#include <string>
using namespace std;
string encrypt(string sentence);
int main()
{
string sentence;
int i = 0;
cout << "Welcome. Enter a sentence: ";
getline(cin, sentence);
cout << sentence << endl;
encrypt(sentence);
cout << endl << endl;
system("pause");
return 0;
}
string encrypt(string sentence)
{
int i = 0;
int x = (sentence.size());
string *encrypted_sentence = new string[sentence.size()];
int *wsk = new int[sentence.size()];
for (i = 0; i < x; i++)
{
wsk[i] = sentence[i];
}
for (i = 0; i < x; i++)
{
if (wsk[i] == ' ')
continue;
else if (islower(wsk[i]))
{
if (wsk[i] <= 99)
wsk[i] = (wsk[i] + 23);
else
wsk[i] = (wsk[i] - 3);
}
else
{
if (wsk[i] <= 67)
wsk[i] = (wsk[i] + 23);
else
wsk[i] = (wsk[i] - 3);
}
}
for (i = 0; i < x; i++)
{
//cout << static_cast <char> (wsk[i]);
encrypted_sentence[i] = wsk[i];
}
return *encrypted_sentence;
}
My problem is, that there is nothing that gets returned. After I run the program I get nothing in return. Can anybody point me in the right direction with this? What have I missed?
First main() returns an int always. void main() is not standard. Secondly:
string encrypted_sentence = new string[sentence.size()];
Will not even compile. encrypted_sentence is of type std::string but you are trying to assign to it a std::string *. Third you should avoid using using namespace std;
Update:
I believe you are trying to output the encrypted string at:
cout << endl << endl;
But all this is doing is outputting 2 newlines and flushing the output twice. If you want to display the encrypted string then you either need to capture the return of the encrypt() function and display it or encrypt() can take the string in by reference. IF you change encrypt() to take a reference then it would become:
void encrypt(string & sentence)
{
string *encrypted_sentence = new string[sentence.size()]; // get rid of this line as it is not needed.
//...
for (i = 0; i < x; i++)
{
sentence[i] = wsk[i];
}
}
And then you would output the string with:
cout << sentence << endl;
In case anyone would seek an answer to this question, I've come up with this, and I'm pretty sure it finally works how I wanted it to:
#include <iostream>
#include <string>
std::string encrypt(std::string to_encrypt);
int main()
{
std::string sentence;
std::string result;
std::cout << "Welcome. Please enter a sentence: ";
getline(std::cin, sentence);
result = encrypt(sentence);
std::cout << "Result: " << result << std::endl;
system("pause");
return 0;
}
std::string encrypt(std::string to_encrypt)
{
int i = 0;
int x = (to_encrypt.size());
std::cout << std::endl << "x = " << x << std::endl;
int *temp = new int[to_encrypt.size()];
for (i = 0; i < x; i++)
{
temp[i] = to_encrypt[i];
}
for (i=0; i < x; i++)
{
if (temp[i] == ' ')
continue;
else if (islower(temp[i]))
{
if (temp[i] <= 99)
temp[i] = temp[i] + 23;
else
temp[i] = temp[i] - 3;
}
else
{
if (temp[i] <= 67)
temp[i] = temp[i] + 23;
else
temp[i] = temp[i] - 3;
}
}
std::string encrypted;
for (i = 0; i < x; i++)
{
encrypted += (static_cast <char> (temp[i]));
}
return encrypted;
}
The code is obviously wrong. string *encrypted_sentence = new string[sentence.size()]; allocates an ARRAY of strings! Not a single string. Judging from that, you can see how your code is wrong.

Using strtol to get long double in c++

I am trying to get the long double out of an array.
long double num;
char * pEnd;
char line[] = {5,0,2,5,2,2,5,4,5,.,5,6,6};
num = strtold(line1, &pEnd);
For some reason the num i am getting is rounded to 502522545.6
I am quite new to C++ so is there something i am doing wrong ? What needs to be done to get the entire number in the num instead of the rounded up?
Thank you for the help !!!
Sorry that's my first post here =)
So the entire program code is as following :
class Number
{
private:
long double num ;
char line[19], line2[19];
int i, k;
public:
Number()
{}
void getData()
{
i = 0;
char ch= 'a';
cout << "\nPlease provide me with the number: ";
while ((ch = _getche()) != '\r')
{
line[i] = ch;
line2[i] = ch;
i++;
}
}
void printData() const
{
cout << endl;
cout << "Printing like an Array: ";
for (int j = 0; j < i; j++)
{
cout << line[j];
}
cout << "\nModified Array is: ";
for (int j = 0; j < (i-k); j++)
{
cout << line2[j];
}
cout << "\nTHe long Double is: " << num;
}
void getLong()
{
char * pEnd;
k = 1;
for (int j = 0; j < i; j++)
{
if (line2[j+k] == ',')
{
k++;
line2[j] = line2[j + k];
}
line2[j] = line2[j + k];
}
line2[i -k] = line2[19];
num = strtold(line2, &pEnd);
}
};
int main()
{
Number num;
char ch = 'a';
while (ch != 'n')
{
num.getData();
num.getLong();
num.printData();
cout << "\nWould you like to enter another number ? (y/n)";
cin >> ch;
}
return 0;
}
The idea is that the number entered is in the following format ($50,555,355.67) or any other number. The program then removes all signs apart of numbers and "."
Then i tried to get the long double num out of an array.
If you run the program you always get the rounded number from num.
The C++ way of doing this is pretty simple:
#include <sstream>
#include <iostream>
#include <iomanip>
int main() {
const std::string line = "502522545.566";
long double num;
std::istringstream s(line);
s >> num;
std::cout << std::fixed << std::setprecision(1) << num << std::endl;
}
Using modern C++ you can simply do:
auto line = "502522545.566"s;
auto num = std::stold(line);
Live example
Theres probably a more C++ way, but sscanf will work:
const char *str = "3.1459";
long double f;
sscanf(str, "%Lf", &f);