I am writing this code to allow user to play game "Guess the number". Once the user guesses right number it asks user if he/she wants to play again. This code works for two plays and if user inputs 'y' to play again for third time, the code shows exception. The exception details are:"Unhandled exception at 0xFEFEFEFE in Ex 5.32 Guess the number.exe: 0xC00001A5: An invalid exception handler routine has been detected (parameters: 0x00000003)."
#include "stdafx.h"
#include <math.h>
#include <stdlib.h>
int a = 1;
int main(int g){
int num, guess;
char YesOrNo;
srand(g);
num = 1 + rand() % 1000;
printf("I have a number between 1 and 1000\nCan you gess my number?\n");
do{
scanf_s("%d", &guess);
if (guess == num){
printf("Excellent! You guessed the number!\n");
break;
}
else if (guess < num)
printf("Too low. Try Again.\n");
else
printf("Too High. Try Again.\n");
} while (1);
printf("Would you like to play again(y or n) ? ");
scanf_s("%s", &YesOrNo);
if (YesOrNo == 'Y' || 'y'){
a++;
main(a);
}
else{
return 0;}
}
Have your scanf_s use the correct format specificer:
scanf_s(" %c", &YesOrNo, 1); // expecting a char
instead of:
scanf_s("%s", &YesOrNo); // expecting a string
If you were using the standard scanf() using the wrong format string can lead to undefined behavior… not positive about the same for scanf_s() but it can’t be good.
Also note that scanf_s() requires a size to be passed with character or string input (hence the 1 after the YesOrNo parameter):
Unlike scanf and wscanf, scanf_s and wscanf_s require the buffer size to be specified for all input parameters of type c, C, s, S, or string control sets that are enclosed in []. The buffer size in characters is passed as an additional parameter immediately following the pointer to the buffer or variable.
Also... you tagged this with both C and C++, note that C allows you to call main() from within itself while C++ does not. Although, frankly IMO there's never a good reason to do this, and I don't see a good reason for your program to.
Related
Can someone tell me why this code is not working anymore? IT was working perfectly fine yesterday now its giving me segmentation fault(core dump)
(This is just filler text because i dont know what to explain anymore, i wrote this code some days ago and it was working perfectly however now its giving me a segmentation error core dump and i dont know the cause to that sadly, so please if anyone could help me and guide me so i can fix this error i would be greateful)
#include<iostream>
using namespace std;
int Strlen(char *s1)
/*returns the length of string in number of characters...*/
{
int length=0;
while(*s1!='\0')
{
*s1++;
length++;
}
return length;
}
int main()
{
int option=0, length=0;
cout<<" \\\\WELCOME TO THE MORSE CONVERTER//"<<endl;
cout<<"Select which type of conversion you want to do:"<<endl;
cout<<"1) Sentence to Morse Code"<<endl;
cout<<"2) Morse Code to Sentence"<<endl;
cin>>option;
switch(option)
{
case 1:
char arr[1000];
char* ptr;
cout<<"Write your sentence to convert in Morse Code\n";
cin.ignore(); //USED TO REFRESH THE CIN BUFFER (WITHOUT THIS THE GETLINE FUNCTION WILL NOT TAKE INPUT)
cin.getline(ptr,1000); //TAKING SENTENCE INPUT INTO THE CHARACTER ARRAY
cout<<"Your sentence is:\n"<<ptr<<endl;
length=Strlen(ptr); //TELLS US THE LENGTH OF THE ARRAY
for(int i=0; *(arr+i)<=length; i++) //WE TAKE i<=length BECAUSE THE STRLEN FUNCTION DOESNT COUNT \0
{
if(*(arr+i)=='A'||*(arr+i)=='a')
cout<<".-";
if(*(arr+i)=='B'||*(arr+i)=='b')
cout<<"-...";
if(*(arr+i)=='C'||*(arr+i)=='c')
cout<<"-.-.";
if(*(arr+i)=='D'||*(arr+i)=='d')
cout<<"-..";
if(*(arr+i)=='E'||*(arr+i)=='e')
cout<<".";
if(*(arr+i)=='F'||*(arr+i)=='f')
cout<<"..-.";
if(*(arr+i)=='G'||*(arr+i)=='g')
cout<<"--.";
if(*(arr+i)=='H'||*(arr+i)=='h')
cout<<"....";
if(*(arr+i)=='I'||*(arr+i)=='i')
cout<<"..";
if(*(arr+i)=='J'||*(arr+i)=='j')
cout<<".---";
if(*(arr+i)=='K'||*(arr+i)=='k')
cout<<"-.-";
if(*(arr+i)=='L'||*(arr+i)=='l')
cout<<".-..";
if(*(arr+i)=='M'||*(arr+i)=='m')
cout<<"--";
if(*(arr+i)=='N'||*(arr+i)=='n')
cout<<"-.";
if(*(arr+i)=='O'||*(arr+i)=='o')
cout<<"---";
if(*(arr+i)=='P'||*(arr+i)=='p')
cout<<".--.";
if(*(arr+i)=='Q'||*(arr+i)=='q')
cout<<"--.-";
if(*(arr+i)=='R'||*(arr+i)=='r')
cout<<".-.";
if(*(arr+i)=='S'||*(arr+i)=='s')
cout<<"...";
if(*(arr+i)=='T'||*(arr+i)=='t')
cout<<"-";
if(*(arr+i)=='U'||*(arr+i)=='u')
cout<<"..-";
if(*(arr+i)=='V'||*(arr+i)=='v')
cout<<"...-";
if(*(arr+i)=='W'||*(arr+i)=='w')
cout<<".--";
if(*(arr+i)=='X'||*(arr+i)=='x')
cout<<"-..-";
if(*(arr+i)=='Y'||*(arr+i)=='y')
cout<<"-.--";
if(*(arr+i)=='Z'||*(arr+i)=='z')
cout<<"--..";
if(*(arr+i)=='0')
cout<<"-----";
if(*(arr+i)=='1')
cout<<".----";
if(*(arr+i)=='2')
cout<<"..---";
if(*(arr+i)=='3')
cout<<"...--";
if(*(arr+i)=='4')
cout<<"....-";
if(*(arr+i)=='5')
cout<<".....";
if(*(arr+i)=='6')
cout<<"-....";
if(*(arr+i)=='7')
cout<<"--...";
if(*(arr+i)=='8')
cout<<"---..";
if(*(arr+i)=='9')
cout<<"----.";
if(*(arr+i)=='.')
cout<<".-.-.-";
if(*(arr+i)==',')
cout<<"--..--";
if(*(arr+i)=='?')
cout<<"..--..";
if(*(arr+i)=='\'')
cout<<".---.";
if(*(arr+i)=='!')
cout<<"-.-.--";
if(*(arr+i)=='/')
cout<<"-.--.";
if(*(arr+i)=='(')
cout<<"-.--.";
if(*(arr+i)==')')
cout<<"-.--.-";
if(*(arr+i)=='&')
cout<<".-...";
/*if(*(arr+i)!='A'||*(arr+i)!='a'||*(arr+i)!='B'||*(arr+i)!='b'||*(arr+i)!='C'||*(arr+i)!='c'||*(arr+i)!='D'||*(arr+i)!='d'||*(arr+i)!='E'||*(arr+i)!='e'||*(arr+i)!='F'||*(arr+i)!='f'||*(arr+i)!='G'||*(arr+i)!='g'||*(arr+i)!='H'||*(arr+i)!='h'||*(arr+i)!='I'||*(arr+i)!='i'||*(arr+i)!='J'||*(arr+i)!='j'||*(arr+i)!='K'||*(arr+i)!='k'||*(arr+i)!='L'||*(arr+i)!='l'||*(arr+i)!='M'||*(arr+i)!='m'||*(arr+i)!='N'||*(arr+i)!='n'||*(arr+i)!='O'||*(arr+i)!='o'||*(arr+i)!='P'||*(arr+i)!='p'||*(arr+i)!='Q'||*(arr+i)!='q'||*(arr+i)!='R'||*(arr+i)!='S'||*(arr+i)!='s'||*(arr+i)!='T'||*(arr+i)!='t'||*(arr+i)!='U'||*(arr+i)!='u'||*(arr+i)!='V'||*(arr+i)!='v'||*(arr+i)!='W'||*(arr+i)!='w'||*(arr+i)!='X'||*(arr+i)!='x'||*(arr+i)!='Y'||*(arr+i)!='y'||*(arr+i)!='Z'||*(arr+i)!='z'||*(arr+i)!='0'||*(arr+i)!='1'||*(arr+i)!='2'||*(arr+i)!='3'||*(arr+i)!='4'||*(arr+i)!='5'||*(arr+i)!='6'||*(arr+i)!='7'||*(arr+i)!='8'||*(arr+i)!='9'||*(arr+i)!='.'||*(arr+i)!=','||*(arr+i)!='?'||*(arr+i)!='\''||*(arr+i)!='!'||*(arr+i)!='/'||*(arr+i)!='('||*(arr+i)!=')'||*(arr+i)!='&')
cout<<" ";
*/
if(arr[i] == ' ')
cout<<" ";
}
break;
}
}
An expression in a condition in your loop
for(int i=0; *(arr+i)<=length; i++) //WE TAKE i<=length BECAUSE THE STRLEN FUNCTION DOESNT COUNT \0
*(arr+i) means a value of the array arr at offset i, or simply arr[i] that is easier on the eyes.
Now, why does arr[i] must be less than or equal to length?
Also your comment on that line makes no sense. Although the terminating 0 is not counted, you don't need to convert it to Morse code. In fact, there is no encoding for \0. So the condition should be < length.
Oh, and you don't need to invent a function for getting the length of the string, there are couple of them available.
On the other hand, you don't even need to know the length of your string, just go until you see that \0.
instead of using pointer ptr use the name of the array
My problem was to take the inputs until user input the test value 0 and the problem is to be solved only by c language, my code below becomes infinite loop by using scanf and printf but the same code if written in C++ it works fine with no problem, Can you help me with my C program what i am missing.
#include <stdio.h>
#include <stdlib.h>
int main() {
int click,test=1,count=0;
char vote;
scanf("%d",&test);
while(test){
int i=0;
for(int i=0;i<test;i++){
scanf("%c",&vote);
scanf("%d",&click);
printf("%c %d hi \n",vote,click);
}
scanf("%d",&test);
}
//printf("%d\n",count);
return 0;
}
my test case was
2
P 1
P 2
2
P 2
M -2
0
In c++ my output comes exactly like test case but in c language its TLE or output limit exceed
When dealing with C you should always check return values of runtime functions, it is the best way to avoid getting errors like the one you have.
scanf returns the number of items that it managed to parse or 0 if it failed.
personally i prefer to use fgets() to read from the stdin and then sscanf to parse the buffer, that way you have (IMHO) a better control of what comes into the program as opposed to obscure scanf formatting. it is easy to do mistakes with scanf because one tends to forget that all input is buffered and scanf reads from that buffer.
E.g. (ocular compiled only)
int click = 0;
int test = 0;
char buffer[128];
char vote = 0;
do
{
if ( fgets(buffer,sizeof(buffer),stdin) != NULL)
{
// read number of tests
if (sscanf(buffer, "%d", &test) == 1)
{
for(int i=0; i < test; ++i)
{
if (fgets(buffer, sizeof(buffer), stdin) != NULL)
{
if (sscanf( buffer, "%c %d", &vote, &click) == 2)
{
printf( "%c %d hi \n", vote, click );
}
else
{
fprintf(stderr, "Invalid format encountered\n");
}
}
}
}
}
}
while (test);
The %c conversion specifier poses problem with leading white spaces as it won't automatically skip them. Since you're receiving inputs in loop, one way to mitigate it is via putting extra space before %c.
scanf(" %c", &vote);
I have error in this place:
strcpy_s(msgToGraphics, game.board_now());
the error is:
IntelliSense: no instance of overloaded function "strcpy_s" matches the argument list argument types are: (char [1024], std::string)
and here is the game.board_now func:
string Board::board_now()
{
return _board;
}
and here is the rest of the code where I try to use the strncpy_s():
#include "Pipe.h"
#include "Board.h"
#include <iostream>
#include <thread>
using namespace std;
void main()
{
srand(time_t(NULL));
Pipe p;
bool isConnect = p.connect();
string ans;
while (!isConnect) {
cout << "cant connect to graphics" << endl;
cout << "Do you try to connect again or exit? (0-try again, 1-exit)" << endl;
cin >> ans;
if (ans == "0") {
cout << "trying connect again.." << endl;
Sleep(5000);
isConnect = p.connect();
}
else {
p.close();
return;
}
}
char msgToGraphics[1024];
// msgToGraphics should contain the board string accord the protocol
// YOUR CODE
Board game;
//strcpy_s(msgToGraphics, game.board_now()); // just example...
p.sendMessageToGraphics("rnbkqbnrpppppppp################################PPPPPPPPRBNKQNBR0"); // send the board string
// get message from graphics
string msgFromGraphics = p.getMessageFromGraphics();
while (msgFromGraphics != "quit") {
game.change_board(msgFromGraphics);
game.change_board_sq(msgFromGraphics);
strcpy_s(msgToGraphics, game.board_now()); // msgToGraphics should contain the result of the operation
// return result to graphics
p.sendMessageToGraphics(msgToGraphics);
// get message from graphics
msgFromGraphics = p.getMessageFromGraphics();
}
p.close();
}
The code is basically for a chess program and I try to recieve the chess board after the changes I made and I dont know how to format him in the strcpy_s() in order to put him in the array and send it back to the given exe.
Since C11 strcpy_s is
1) `char *strcpy( char *dest, const char *src );`
2) errno_t strcpy_s(char *restrict dest, rsize_t destsz, const char *restrict src);
strcpy_s is Same as (1),
except that it may clobber the rest of the destination array with unspecified values and that the following errors are detected at runtime and call the currently installed constraint handler function:
src or dest is a null pointer
destsz is zero or greater than RSIZE_MAX
destsz is less or equal strnlen_s(src, destsz); in other words, truncation would occur
overlap would occur between the source and the destination strings
The behavior is undefined if the size of the character array pointed to by dest <= strnlen_s(src, destsz) < destsz; in other words, an erroneous value of destsz does not expose the impending buffer overflow.
As all bounds-checked functions, strcpy_s is only guaranteed to be available if __STDC_LIB_EXT1__ is defined by the implementation and if the user defines __STDC_WANT_LIB_EXT1__ to the integer constant 1 before including string.h.
Refer the page for more information http://en.cppreference.com/w/c/string/byte/strcpy
The simplest solution would be to make msgToGraphics a std::string too, and then instead of using the C function strcpy_s, just assign to it to do the same thing:
msgToGraphics = game.board_now();
If you need to get a non-const char* to the underlying array, you can do it like this (with the usual caveats):
p.sendMessageToGraphics(&msgToGraphics[0]);
But really you should change the interface to not rely on a char array being passed in. (Hint: use std::string instead.)
I'm working on a project where I need to check for the correct input (n), I currently have a bit of code which won't allow string to be entered as it will ask again for a correct amount. I'm having trouble writing a code that won't allow float numbers to get through as it currently just ignores the float part of the input. I'm sorry if this is a simple question, but I haven't found a way to get around this yet.
for(int i=0; i<1; ++i)
{
string b1;
int e;
do
{
getline(cin,b1);
e=atoi(b1.c_str());
}
while(e==0 && b1!="0");
n=e; // where n is the user input
}
Assuming you consider anything with decimal point ('.') or using scientific notation with a negative exponent as a non-acceptable floating point number, just check if the entered string contains one of those:
std::string::iterator it;
if (b1.end() != std::find(b1.begin(), b1.end(), '.')
|| (b1.end() != (it = std::find_if(b1.begin(), b1.end(),
[](char c){ return c == 'e' || c == 'E'; })
&& it + 1 != b1.end()
&& '-' == it[1])) {
// deal with the string being a floating point number with a fractional part
}
Note, that this will consider, e.g., "10e-1" to be a bad value although it is actually just a fancy spelling of "1".
If you enter a float value then it will have a decimal point (.). As your input is a string hence you can do the following check :-
do
{
getline(cin,b1);
if(bi.find(".")!=b1.npos); // search if a decimal point is present or not
cout<<"wrong input";
else
e = stoi(b1); // stoi works similar to atoi but on strings
}
First thing you want to do is not repeat the code over and over ever time you want to read an integer. Make a function:
int getInt(std::istream & in)
This will take any input stream, cin, a file, a std::stringstream, whatever. Next we set up a few local variables we need.
{
std::string b1;
int e;
Now we build the input loop
while (std::getline(in, b1))
This will loop until the input stream fails. If it never fails and the user can't get their act togehter, we'll be here for a long long time. With Gilligan. The Skipper too. Maybe we can bum some money off of Mr. Howell for start-up seed capital, eh?
{
size_t pos;
Catch any exceptions thrown by the string -to-int conversion
try
{
Convert to int. pos will be updated with the character that ended the conversion. If it is not the end of the string, the string does not contain an int. If it does contain an int, we exit the function and return the int.
e = std::stoi(b1, &pos);
if (pos == b1.length())
{
return e;
}
}
We don't really need to do anything in the catch block. You could output a message to instruct or mock the user if you wish.
catch (...)
{
}
}
If we got here, the IO stream failed and we need to let folks know. Throw an exception.
// IO failure. throw exception
}
Usage is simple:
int value = getInt(cin);
You may wish to wrap the call in an try-catch block to catch the IO failure exception. cin's failure cases are pretty weird and usually fatal, though.
When calling getInt on a file you will want to handle things more carefully because end of file is a common occurrence.
All together without the running commentary:
int getInt(std::istream & in)
{
std::string b1;
int e;
while (std::getline(in, b1))
{
size_t pos;
try
{
e = std::stoi(b1, &pos);
if (pos == b1.length())
{
return e;
}
}
catch (...)
{
}
}
// IO failure. throw exception
}
You can use std::stringstream for this purpose :-
for(int i=0; i<1; ++i)
{
string b1;
char c=' ';
int e=0, check=0;
do
{
getline (cin, b1);
stringstream ss(b1);
ss >> check;
if(ss>>c)
cout << "bad input";
else
e=check;
}
while(e==0 && b1!="0");
n=e;
}
I am writing the hangman game in C++ and I was wondering how I can make sure that the word that my first user inputs just contains alphabetic characters, nothing else. I have to prompt the user to enter a new word when the word that they have already entered is not valid.
there are functions I use to do that but for some my check boundary function does not work properly. Please help, I have no idea how to fix it. In my first function I ask the user's input but and then I use another function to error check this word.
word1 is the array that has stored my first word, and I assume that the letters are all in lower case for now . so I use the ASCII value of the characters to make sure that it is within the boundary. but say if I enter 45 it does ask me to reenter the word but the second word will be accepted no matter what it is . it could be |*%^% it accepts it anyway.
void CheckBound (char word1[], int SIZE1)
{
int i;
int w1[SIZE4];
int found;
for (i=0;i<strlen(word1);i++)
{
w1[i]=(int)word1[i];
if (w1[i] >= 97 && w1[i] <= 122)
found=1;
else
{
printf("Please re-enter your word: ");
fgets(word1, SIZE1, stdin);
word1[strlen(word1)-1]='\0';
printf("%s \n", word1);
}
}
return;
}
When you detect a non-alphanumeric character, you are still in the first loop iterating over each character of word1. Once the user has entered a new word, the loop continue with i!=0, which is of course incorrect.
Try this instead:
oid CheckBound (char word1[], int SIZE1)
{
int i;
bool ok = false;
while(!ok)
{
ok = true;
for (i=0;i<strlen(word1);i++)
{
int c = word1[i];
if (c < 97 || c > 122)
{
ok = false;
break;
}
}
if(!ok)
{
printf("Please re-enter your word: ");
fgets(word1, SIZE1, stdin);
word1[strlen(word1)-1]='\0';
printf("%s \n", word1);
}
}
}
By the way, this is C, not C++.
typical C++ would use:
std::string instead of char array/char pointers for storing strings
std::vector, std::array for arrays (instead of plain C arrays)
streams for printing and inputting text