Is this code right? My IT teacher says it's wrong - c++

Take a string from user then change the last letter to upper and write the 2nd letter and 4th letter from the string.
Generate 10 random integers from <-10,5>. Print these numbers. To the even numbers, add 100 and print them again.
I wrote this code; is it right?
#include <iostream>
#include <string>
#include<time.h>
#include <array>
using namespace std;
int main()
{
string a;
cin >> a;
cout << a << endl;
a.back() = toupper(a.back());
cout << a<<endl;
cout << "2 letter is "<<a.at(2) << endl;
cout <<" 4 letter is "<< a.at(4) << endl;
srand(unsigned(time(0)));
int tab[10];
for (int i = 0; i < 10; i++)
{
int z = (rand() % 16) - 10;
tab[i] = z;
}
for (int i = 0; i < 10; i++)
{
cout << tab[i] << endl;
}
cout << "===============" << endl;
for (int i = 0; i < 10; i++)
{
if (tab[i] % 2 == 0)
{
tab[i] += 100;
}
}
for (int i = 0; i < 10; i++)
{
cout << tab[i] << endl;
}
}

This is wrong
cout << "2 letter is "<< a.at(2) << endl;
The second letter in a string is a.at(1) because in C++ array indexes start at zero, but in English we start counting at one.

Your code is wrong! The following two lines, in particular:
cout << "2 letter is "<<a.at(2) << endl;
cout <<" 4 letter is "<< a.at(4) << endl;
Why? Because array indexes (and string positions) begin at zero in C++, so the first letter will be a.at(0) and, thus, the second letter will be a.at(1).
So, you should have this:
cout << "2 letter is " << a.at(1) << endl;
cout <<" 4 letter is " << a.at(3) << endl;
Also, for better overall coding-style guidelines, please read this: Why is "using namespace std;" considered bad practice?

for (int i = 0; i < 10; i++)
{
if (tab[i] % 2 == 0)
{
tab[i] += 100;
}
}
for (int i = 0; i < 10; i++)
{
cout << tab[i] << endl;
}
I believe this is where your problem lies. Your teacher said if they are even, print them again - and by that I think he/she means to print just the even numbers again (I am taking a liberal use of language here), so change the above to:
for (int i = 0; i < 10; i++)
{
if (tab[i] % 2 == 0)
{
tab[i] += 100;
cout << tab[i] << endl;
}
}

There are several things I would consider sub-optimal or incorrect if I was your instructor:
Accessing at(2) and at(4) will give back 3rd and 5th characters, not 2nd and 4th. Also, when you say "2 letter" and "4 letter", do you (or your instructor) mean letter #2 and letter #4, or first 2 letters and then first 4 letters. There seems to be something lost in translation here, as was already commented.
You do not check for string length before accessing characters in it. You access a.back() without checking that the string is not empty, and at(2) and at(4) without checking it is of sufficient length. This makes it very easy to crash your program, by providing insufficient characters as input (you did not provide any input assumptions, so this may be OK with your instructor).
For the second part of the program - the one with the random numbers - you are using 4 loops, when 2 would have been perfectly sufficient: you could generate the numbers, and print them in one loop. Then, you could add 100 to the even ones, and print again, in a second loop.
Finally, when writing code, be consistent with your indentation. The first part of you code is indented by 4 characters, and the second, by 8. Only indent within blocks, and keep indentation uniform for the entire block.

Related

“invalid operands to binary expression” error?

C++ newbie here, basically I am trying to print out a list of random characters based off user input. I know my error involves the "m <= num" statement, but not sure how to go about fixing that. Or am I going about this completely wrong? Explanations are greatly appreciated!
Note My logic is that 'm' is the list of characters so for 'num' I am trying to print out a list of characters based on the value of 'num'. For example if the user selects 2 for list and 5 for elements I would want the output to be....
list 1: "wtwef"
list 2: "wopoe"
#include <iostream>
#include <string>
#include <vector>
#include <list>
using namespace std;
int main() {
srand (time(NULL));
int L;
string alpha = "abcdefghijklmnopqrstuvwxyz";
list<string> m;
cout << "Give the number of lists: ";
cin >> L;
for (int i = 1; i <= L; i++){
cout << "Give the number of elements for list " << L << " : "<< endl;
int num; cin >> num;
for (int k = 0; m <= num; k++){
cout << alpha[rand() %100] << " " << endl;
m.push_back(alpha[rand() %100]);
}
cout << "Give a word: " << endl;
cin >> s;
}
The issue with the expression "m <= num" is because m is of type std::list while num is of type int. It doesn't make sense to compare a list with an int, which is the real world equivalent of comparing a shopping list with 4, it just doesn't mean anything. You may have intended "k <= num".
The line cin >> s is also an error, s isn't defined.
You also have a line m.push_back(alpha[rand() % 100]); that will be an error, m has a type of string while the using the [] operator on alpha will return a character, see code below for solution.
You use the modulus operator in two places, where you mod by 100. If you want a character at a random index you should, in this case, do alpha.substr((double) rand() / RAND_MAX * alpha.length(), 1). Note that RAND_MAX is a constant that should be predefined, you shouldn't need to set it. I have a feeling what you're trying to accomplish in the inner loop looks like:
string randomCharacter = alpha.substr((double) rand() / RAND_MAX * alpha.length(), 1)
cout << randomCharacter << " " << endl;
m.push_back(randomCharacter);
You are also missing a left brace in the code somewhere (may be due to copy-paste) which would be another reason it wouldn't compile.
If what you want is to be able to type in the terminal how many sequences of random characters followed by how many characters are in each sequence, you would want to re-write the inner loop to look like:
string randomCharacters = "";
for (int k = 0; k <= num; k++){
string randomLetter = alpha.substr((double) rand() / RAND_MAX * alpha.length(), 1);
cout << randomLetter << " " << endl;
randomCharacters += randomLetter;
}
m.push_back(randomCharacters);
This will fill the list with strings filled with random characters from array alpha, which you can use later. You can remove the cout if you don't want to see all the characters printed to the terminal as they are randomly chosen.
After your edit to the question:
The solution should look like:
srand(time(NULL));
int L;
string alpha = "abcdefghijklmnopqrstuvwxyz";
vector<string> m;
cout << "Give the number of lists: ";
cin >> L;
cout << "Give the number of elements for the lists: ";
int num;
cin >> num;
cout << endl;
for (int i = 1; i <= L; i++){
string randomCharacters = "";
for (int k = 0; k < num; k++){
string randomLetter = alpha.substr((double) rand() / RAND_MAX * alpha.length(), 1);
randomCharacters += randomLetter;
}
m.push_back(randomCharacters);
}
for(int i = 0; i < m.size(); i++)
{
cout << "list" << (i+1)<< ": " << m[i] << endl;
}
Note, this solution switched list for vector as it's simpler in this case.

Iterating through array using loop in c++ and program says "exit status -1"?

So I am trying to get comfortable with arrays for my HW assignments. I have two loops. First loop iterates through the sequence, that's good and well I think I dont know. Then the second loop is supposed to display all inputs the user inputted depending on how big size_of_array is (in this case, it's 5, so that should be 5 cars the user enters).
When i run it, the first part works just fine in terms of taking input, but the second part F R E A K S out and gives me "exit status -1" wtf?!?!?!??!
Appreciate the help:
#include <iostream>
using namespace std;
int main()
{
int size_of_array = 5;
string ideal_cars[size_of_array];
int count;
for (count = 1; count <= size_of_array; count++)
{
cout << "Enter car number " << count << "." << "\n";
cin >> ideal_cars[count];
}
for (count = 0; count <= size_of_array; count++)
{
cout << "You entered " << ideal_cars[count] << ".";
}
}
The first index of an array is 0, so when size_of_array is 5, the possible indices are 0, 1, 2, 3, 4.
The 1st element is ideal_cars[0].
The 2nd element is ideal_cars[1].
The 3rd element is ideal_cars[2].
The 4th element is ideal_cars[3].
The 5th element is ideal_cars[4].
ideal_cars[5] is out of range and not allowed. For a graphical illustration, see http://www.cplusplus.com/doc/tutorial/arrays.
So in your for loop you need to make sure count is less and not equal to size_of_array:
for (count = 0; count < size_of_array; count++)
Example:
#include <iostream>
using namespace std;
int main()
{
int size_of_array = 5;
string ideal_cars[size_of_array];
int count;
for (count = 0; count < size_of_array; count++)
{
cout << "Enter car number " << count << "." << endl;
cin >> ideal_cars[count];
}
for (count = 0; count < size_of_array; count++)
{
cout << "You entered " << ideal_cars[count] << "." << endl;
}
return 0;
}
Demo: https://ideone.com/LWbSeu.

C++ Displaying An Organized List of Words

I am making a 20 questions game in C++ and have everything working, except for the displayWords function. The code I currently have keeps breaking. Any explanation would be appreciated! Thank you!
void displayWords()
{
int x = 0;
string words[50] = {"LCHS","Shark","Pencil","Pizza","New York","Fish","Car","Ice Cream","Los Angeles","Bird","Basketball","Fried Chicken",
"Dog","Tiger","Penguin","Plane","Rock","Barbecue Sauce","Mustard","Ketchup","Hot sauce","Peppers","Salt","Tacos","Shrimp","Pickels",
"Tomatos","Bannanas","Burger","Computer","Iphone","Motorcycle","Bicycle","Skateboard","Lightbulb","Golf Ball","Surfboard","Luggage",
"Rollercoaster","Cat","Lion","Cockroach","Grasshopper","Beach","Theme Park","Swimming Pool","Bowling Ally","Movie Theater","Golf Course","Shopping Mall"};
cout << "The following list of words are what the computer is capable of guessing" << endl;
cout << endl;
while(x < 50)
{
for (int y = 0; y <= 5; y++)
{
cout << words[x] << ", ";
if(x<50)
x++;
}
cout << endl;
}
}
I would like it to display the list of 50 words in an organized fashion.
By example, as:
for( int x = 0; x<sizeof(words)/sizeof(*words); x++ ) {
if( x%5==0 ) cout << endl; else cout << ", ";
cout << words[x];
}
take into account the problematic of the array's size calculation: see this link How do I find the length of an array?
If I understand correctly, you want your list displayed as 5 columns. Simplest way, use a nested for loop and proper formatting with std::setw (must #include <iomanip>):
for(size_t i = 0; i < 10; ++i)
{
for(size_t j = 0; j < 5; ++j)
{
std::cout << std::setw(20) << std::left << words[i * 5 + j];
}
std::cout << std::endl;
}
Your actual loop is incorrect, as it will lead to repetitions.
Maybe I'm not interpreting your question correctly but if you want to just print out the 50 words then you can use something like the code below. Not sure of the reason that the nested for loop iterating y was there.
Edit
void displayWords()
{
int x;
string words[50] = {"LCHS","Shark","Pencil","Pizza","New York","Fish","Car","Ice Cream","Los Angeles","Bird","Basketball","Fried Chicken",
"Dog","Tiger","Penguin","Plane","Rock","Barbecue Sauce","Mustard","Ketchup","Hot sauce","Peppers","Salt","Tacos","Shrimp","Pickels",
"Tomatos","Bannanas","Burger","Computer","Iphone","Motorcycle","Bicycle","Skateboard","Lightbulb","Golf Ball","Surfboard","Luggage",
"Rollercoaster","Cat","Lion","Cockroach","Grasshopper","Beach","Theme Park","Swimming Pool","Bowling Ally","Movie Theater","Golf Course","Shopping Mall"};
cout << "The following list of words are what the computer is capable of guessing" << endl;
cout << endl;
for(x = 0; x < words.size();x++)
{
cout << words[x]<< ", ";
}
}
Also some information on how the code is breaking, like are any errors being thrown or has debugging caused issues so far?

Pin Challenge Response Sysem

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string.h>
using namespace std;
int main()
{
char pin[6]; //character array to allow for ease of input
int randomNumbers[10]; //holding the randomized numbers that are printed back to the user
int pinStorage[5];
char pinVerify[5];
char pinReenter[6];
int result;
srand(time(0));
cout << "Enter your pin number" << endl;
cin >> pin;
for (int i = 0; i < 5; i++)
{
pinStorage[i] = pin[i] - '0';
}
for (int i = 0; i < 10; i++)
{
randomNumbers[i]= rand() % 3 + 1;
}
cout << "Pin Verify: ";
for (int b = 0; b < 5; b++)
{
for (int d = 0; d <10; d++)
{
if (pinStorage[b]== d)
{
pinVerify[b] = randomNumbers[d];
switch (pinVerify[b])
{
case 1: pinVerify[b] = '1';
break;
case 2: pinVerify[b] = '2';
break;
case 3: pinVerify[b] = '3';
}
cout << pinVerify[b] << " ";
}
}
}
cout << " " << endl;
cout << "Pin : 0 1 2 3 4 5 6 7 8 9" << endl;
cout << "Number: ";
for (int c = 0; c < 10; c++)
{
cout << randomNumbers[c] << " ";
}
cout << " " << endl;
cout << "Renter pin" << endl;
cin >> pinReenter;
for(int h = 0; h < 5; ++h)
{
int digit = pinStorage[h];
pinReenter[h] = randomNumbers[digit] + '0';
}
cout << "PV: " << pinVerify;
cout << "PR: " << pinReenter;
result = (strcmp(pinVerify, pinReenter));
switch(result)
{
case 1: cout << "You did not enter the pin correctly!" << endl;
break;
case 0: cout << "Pin Entered Correctly!" << endl;
break;
case -1: cout << "You did not enter the pin correctly!" << endl;
}
The above is my code. The objective is to be able to enter a normal 5 digit pin such as 12345. The program will then store that pin, and produce a screen like this:
Pin: 0 1 2 3 4 5 6 7 8 9
Num: 3 1 2 3 2 2 3 1 1 3
The program randomized the num part that you see and assigns it to the numbers above. That way the user reenters 12322 and the computer recognizes it as him entering the right code. The next time it where to do it, it would be rerandomized to something else. This whole project is designed to prevent shoulder surfing.
However I seem to be having a problem with my code. Almost everything is working but with the final strcmp function. Even though I have pinVerify set to 5, it still gives me 5 numbers and a ASCII character at the end, something like 21323☻. This makes it impossible to ever have pinVerify and pinReenter as equal, meaning it's impossible for the program to tell you you entered in the challenge correctly, even when you did.
Can anyone help me fix this? I've been looking and tinkering for a while and have been completely unsuccessful.
C-style strings are null-terminated. In your example, it means that, when you want to work with two strings of length 5, you should actually reserve 5+1=6 chars for each of them, and make sure that the 5-th (0-indexed) char contains a character with ASCII code 0. Otherwise, strcmp, and any other C-string function, proceeds past the end of your char[5] array until it finds a byte containing zero.

char(string) to integer

I was wondering how to compare one array into two arrays but with some rules:
In my code I need to type 8 digits to make the cycle - OK, I did it. Now I need to compare the array = m[3] to two different arrays:
first array must be with (if m[i]%2==0) ...
second array must be with (if m[i]%2!=0) ...
So if I type from keyboard those three rows in my Main array (m[3]):
12345678
12345689
12344331
After typing them, I need to set the in those two different arrays and here I think I need to make the char(string) to integer to make the check with %, or to somehow do the check only on the last digit (it will work the same way).
So here goes the next step after typing the 3 rows:
arrA=12345678
arrB=12345689 12344331
#include <iostream>
#include <conio.h>
#include <string>
#include <cstdlib>
#include <stdlib.h>
using namespace std;
int main()
{
int i,n;
char m[3];
for(i=1; i<=3; i++)
{
cout<<i<<". Fak nomer: "<<endl;
do
{
cin>>m[i];
gets(m);
}
while (strlen(m)!=7);
cout<<"As integer: "<<atoi(m);
}
}
From what I understand, you are trying to read three positive integers into an array called m, but you want to ensure the following:
all three number have eight digits
the first number (m[0]) is even
the second number (m[1]) is odd
It would be a lot easier if m can be an array of integers, then a conversion from a string to an int is not required. To read the three integers from the console, use this:
// m is now an array of integers
int m[3];
// loops from m[0] to m[2]
for(int i = 0; i < 3; i++)
{
cout<<i<<": "<<endl;
do
{
cin>>m[i];
}
while (!(m[i] >= 1e7 && m[i] < 1e8));
// m[i] must be greater than or equal to 10000000 and less than 100000000
// before continuing
}
By making m an array of integers, checking for even or odd becomes easier:
if (m[0] % 2 == 0)
cout << "m[0] is even" << endl;
if (m[1] % 2 != 0)
cout << "m[1] is odd" << endl;
not sure if i understand your problem, but why not just change
char* m[3];
to
int m[3];
you'd probably want to redo the loop
int m[3];
for(i=0; i<3; i++)
{
cout<<i+1<<". Fak nomer: "<<endl;
cin>>m[i];
while (m[i] < 1000000 || m[i] >9999999)
{
cout<<"number is less/more than 7 digits. Try again:"<<endl;
cin>>m[i];
}
cout<<"As integer: "<< m[i];
}
It is difficult to understand exactly what you're trying to achieve.
If I understand it correctly, you're trying to get 3 7-character input strings (of integers) from the user, and then check each integer of the first string in turn against the same position character in the other 2 strings?
#include <iostream>
#include <string>
int main()
{
std::string m[3];
for(int i = 0; i < 3; ++i)
{
std::cout << i + 1 << ". Fak nomer: "<< std::endl;
do
{
std::cin >> m[i];
}
while (m[i].size() != 7);
}
// we have enforced each string to be 7 characters long, check each character in turn
for(int i = 0; i < 7; ++i)
{
// get the i'th character of each string, and subtract the ascii '0' character to convert to an integer
int a1 = m[0][i] - '0';
int a2 = m[1][i] - '0';
int a3 = m[2][i] - '0';
std::cout << "checking " << a1 << " against " << a2 << " and " << a3 << std::endl;
if (a1 % a2 == 0)
std::cout << a1 << " % " << a2 << " == 0" << std::endl;
if (a1 % a3 != 0)
std::cout << a1 << " % " << a3 << " != 0" << std::endl;
}
return 0;
}