How can I get around the use of VLAs? - c++

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;
}

Related

Pushing back a vector gives absurd results (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

s.erase is not working when trying to remove spaces from a string

I am trying to remove the spaces from a string to validate a Palindrome phrase. I have looked up other methods, but my professor literally copy and pasted the remove space for loop in our instructions but I can't get it to work and he says he doesn't want us going to the internet for help. I am trying to remove spaces from a phrase like "too hot to hoot" to validate it. I can get my program to work with single words like "bob", but not phrases.
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char input[100];
cout << "Please enter a word/phrase: ";
cin >> input;
for (int i = 0; i < strlen(input); i++)
{
while (s[i] == ' ')//getting "s" is undefined error
s.erase(i,1);
}
int i = 0;
int j = strlen(input)-1;
bool a = true;
for (i = 0; i < j; i++)
{
if (input[i] != input[j])
{
a = false;
}
j--;
}
if(a)
{
cout << input << " is a Valid Palindrome." << endl;
}
else
{
cout<< input << " is not a Valid Palindrome." << endl;
}
system("pause");
return 0;
}
Maybe you have not copy the result from temporary variable 's'. So, the modified codes should be:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <cstring>
using namespace std;
int main(int argc, char *argv[])
{
char input[100];
cout << "Please enter a word/phrase: ";
fgets(input, 100, stdin);
string s(input); // define a temporary variable 's'
int i = 0;
while (i < s.length())
{
if (s[i] == ' ' || s[i] == '\n')
{
s.erase(i, 1); // erase from variable 's', other then 'input'
continue;
}
i++;
}
// copy result from 's' to 'input'
sprintf(input, "%s", s.c_str());
int j = strlen(input) - 1;
bool a = true;
i = 0;
for (i = 0; i < j; i++)
{
if (input[i] != input[j])
{
a = false;
}
j--;
}
if (a)
{
cout << input << " is a Valid Palindrome." << endl;
}
else
{
cout << input << " is not a Valid Palindrome." << endl;
}
system("pause");
return 0;
}

Why is it not working?

I want to create a program that will transform the same words into one. I have a problem with code where I used "while". If I put "if" instead of "while" its working, but not as right as I want, so I need to use "while", but its not working correctly. Its compiling, but not working after inputting the string a.
#include <iostream>
using namespace std;
int main ( ) {
string a;
cout << "Введите string a: ";
getline(cin,a);
for (int i = 0; i < a.length(); i++) {
while (a[i]=a[i+1]) {
for (int z = i; z < a.length(); z++) {
a[z]=a[z+1];
}
}
}
cout << endl << a << endl;
}
while (a[i]=a[i+1]) {
you probably mean
while (a[i]==a[i+1]) {
= is assignment; == is comparison.
When compilomg, pass -Wall to get warnings about this sort of thing. (If a microsoft compiler turning warnings on may require something different; for other compilers, -Wall means "turn on warnings: all normal ones").
Even when I replaced while with if it still wasn't working as you intended. I'm more surprised that you're able to use getline without the string header. You're also assigning the previous character of string a to the next character of a.
Please try this:
#include <iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<string> dupes;
string word;
string a;
cout<<"Enter line:";
getline(cin , a);
int i = 0; //the counter
while(i <= a.length()) {
if(!isspace(a[i])) {
word += a[i];
} if(isspace(a[i])) {
bool present = (find(dupes.begin() , dupes.end() , word) != dupes.end());
if(!present) {
dupes.push_back(word);
word = "";
}
word = "";
}
++i;
}
}
Try your best to avoid nesting loops into one another when possible.
I solved it!
#include <iostream>
using namespace std;
int main ( ) {
setlocale(LC_ALL,"Russian");
cout << "Сборник задач: 7.2" << "\nLv Easy" << "\nExercise #02" << endl << endl;
string a;
cout << "Enter a line: ";
getline(cin,a);
for (int i = 0; i < a.length(); i++) {
for (int j = 0; j < a.length(); j++) {
if (a[i]==a[i+1]) {
for (int z = i; z < a.length(); z++)
a[z]=a[z+1]; } } }
cout << endl << a << endl << endl;
}

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:

Controlling input in c++ and display

Question :
Your program is to use the brute-force approach in order to find the Answer to Life, the Universe, and Everything. More precisely... rewrite small numbers from input to output. Stop processing input after reading in the number 42. All numbers at input are integers of one or two digits.
Example
Input:
1
2
88
42
99
Output:
1
2
88
So that is the question, however i am still a beginner and unable to have an input tab like that. In my program, how should i modify it such that it still accepts numbers after 42, however, it does not print them? currently I am only able to terminate the input at 42.
#include <iostream>
using namespace std;
int main()
{
int A[100], num, i=0,k,count;
for(count = 0; count != 1;){
cin >> k;
if (k!=42){
A[i] = k;
i++;
}
else
count =1;
}
cout << endl;
for (count = 0; count <i; count ++){
cout << A[count] << endl;
}
}
You don't have to use array at all. You can print the value just after reading it. Exit when you read 42. This may help you.
#include <iostream>
using namespace std;
int main() {
// your code goes here
int n ;
for(; ;) {
cin >> n ;
if(n == 42) {
return 0 ;
}
cout << n << endl ;
}
return 0;
}
Pretty sure the easiest way to do so is to simply ask the user how many numbers they need to enter.
#include <iostream>
using namespace std;
int main()
{
int A[100], k, count;
cout << "How many numbers do you want to enter ? ";
cin >> count; //this is to count how many numbers the user wants to enter
for(int i(0); i < count; ++i) //put all the numbers user enters in your array
{
cin >> k;
A[i] = k;
}
cout << endl;
for (int i(0); i < count; ++i)
{
if (A[i] == 42) //if the element at index i is == 42 then stop displaying the elements
break;
else
cout << A[i] << " "; //else display the element
}
cout << endl;
return 0;
}
Else you would need to put everything in a string and parse it and i'm not quite sure how that goes as I am a beginner as well.
EDIT:
Actually here you go, I think that is correct and does exactly what you want.
Do keep in mind that if user enters p.e "1 88 442" it will output "1 88 4" because it found "42" in "442". But it should be okay because you precised input numbers should only be two digits max.
#include <iostream>
using namespace std;
int main()
{
string k;
getline(cin, k);
cout << endl;
for (unsigned int i(0); i < k.length(); ++i)
{
if (!((k[i] == '4') && (k[i+1] == '2'))) //if NOT 4 followed by 2 then display
cout << k[i];
else
break; //else gtfo
}
cout << endl;
return 0;
}
Use a bool value to control the execution of your code.
#include <iostream>
#define N_INPUT 100
#define THE_ANSWER 42
using namespace std;
int main()
{
int array[N_INPUT], i, input, count=0;
bool universeAnswered = false;
for (i = 0; i < N_INPUT; i++) {
cin >> input;
if (!universeAnswered)
{
if (input == THE_ANSWER) {
universeAnswered = true;
} else {
array[count] = input;
count++;
}
}
}
for (i = 0; i < count; i++) {
cout << array[i] << endl;
}
}
(My code was not tested)
You just have to have some state to see if you have seen 42 already, and only output if you haven't
#include <iostream>
int main()
{
bool output = true;
for (int n; std::cin >> n;)
{
output &= (n != 42);
if (output)
{
std::cout << n << std::endl;
}
}
return 0;
}