scanf is skipped - c++

I have the following code and I have defined the functions that I am calling here, the problem here is : I run the code
input: 1
input: 2
input: 2
input: 6
input: 5 6 // for the scanf associated with i=6;
after this I get the output on the screen as
enter ur choice and then it exits out of the program ... its like the scanf gets the value from somewhere but I dunno from where I also tried fflush(stdin) doesnt seem to work can any one please help
int main()
{
int i,*j,k,pos,val;
Element *stacka = new Element;
stacka =NULL;
while(i!=5)
{
printf("Enter ur choice \n");
fflush(stdin);
scanf("%d",&i);
if(i==1)
{
if(createStack(&stacka))
{
printf("yes");
}
}
if(i==2)
{
k=2;
if(push(&stacka,&j))
{
printf("yes");
}
}
if(i==3)
{
if(pop(&stacka,&k))
{
printf("yes %d",k);
}
}
if(i==4)
{
if(emptyStack(&stacka))
{
printf("yes");
}
}
if(i==6)
{
scanf("%d,%d",&pos,&val);
fflush(stdin);
insert_at_pos(pos,val,&stacka);
}
}
return 0;
}

Try inserting a space before %d:
scanf(" %d,%d",&pos,&val);
This will eat any leading whitespace that might be in the input buffer, e.g., the newline from the earlier entry of i.
Also, initialize i before the loop.

Related

Is there a way to stop the loop repeating more than once when running

I want to build a simple questionnaire program. When i run the code it repeats the statement twice when i want it to run only once and not repeat the cout statements. This only happens when i use strings and not characters. Sorry for the clumsy writing.[enter image description here][1]
The code is below:
#include<iostream>
#include<string>
using namespace std;
bool N='n';
bool Y='y';
bool YES="yes";
bool NO="no";
int main(){
char response, response2, response3;
string response_1, response_2, response_3;
cout<<"Hello would you like to answer a few questions?"<<endl<<"Please input y or n"<<endl;
cin>>response;
{ do{
if((response_1=="yes")||(response=='y')){
cout<<"please continue:"<<endl;
break;}
else if((response_1=="no")||(response=='n')){
cout<<"Please exit the program then:"<<endl;
}
else{
cout<<"Wrong input";
}
}
while((response_1!="yes")||(response!='y'));
}
{ do{
cout<<"Question one"<<endl<<"Can birds sing?.....";/*This statement repeats more than once.*/
cin>>response2;
if((response_2=="yes")||(response2=='y')){
cout<<"Correct they do sing"<<endl;
break;
}
else if((response_2=="no")||(response2=='n')){
cout<<"Do you want to try again?"<<endl;
}
else{
}
}
while((response_2!="yes")||(response2!='y'));
}
{ do{
cout<<"Question two now"<<endl<<"Are pigs smart?......"<<endl;/*This on also repeats moer than once*/
cin>>response3;
if((response_3=="yes")||(response3=='y')){
cout<<"Yes they are smart"<<endl;
break;
}
else if((response_3=="no")||(response3=='n')){
cout<<"Do you want to try again?"<<endl;
}
else{
}
}
while((response_3!="yes")||(response3!='y'));
}
return 0;
}
[1]: https://i.stack.imgur.com/bTnBY.jpg
You declare response as a char, but first time when you are trying to initialize it from console
cin>>response;
your input contains 3 chars ("yes" in third line of you example [1]), so responsegets 'y', but 'e' and 's' are also in the input stream now, so this is the reason, why during the next reading from console:
cin>>response2;
response2 is initialized with 'e', which causes printing of extra Can birds sing?.....Question one, afterwards 'response2' gets 's' and print extra line again.
I recommend you to delete all redundant variables and use only std::string response. It will be harder to make a mistake then.
You can add a variable that counts how many times the loop has looped
int loopCount = 0;
int LoopMaxTries = 1;
while ( loopCount < LoopMaxTries /* and possibly other stuff */ ) {
// at the end of the loop
loopCount++;
}

Unable to Process Data from Text File in C++

Why is it that this program will not register the correct ID and Pin number entered?
Anything typed will proceed to wrong data being input but the correct data doesn't get recognized.
Inside the text file is 5 IDs, and 5 Pin numbers in a format of 5 rows 2 columns.
#include<iostream>
#include<iomanip>
using namespace std;
void main()
{
const int MAX=10, screenWidth=80;
string A = "Welcome to ABC Bank!";
int i=0;
int ID[MAX], Password[MAX], pin, acc, counter=1 ,limit=2;
cout<<setw((screenWidth-A.size())/2)<<" "<<A<<endl;
cout<<"\nAccount ID: ";
cin>>acc;
cout<<"Pin: ";
cin>>pin;
ifstream accountFile;
accountFile.open("AccountDetails.txt");
if (!accountFile)
cout<<"Unable to open requested file!";
else
{
while (!accountFile.eof())
{
accountFile>>ID[i]>>Password[i];
i++;
}
accountFile.close();
while (acc==ID[i] && pin==Password[i])
{
cout<<"Login successful!\n";
break;
}
while (acc!=ID[i] || pin!=Password[i])
{
if (counter==3)
{
cout<<"\nUnauthorized Access Detected. Account has been LOCKED!\n";
break;
}
else
{
cout<<"\nWrong Account ID/Pin. Please try again!"<<" (Attempts Left:"<<limit<<")";
cout<<"\nAccount ID: ";
cin>>acc;
cout<<"Pin: ";
cin>>pin;
counter++;
limit--;
}
}
}
system("pause");
}
After reviewing what #Joachim Pileborg stated in his answer earlier,
this is the updated code that I have done. Sadly, now this code fails to login successfully after the 1st attempt fails and the 2nd attempt is correct.
ifstream accountFile;
accountFile.open("AccountDetails.txt");
if (!accountFile)
cout<<"Unable to open requested file!";
else
{
while (accountFile>>ID[i]>>Password[i])
{
i++;
}
accountFile.close();
bool success = false;
for (int j=0; !success && j<i; j++)
{
if (ID[j] == acc && Password[j] == pin)
success = true;
}
if (success)
cout<<"\nLogin Successful!\n";
else
{
while (!success)
{
cout<<"\nAccount ID/Pin is incorrect. Please try again!"<<" (Attempts Left: "<<limit<<" )";
cout<<"\nAccount ID: ";
cin>>acc;
cout<<"Pin: ";
cin>>pin;
counter++;
limit--;
if (counter==3)
{
cout<<"Unauthorized Access Detected! Account Has Been LOCKED!\n";
break;
}
}
}
}
system("pause");
The logic for your login success/failure checks are flawed. To begin with they will invoke undefined behavior because you will access uninitialized elements of the arrays.
If, as you say, the file contains five entries, then after the loop i will have the value 5 which is the sixth element in the arrays (after you fix the reading loop, otherwise the value of i will be 6).
If we then overlook the UB (Undefined Behavior) the first loop, checking for successful login, that condition will most likely never be true, and that's good because otherwise you would have an infinite loop there. Then comes the second loop where you check for unsuccessful login, where the condition will almost always be true, and that will lead to an infinite loop.
To check if the login credentials given by the user was correct or not, I suggest something like
bool success = false;
for (int j = 0; !success && j < i; ++j)
{
if (ID[j] == acc && Password[j] == pin)
{
success = true;
}
}
if (success)
{
// Login successful
}
else
{
// Login failed
}
using namespace std;
int main()
{
const int MAX=10, screenWidth=80;
string A = "Welcome to ABC Bank!";
int i=0;
int ID[MAX], Password[MAX], pin, acc, counter=1 ,limit=2;
cout<<setw((screenWidth-A.size())/2)<<" "<<A<<endl;
cout<<"\nAccount ID: ";
cin>>acc;
cout<<"Pin: ";
cin>>pin;
ifstream accountFile;
accountFile.open("AccountDetails.txt");
if (!accountFile)
cout<<"Unable to open requested file!";
else
{
while (accountFile>>ID[i]>>Password[i])
{
i++;
}
accountFile.close();
bool success = false;
while (!success)
{
for (int j=0; !success && j<i; j++)
{
if (ID[j] == acc && Password[j] == pin)
success = true;
}
if (success)
cout<<"\nLogin Successful!\n";
else
{
cout<<"\nAccount ID/Pin is incorrect. Please try again!"<<" (Attempts Left: "<<limit<<" )";
cout<<"\nAccount ID: ";
cin>>acc;
cout<<"Pin: ";
cin>>pin;
counter++;
limit--;
}
if (counter==4)
{
cout<<"Unauthorized Access Detected! Account Has Been LOCKED!\n";
break;
}
}
}
system("pause");
}
CODE IS WORKING, Thank you for the input and help Mr Joachim Pileborg!

to check type of input in c++

## To check type of data entered in cpp ##
int main()
{
int num;
stack<int> numberStack;
while(1)
{
cin>>num;
if(isdigit(num))
numberStack.push(num);
else
break;
}
return(0);
}
If I declare a variable as interger, and I input an alphabet, say 'B', instead of the number, can I check this behavior of user? My code above exits when first number is entered and does not wait for more inputs.
First of all, the std::isdigit function checks if a character is a digit.
Secondly, by using the input operator >> you will make sure that the input is a number, or a state flag will be set in the std::cin object. Therefore do e.g.
while (std::cin >> num)
numberStack.push(num);
The loop will then end if there's an error, end of file, or you input something that is not a valid int.
First take your input as string
Using builtin libraries like isdigit() classify it as an integer
else if it contains '.'then its a float
else if it a alphanumerical the it is a string thats it
Code for this is below,
#include<iostream>
#include<string.h>
using namespace std;
int isint(char a[])
{
int len=strlen(a);
int minus=0;
int dsum=0;
for(int i=0;i<len;i++)
{
if(isdigit(a[i])!=0)
dsum++;
else if(a[i]=='-')
minus++;
}
if(dsum+minus==len)
return 1;
else
return 0;
}
int isfloat(char a[])
{
int len=strlen(a);
int dsum=0;
int dot=0;
int minus=0;
for(int i=0;i<len;i++)
{
if(isdigit(a[i])!=0)
{
dsum++;
}
else if(a[i]=='.')
{
dot++;
}
else if(a[i]=='-')
{
minus++;
}
}
if(dsum+dot+minus==len)
return 1;
else
return 0;
}
int main()
{
char a[100];
cin>>a;
if(isint(a)==1)
{
cout<<"This input is of type Integer";
}
else if(isfloat(a)==1)
{
cout<<"This input is of type Float";
}
else
{
cout<<"This input is of type String";
}
}
use cin.fail() to check error and clean the input buffer.
int num;
while (1) {
cin >> num;
if (cin.fail()) {
cin.clear();
cin.sync();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
continue;
}
if (num == -1) {
break;
}
numberStack.push(num);
}

Encountering error in scanning a character in stacks [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
#include <stdio.h>
#define MAXLEN 100
typedef struct
{
char element[MAXLEN];
int top;
} stack;
stack init(stack s)
{
s.top=-1;
return s;
}
int isEmpty(stack s){
return(s.top==-1);
}
int isFull(stack s){
return (s.top==MAXLEN-1);
}
stack push(stack s,char ch){
if(s.top==MAXLEN-1){
printf("\n the stack is full\n");
return s;
}
else{
++s.top;
s.element[s.top]=ch;
return s;
}
}
stack pop(stack s){
if(s.top==-1){
printf("\n the stack is empty");
return s;
}
else{
--s.top;
return s;
}
}
void top(stack s){
if(s.top==-1){
printf("\n empty stack");
}
else
printf("%c",s.element[s.top]);
}
void print(stack s){
int i;
printf(" serial no character ");
for(i=0;i<s.top;++i){
printf(" %d %c \n",i,s.element[i]);
}
}
int main(){
stack s;
s.top=-1;
init(s);
char e;
int n,j=1,k;
while(j==1){
printf("\n enter your choice 1.push 2.pop 3.top 4.print 5.exit:");
scanf("%d",&n);
switch(n)
{
case 1:
printf("\n enter the element to be pushed: ");
scanf("%ch",&e);
s=push(s,e);
break;
case 2:
s=pop(s);
break;
case 3:
top(s);
break;
case 4:
print(s);
break;
case 5:
j=0;
break;
default:
printf("\n wrong choice entered enter correct one ");
break;
}
}
}
The error occurs after I compiled and run it and have scanned a character; it goes out of the switch and is not scanning the value of n for consecutive time and is just going into switch with the pre-assigned value and it comes out of switch and asks for n to enter t. In this way I am encountering space as character automatically in the stack elements and the top is getting doubled. Please help me with this. You can once compile it and check for yourself.
Change
scanf("%ch",&e); /* %ch ? */
To
scanf(" %c",&e); // notice a whitespace in the format string
As scanf("%c",&e); leaves a newline, which is consumed again.
which tells scanf to ignore whitespaces.
OR
if (scanf(" %c",&e) != 1)
//Print error
It doesn't take a lot to make the code work sanely. In the fixed code below, I pre-declare the functions because of the compiler options I use. An alternative is to define the functions as static.
#include <stdio.h>
#define MAXLEN 100
typedef struct
{
char element[MAXLEN];
int top;
} stack;
int isEmpty(stack s);
int isFull(stack s);
stack init(stack s);
stack pop(stack s);
stack push(stack s, char ch);
void print(stack s);
void top(stack s);
stack init(stack s)
{
s.top = -1;
return s;
}
int isEmpty(stack s)
{
return(s.top == -1);
}
int isFull(stack s)
{
return(s.top == MAXLEN - 1);
}
stack push(stack s, char ch)
{
if (s.top == MAXLEN - 1)
{
printf("the stack is full\n");
}
else
{
++s.top;
s.element[s.top] = ch;
}
return s;
}
stack pop(stack s)
{
if (s.top == -1)
{
printf("the stack is empty\n");
}
else
{
--s.top;
}
return s;
}
void top(stack s)
{
if (s.top == -1)
printf("empty stack\n");
else
printf("TOS: %c\n", s.element[s.top]);
}
void print(stack s)
{
int i;
printf("serial no character\n");
for (i = 0; i <= s.top; ++i)
{
printf(" %3d %c\n", i, s.element[i]);
}
}
int main(void)
{
stack s;
s.top = -1;
init(s);
char e;
int n, j = 1;
while (j == 1)
{
printf("\nenter your choice 1.push 2.pop 3.top 4.print 5.exit: ");
if (scanf("%d", &n) != 1)
{
fprintf(stderr, "Failed to read a number.\n");
return 1;
}
switch (n)
{
case 1:
printf("\nenter the element to be pushed: ");
if (scanf(" %c", &e) != 1)
{
fprintf(stderr, "Failed to read a character.\n");
return 1;
}
s = push(s, e);
break;
case 2:
s = pop(s);
break;
case 3:
top(s);
break;
case 4:
print(s);
break;
case 5:
j = 0;
break;
default:
printf("incorrect choice (%d not in range 1-5); enter correct one\n", n);
break;
}
}
return 0;
}
Apart from making the indentation consistent (I use uncrustify, but there are other tools that can do the job too), I added error checking to the scanf() statements, fixed the "%ch" format string (the h is superfluous, though mostly harmless), removed trailing spaces from printing, used a newline at the end of non-prompting printf() statements.
Your printing code wasn't printing enough; because of the way you're running your stack pointer, you need to print for (i = 0; i <= s.top; i++) with <= instead of <. A more orthodox way of using top has it showing the next space to use (so the number starts at zero and goes up to MAXLEN). There'd be a number of consequential changes to make.
However, there are some major curiosities left. You keep on passing stacks by value and returning them by value, rather than passing them by pointer. You're therefore passing 104 bytes to and from functions, which is quite a lot. In this code, efficiency isn't a big issue, but the style is unorthodox, shall we say. Your initialization stanza in main() is problematic, too:
stack s;
s.top = -1;
init(s);
The first line is fine. The second line sets top, and is OK in terms of "it works", but violates encapsulation. The next line has multiple problems. It takes a copy of the already initialized stack, sets top to -1, and returns the modified value. Your calling code, however, ignores the returned value.
If you passed pointers to your functions, you'd use:
void init(stack *s)
{
s->top = -1;
}
and then:
stack s;
init(&s);
If you pass values, you could use:
stack s;
s = init(s);
though that's a bit pointless and you could use:
stack init(void)
{
stack s;
s.top = -1;
return s;
}
and then call:
stack s = init();
Of these, passing by pointer is the normal mechanism for largish structures (where, if asked to specify 'largish', I'd say "16 bytes or more"). You can make exceptions on an informed basis, but be careful of the hidden costs of passing large structures by value. Also, changes made to the structures passed by value are not reflected in the calling function. You circumvent that by returning the modified value, but be cautious.

Printing null character when input is odd character amount

I've been toying with this c program for a while, and I can't seem to figure out what I'm missing.
In the very bottom of my code, I have a function that replaces every other word with a "-".
My problem is that when I enter an odd numbered word, such as "Cat", "dog", "hamburger", it will place a "-" in what I think is the null character position, though I have not been able to debunk it.
Thank you for your help!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void replace(char w[]);
int main( )
{
char w[100], x[100], y[100];
int z = 0;
printf("Player 1, please enter the secret word: ");
fgets(x,100,stdin);
// system("clear");
while( strcmp(x,y) != 0 )
{
strcpy(w,x);
// printf("\nLength of String : %d", strlen(w)-1);
replace(w);
printf("Player 2, the word is %s\n",w);
printf("Player 2, please guess the word: ");
fgets(y,100,stdin);
z++;
if( strcmp(x,y) != 0 )
{
printf("Wrong. Try again.\n");
}
else
{
//system("clear");
printf("Correct!\n");
printf("It took you %d attempt(s).\n",z);
switch (z)
{
case 1 :
case 2 :
printf("A. Awesome work!");
{break;}
case 3 :
case 4 :
printf("B. Best, that was!");
{break;}
case 5 :
case 6 :
printf("C. Concentrate next time!");
{break;}
case 7 :
printf("D. Don't quit your day job.");
{break;}
default :
printf("F. Failure.");
{break;}
}
}
}
getch();
}
void replace(char w[])
{
int a;
a = 0;
while (w[a] != '\0')
{
if (a % 2 != 0)
{
w[a] = '-';
a++;
}
if (w[a] != '\0')
{
a++;
}
else
{
break;
}
}
}
From the fgets manual;
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte (\0) is stored after the last character in the buffer.
The newline entered is what you're replacing.
You can implement like this...
int a;
int len;
a = 0;
len = strlen(w);
if(len%2 == 0)
len = len-1;
while (len!=a)
{
if (a % 2 != 0)
{
w[a] = '-';
a++;
}
if (w[a] != '\0')
{
a++;
}
else
{
break;
}
}
I think replacing fgets with just gets will work:
Try:
//fgets(x,100,stdin);
gets(x);
and
//fgets(y,100,stdin);
gets(y);
That will be enough I think.
The problem is caused by the additional '\n' character in the char array passed to the replace function.
For instance, when the input is "Cat", the passed char[] w contains {'C', 'a', 't', '\n', '\0'};
The additional '\n' also gets replaced with "-" character.
The following will solve this problem.
while (w[a] != '\0')
{
if (w[a] != '\0' && w[a] != '\n')
{
if (a % 2 != 0)
{
w[a] = '-';
}
a++;
}
else
{
break;
}
}
As a bit of an aside, can I suggest structuring your replace() code differently
void replace(char charw[])
{
int length=strlen(charw);
int i;
for (i=0;i<length;i++)
{
if (i%2==1) /*yes, i%2 would also work, but lets not get too clever*/
{charw[i]='-';}
}
}
This is far more readable. Breaking in the middle of a loop...not so much.