I'm trying to take user inputted notes and store them in an array. The validation works fine but when I input the last value in the loop I get:
Debug Assertion Failed!
Expression: "(_Ptr_user & (_BIG_ALLOCATION_ALIGNMENT - 1))==0"&&0
An invalid parameter was passed to a function that considers invalid parameters fatal.
I'm struggling to understand where the issue is and how I can fix it.
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
typedef string noteName;
noteName getNoteName(int i)
{
bool flag = true;
noteName Namein;
do
{
cout << "Please enter note name no. " << i + 1 << ": ";
cin >> Namein;
cout << "------------------------------------\n";
if (Namein.length() > 3 || Namein.length() < 2)
{
cout << "Sorry, a note name must be 2 or 3 characters long. Please try again.\n";
flag = false;
}
else if (Namein.length() == 3 && Namein[1] != '#')
{
cout << "Sorry, the second character of a sharp note name must be #. Please try again.\n";
flag = false;
}
else if ((Namein[0] < 'a' || Namein[0] > 'g') && (Namein[0] < 'A' || Namein[0] > 'G'))
{
cout << "Sorry, the first character of a note name must be a letter between A and G. Please try again.\n";
flag = false;
}
else if (isdigit(Namein.back()) == false)
{
cout << "Sorry, the last character of a note name must be a number. Please try again.\n";
flag = false;
}
else
{
flag = true;
}
} while (flag == false);
return Namein;
}
int main()
{
const int numNotes = 4;
noteName NoteNames[numNotes];
cout << "Hello\n";
for (int i = 0; i <= numNotes; i++)
{
NoteNames[i] = getNoteName(i);
}
cout << "Thank you, the note names and lengths you entered were: \n\n";
for (int i = 0; i <= numNotes; i++)
{
cout << i << ". " << NoteNames[i] << "\n";
}
cout << "Done!";
return 0;
}
I want to say it's something to do with getNoteName() having a string return type as I haven't had this issue with any of my other functions that return int.
noteName NoteNames[numNotes]; defines an array where NoteNames[numNotes - 1] is the largest element you can access.
You go one further than this. The behaviour on doing that is undefined which is manifesting itself as the crash that you observe.
Replace your loop limits with for (int i = 0; i < numNotes; i++), or similar.
(You also have your CamelCase conventions for class names and variable names switch round from what's normal, which makes your code confusing to read.)
(I'd also rather see constexpr int numNotes = 4;: Google that for more details.)
Related
I'm new to C++. I have errors. But, i dont know how to fix it. Could anyone please help me? Thank you.
P - Print numbers
A - Add a number
M - Display mean of the numbers
S - Display the smallest number
L - Display the largest number
Q - Quit
Errors : expected unqualified id before return 0
error : expected ';' before {}
#include <iostream>
#include <vector>
using namespace std;
int main(){
char input {};
vector <double> numbers {};
int number{};
int sum{};
int min_number{};
int max_number{};
bool condition {true};
cout << "Enter a command" << endl;
cin >> input;
if(numbers.size() > 0){
while(condition){
if (input == 'P' || input == 'p'){
for(auto x: numbers)
cout << x << endl;
}
else if(input == 'A' || input == 'a'){
cout << "Enter a number";
cin >> number;
numbers.push_back(number);
}
else if(input == 'M' || input == 'm'){
for(auto x : numbers)
sum += x;
cout << sum / numbers.size() << endl;
}
else if(input =='S' || input == 's'){
for(size_t i {0}; i < numbers.size(); ++i)
if(numbers.at(i) < min_number)
min_number =numbers.at(i);
}
else if(input =='L' || input == 'l'){
for(size_t i {0}; i < numbers.size(); ++i)
if(numbers.at(i) > max_number)
max_number =numbers.at(i);
}
else if(input =='Q' || input == 'q'){
condition {false};
}
}
cout << "[] - list is empty, unable to calculate" << endl;
}
return 0;
}
In your section dealing with Q/q, the statement:
condition {false};
is not a valid form of assignment, you should instead use:
condition = false;
The braces are fine for initialisation, but that's not what you're trying to do on that line.
As an aside, this line:
if(numbers.size() > 0){
seems a little strange. Since you initialise the list to empty, the main loop will never start (because it's inside the if block) even though you have already asked the user for input.
That's a runtime error rather than a syntax error but you'll still need to fix it at some point.
I suspect that particular should should be done only as part of the calculation of the mean, so as to avoid dividing by zero.
I have written this for you. Since, you're a learner, I think that you should be practicing better things like STL functions and not using using namespace std; at top.
You may find some things new, but don't be frightened, just search them on some website like cppreference and see what that entity do and how to effectively use it.
There were many logical errors. #paxdiablo has mentioned them in his answer. I have removed every of them and this code works.
#include <algorithm>
#include <cctype>
#include <iostream>
#include <vector>
int main() {
std::vector<double> numbers;
while (true) {
char input;
std::cout << "Enter a command: ";
std::cin >> input;
switch (std::toupper(input)) {
case 'P':
if (numbers.empty())
std::cerr << "The list is empty!" << std::endl;
else {
for (auto &&i : numbers)
std::cout << i << ' ';
std::cout << std::endl;
}
break;
case 'A': {
int number;
std::cout << "Enter a number: ";
std::cin >> number;
numbers.push_back(number);
break;
}
case 'M':
if (numbers.empty())
std::cerr << "The list is empty! Cannot perform the operation!!";
else {
int sum = 0;
for (auto &&i : numbers)
sum += i;
std::cout << "Mean: " << (sum / numbers.size()) << std::endl;
}
break;
case 'S':
std::cout << "Smallest Number: " << *std::min_element(numbers.begin(), numbers.end()) << std::endl;
break;
case 'L':
std::cout << "Largest Number: " << *std::max_element(numbers.begin(), numbers.end()) << std::endl;
break;
case 'Q':
return 0;
default:
std::cerr << "Unrecognised Command!!" << std::endl;
}
}
return 0;
}
Basically, this program allows a user to enter a sentence and depending on the users selection, it will show the middle character of the sentence, display it uppercase or lowercase, or backwards. Simple program, but I am new to programming so that may be the problem. I would like to figure out how to use loops instead of a ton of if statements. When I try to make some loops it breaks certain parts of the code but I am sure that is because I don't properly understand them. If you have any criticism or any advice on the code, I'd be happy to hear it. Thanks in advance!
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
int sel;
string sent;
bool validinput;
int i;
int x;
int j;
int a;
cout << "Welcome to my program. Enter a sentence and select one of the options below.\n";
cout << "Enter -999 to exit the program." << endl;
cout << "============================================================================" << endl;
cout << endl;
cout << "1. Display the middle character if there is one." << endl;
cout << "2. Convert to uppercase." << endl;
cout << "3. Convert to lowercase." << endl;
cout << "4. Display backwards." << endl;
cout << "Enter a sentence: ";
getline (cin, sent);
cout << "Selection: ";
cin >> sel;
if (sel < 1 && sel > 4)
{
cout << "Invalid input. Try again. Selection: ";
cin >> sel;
validinput = false;
}
else (sel >= 1 && sel <= 4);
{
validinput = true;
}
if (validinput == true)
{
if (sel == 1)
{
j = sent.length() / 2;
cout << "The middle character is: " << sent.at(j) << endl;
}
if (sel == 2)
{
for (int i = 0; i < sent.length(); i++)
{
if (sent.at(i) >= 'a' && sent.at(i) <= 'z')
{
sent.at(i) = sent.at(i) - 'a' + 'A';
}
}
cout << "Uppercase: " << sent << endl;
}
if (sel == 3)
{
for (int x = 0; x < sent.length(); x++)
{
if (sent.at(x) >= 'A' && sent.at(x) <= 'Z')
{
sent.at(x) = sent.at(x) - 'A' + 'a';
}
}
cout << "Lowercase: " << sent << endl;
}
if (sel == 4)
{
for (a = sent.length() - 1; a >= 0; a--)
{
cout << sent.at(a);
}
}
}
system("pause");
return 0;
}
Personally I would use the switch selection statement. I roughly did this just to explain a bit on how it can make your code more friendly and understandable.
int sel;
bool validInput = false;
switch(sel)
{
case 1:
//display middle char if there's one
case 2:
//convert to uppercase
case 3:
//convert to lowercase
case 4:
//display backwards
validInput = true;
break;
default: //if number does not meat 1, 2, 3 or 4
validInput = false;
break;
}
As you may notice, for case 1, case 2, case 3 and case 4, there's a break just to say that if the number is between 1 to 4; validInput is true.
Reference: Switch Selection Statement
i suggest using a switch. It will organize your code better. From looking at your code you seem to have used for and if wisely. But I suggest the if statements checking for the input be replaced with switch.
From what I am reading from the book and from prior examples that I have been doing from the book this is what I have come up with. I appreciate the extra advice but I am trying to learn what the chapter is trying to show me so I can move on and learn the basics before I try code I have never seen before. I want the user to type 0 to end the loop but for some reason the loop keeps going? I think I may be missing something that is preventing it from stopping.
// Ex4_08.cpp
// Initializing pointers with strings
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main()
{
bool keepgoing = true;
int answer;
while (keepgoing = true)
{
const char* pstr[]{ "Aa", // Initializing a pointer array
"Bb",
"Cc",
"Dd",
"Ee",
"Ff",
"Gg",
"Hh",
"Ii",
"Jj",
"Kk",
"Ll",
"Mm",
"Oo",
"Pp",
"Qq",
"Rr",
"Ss",
"Tt",
"Uu",
"Vv",
"Ww",
"Ss",
"Yy",
"Zz",
};
const char* pstart{ "Your letter is " };
int dice{};
cout << endl
<< "Enter a number between 1 and 26 " << _countof(pstr) << ": ";
cin >> dice;
cout << endl;
if (dice >= 1 && dice <= _countof(pstr)) // Check input validity
cout << pstart << pstr[dice - 1]; // Output star name
else
cout << "Sorry, you haven't selected a correct number."; // Invalid input
cout << "Do you want to do this again? Type 0 for no: " << endl;
cin >> answer;
if (answer == 0)
{
keepgoing = false;
}
}
cout << endl;
return 0;
}
I've modified you initial code sample, using vector and string which are more C++ and easier to use:
#include <iostream>
#include <string> // for string
#include <vector> // for vector
using std::cin;
using std::cout;
using std::endl;
int main()
{
std::vector<std::string> pstr;
for (char c = 'a'; c <= 'z'; c++) // cycle over the 26 ASCII letters
{
std::string temp; //
temp += c - 32; // add capital character (e.g A)
temp += c; // add character (e.g. a)
pstr.push_back(temp); // push the new string (e.g. Aa) to the vector
}
const char* pstart{ "Your letter is " };
int dice{};
while (true)
{
cout << endl
<< "Enter a number between 1 and 26 " << pstr.size() << ": ";
cin >> dice;
if (dice == 0)
{
break; //break if the user enters 0
}
cout << endl;
if (dice >= 1 && dice <= pstr.size()) // Check input validity
cout << pstart << pstr[dice - 1]; // Output star name
else
cout << "Sorry, you haven't selected a correct number."; // Invalid input
}
cout << endl;
return 0;
}
Your code is wrong here:
while (keepgoing = true) {
...
if (answer == 0) {
keepgoing = false;
}
}
You are setting the keepgoing to false, but in the while condition you are resenting it to true. You must use the == operator (as in while(keepgoing == true)) or remove it (while(keepgoing)).
Otherwise, you may use while(true) or for (;;) and break instead of keepgoing = false:
for (;;) { // or while (true); to me, that's only a matter of preference.
...
if (answer == 0) {
break; // exit the loop
}
}
They do produce infinite loop until you enter the break condition.
Change this line:
while (keepgoing = true)
To this:
while (keepgoing == true)
The first assigns the value true to the variable keepgoing. The second checks of the value of keepgoing is true. This is a very common issue that trips of many new programmers (and occasionally an old one). :-)
I'm trying to get the program to loop again, up to three times, if the user entered a number that does not follow the function defined in the if statement. The code as is, only loops once and then exits. Did I type the for loop incorrectly or is it the if...else statement that is wrong?
#include <iostream>
using std::cout; using std::cin; using std::endl;
int main() {
cout << "Enter a positive odd number less than 40: ";
int num = 0;
for (int a = 0; a < 3; ++a);
cin >> num;
{
if (num < 40 && num > 0 && num % 2 == 1)
{
cout << "Thank you!" << endl;
}
else cout << "That is incorrect, try again!" << endl;
}
}
Did I type the for loop incorrectly or is it the if...else statement that is wrong?
Both. You should (1) remove the semicolon following the for statment; (2) move cin >> num into the for loop body; (3) add break; inside the if.
for (int a = 0; a < 3; ++a)
{
cin >> num;
if (num < 40 && num > 0 && num % 2 == 1)
{
cout << "Thank you!" << endl;
break;
}
else cout << "That is incorrect, try again!" << endl;
}
BTW1: Try to use the debugger, then you'll find out what happened in fact.
BTW2: The code will fail when cin >> num fails (e.g. user entered an invalid value), you might need to check the result of cin >> num, to process the case. Such as:
for (int a = 0; a < 3; ++a)
{
if (cin >> num)
{
if (num < 40 && num > 0 && num % 2 == 1)
{
cout << "Thank you!" << endl;
break;
}
else cout << "That is incorrect, try again!" << endl;
}
else
{
cin.clear(); // unset failbit
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // skip bad input
cout << "Wrong input, try again!" << endl;
}
}
bool isValid = false;
int num;
while(!isValid)
{
cout << "enter a positive odd integer " << endl;
cin >> num;
if(num < 40 && num > 0 && num % 2 == 1 )
{
cout << "thank you"<<endl;
isValid = true;
}
else
isValid = false;
}
Why not use some thing like this, it will loop until isValid = true which will only happen when your conditions are met?
I understand I guess, if you're doing a school project or some thing and you're forced to do it with a for loop but in general this would be a much better solution for some thing like this than a for loop!
When I run my program, I have to type how many rows do I want in my output. I have a limit from 1 to 100 rows. Each row is a task with a name of the task followed by increasing number, example: Task1:, Task2, .... When I type something into input, it must convert input string /see the code below - except the code in main();/.
My problem is that when I type first input, it should go to next task/next row/ but it doesnt. I type for example 10 strings but they dont go each to next task but they stay in one task..hope you understand now.
#include<iostream>
#include<string>
#include <ctype.h>
using namespace std;
void Convert(string input){
string output = "";
string flag = "";
bool underscore = false;
bool uppercase = false;
if ( islower(input[0]) == false){
cout << "Error!" <<endl;
return;
}
for (int i=0; i < input.size(); i++){
if ( (isalpha( input[i] ) || (input[i]) == '_') == false){
cout << "Error!" <<endl;
return;
}
if (islower(input[i])){
if (underscore){
underscore = false;
output += toupper(input[i]);
}
else
output += input[i];
}
else if (isupper(input[i])){
if (flag == "C" || uppercase){
cout << "Error!"<<endl;
return;
}
flag = "Java";
output += '_';
output += tolower(input[i]);
}
else if (input[i] == '_'){
if (flag == "Java" || underscore){
cout << "Error!" <<endl;
return;
}
flag = "C";
underscore = true;
}
}
cout << output <<endl;
}
int main(){
const int max = 100;
string input;
int pocet_r;
cout << "Zadaj pocet uloh:" << endl;
cin >> pocet_r;
if(pocet_r >= 1 && pocet_r <=100)
{
for (int i = 0; i <pocet_r; i++)
{
cout << "Uloha " << i+1 << ":" << endl;
while (cin >> input)
Convert (input);
while(input.size() > max)
cout << "slovo musi mat minimalne 1 a maximalne 100 znakov" << endl;
while(input.size() > max)
cin >> input;
while (cin >> input)
Convert(input);
}
}else{
cout << "Minimalne 1 a maximalne 100 uloh" << endl;
}
system("pause");
}
Your first if in Convert will always fail on a non-underscore and return. I don't think that's what's intended. Agree with other answer on the while cin loop. The next two whiles should be if's apparently. Step thru this code with a debugger and watch it line by line and see where it fails. You've got multiple issues here, and I'm not entirely sure what the intent is.
Edit - I didn't parse the extra parenthesis correctly. The first if in convert is actually okay.