Using function if, if condition is true, not working? - c

I want so that when the user enters e it will run my function called enter and scan in values but all I get is VECRQ?:, why is this? Did I call upon the function wrong?
I tried having the while loop to 1 also instead of menuoption != 'q' didn't work. I was thinking that with the menuoption is not equal to 'q' it will keep the loop running until the user actually enters 'q' to shut the program off.
#include <stdio.h>
int enter(int measurments[], int nrOfmeasurments)
{
while(nrOfmeasurments<10)
{
printf("Enter measurment #%d (or q to quit): ",nrOfmeasurments+1);
int oneMeasurment;
int readInteger = scanf("%d",&oneMeasurment);
if(readInteger)
{
measurments[nrOfmeasurments] = oneMeasurment;
nrOfmeasurments ++;
//return nrOfmeasurments;
}
else
{
char tmp;
scanf(" %c",&tmp);
break;
}
}
if(nrOfmeasurments==10)
{
printf("Array is full\n");
}
return nrOfmeasurments;
}
int main(void)
{
int measurments[10];
int nrOfmeasurments;
char menuoption;
printf("Measurment tool 2.0\n");
while (menuoption != 'q')
{
printf("VECRQ?:\n");
scanf(" %c",&menuoption);
if (menuoption == 'e')
{
//int MeasurmentData[10];
//int nrOfmeasurments;
//enter(measurments, nrOfmeasurments);
nrOfmeasurments = enter(measurments, nrOfmeasurments);
}
else if(menuoption == 'v')
{
}
else if(menuoption == 'c')
{
}
else if(menuoption == 'q')
{
printf("Exiting Measurment tool 2.0\n");
break;
}
}
}

Don't forget to init your variables with default values. Your problem is that nrOfmeasurments is not initialized and have some trash value. Also, set a default value to menuoption for some non q char to be sure, that your loop will be executed at least one time

Related

press q for quit and enter for continue

I have a do-while loop, and I want if I press ENTER key, the progress will continue, but q will finish the program. It is not working as the program will end straight away and does not wait for the user to enter the key.
Code below is my main code.
void displayGrid() {
bool progress = true;
printf("%s", "input round for round mode, moves for move mode");
scanf("%s", input);
toLowerCase(input);
if (strcmp(input, "round") == 0) {
do {
printf("Enter key ENTER to continue,Q for quit \n");
bool qoc = quitOrContinue();
if (qoc) {
} else if (!qoc) {
progress = false;
}
} while (progress);
}
}
This is my code for checking enter and q key:
bool quitOrContinue() {
if (kbhit()) {
char click = fgetc(stdin);
while (getchar() != '\n');
if (click == 0x0A) {
return true;
} else if (click == 'q') {
return false;
}
}
}
You do not need three functions to read a char from stdin.
Here's some psuedo-code to illustrate how to read one char. (I couldn't test it, so there may be some bugs in it).
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
static bool quitOrContinue(void)
{
int click = fgetc(stdin);
if (click == 0x0A) {
return true;
} else if (click == 'q') {
return false;
}
/* Returns false in case of any other character */
return false;
}
int main(void)
{
bool condition = false;
do {
printf("Hello World\n");
printf("Enter q to quit or ENTER to continue.\n");
condition = quitOrContinue();
} while (condition);
return EXIT_SUCCESS;
}
You do not need the progress variable.
while (getchar() != '\n');
serves no purpose in your code, unless you're trying to flush stdin.
regarding:
printf("%s", "input round for round mode, moves for move mode");
You could use:
printf("input round for round mode, moves for move mode");
regarding:
scanf("%s", input);
What happens when one inputs more than size characters?
Limit length:
scanf("%6s", input);

why for loop in program is not working correctly.it show display correct output but giving strange output

#include<stdio.h>
#include<string.h>
int main()
{
char username[5][10]={"akshay","shubham","gaurav","rahul","amit"};
int i,a=1;
char urname[10];
char pass[10];
printf("enter the Username : ");
scanf("%s",urname);
printf("enter the passwword : ");
scanf("%s",pass);
for(i=0;i<5;i++)
{
if(strcmp(&username[i][0],urname)==0) //username check
{
if(strcmp("helloworld",pass)==0) //password check
{
printf("correct username");
break;
}
else
printf("wrong pass");
break;
}
else
printf(" wrong username");
}
return 0;
}
//i wanted to make a login page but by some mean it is not working correctly please help me out...
Couple of things wrong with your code. First, the array size of 10 is insufficient for a string like "helloworld", in which we see 10 characters appear. You didn't count the '\0' byte at the end of the string. See this for details: What does the symbol \0 mean in a string-literal?
You also display an error immediately after you find a username mismatch. You should only do so in the end, after you have checked every entry in the username[][] array and perhaps set a flag.
#include <stdio.h>
#include <string.h>
int main(void)
{
char username[5][10] = {"akshay", "shubham", "gaurav", "rahul", "amit"};
int i, uname_flag = 0;
char urname[11];
char pass[11];
printf("enter the Username : ");
if (scanf("%10s", urname) != 1) // limit characters to be read to 10, to avoid buffer overflow
// also check the return value of scanf for input failure
{
return 1;
}
printf("enter the passwword : ");
if (scanf("%10s", pass) != 1)
{
return 1;
}
for (i = 0; i < 5; i++)
{
if (strcmp(username[i], urname) == 0) //username check
{
uname_flag = 1; // username is correct
if (strcmp("helloworld", pass) == 0) //password check
{
printf("correct username & pass");
break;
}
else
{
printf("wrong pass");
break;
}
}
}
if (uname_flag == 0) // check outside the loop
{
printf("wrong username\n");
}
return 0;
}

Comparing character inputs read from stdin

I am trying to debug a program which were I am getting the values 'S' or 'P' from standard input. My function calc_resistance() needs to distinguish between these two cases as well as a case were neither 'S' nor 'P' has been entered. The program always evaluates to the third case (neither 'S' nor 'P'`), why is this so?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
float calc_resistance(char conn) {
float retval = 0.0;
if (conn == 'S') {
retval = 1;
}
else if (conn == 'P') {
retval = 2;
}
else {
retval = -1;
}
return retval;
}
int main() {
char connection_type[25];
float resistance = 0.0;
while(1) {
printf("Enter 'S' or 'P': ");
scanf("%s", connection_type);
if(strlen(connection_type) != 1 ||
(strncmp(connection_type,"S",25) && strncmp(connection_type,"P",25))) {
printf("Answer not understood. Enter 'S' or 'P'.\n");
continue;
}
break;
}
resistance = calc_resistance(connection_type);
printf("Connection type: %f", resistance);
}
The mistake you're doing is to pass an array to the calc_resistance() function when it is defined to accept only a single char.
Seeing the input pattern, connection_type doesn't need to be an array, with the help of %c format specifier, you can easily make connection_type a single char variable to work on the input.
You can read more about this on the man page of scanf(). Also, after each iteration, don't forget to sweep out the remaining newline.
Moral of the story :: Enable compiler warnings and pay heed to them.
You want to detect the first two cases right? if yes then try this one instead of passing the whole address in your function calc_resistance(connection_type) only pass one character then try, You can modify the code as below.
#include
#include
#include
float calc_resistance(char conn)
{
float retval = 0.0;
if (conn == 'S')
{
retval = 1;
}
else if (conn == 'P')
{
retval = 2;
}
else
{
retval = -1;
}
return retval;
}
int main()
{
char connection_type[25];
float resistance = 0.0;
while(1)
{
printf("Enter 'S' or 'P': ");
scanf("%s", connection_type);
if (strlen(connection_type) != 1 || (strncmp(connection_type,"S",25) && strncmp(connection_type,"P",25)))
{
printf("Answer not understood. Enter 'S' or 'P'.\n");
continue;
}
break;
}
resistance = calc_resistance(connection_type[0]);
printf("Connection type: %f", resistance);
}

How to check whether ID already exists in File with C Programming

I have this coding down below (just posting the Customers Management only).
This a database in which I am adding a customer each time it passes. Now I need to check whether the c.ID which is the client ID exists or not.
I tried doing a method called searchID which returns 1 if it's found or -1 if it's not found.
Problem is when I try to run the program, the program literally hangs there. Whether I press 23 or "ENTER" nothing happens and I would need to exit it using the CTRL + C;
so this is how it works:
When I add a customer (Which is a struct) it saves into the file but I first need to check
whether the ID exists in the database or not otherwise I need to ask the user to either input another ID or go back to the Main Menu
Any suggestions please?? thank you
#include<io.h>
#include<fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "..\Headers\common.h"
#include "..\Headers\customerManagement.h"
static FILE *cfp;
static customer c;
#define STRUCTSIZE sizeof (customer)
/** This is the Customers's Main Menu in which the various sections can be
* accessed from here
*/
boolean customerMainMenu()
{
int optionC;
clrscr();
copyright();
printf ("\n\n\n\n\t\t ************* Customer's Main Menu *************\n \n \n");
printf ("Press [1] to add a new Customer\n");
printf ("Press [2] to edit a Customer\n");
printf ("Press [3] to list all Customers\n");
printf ("Press [4] to Show a Customer's last Order\n");
printf ("Press [5] to go back to Main Menu\n\n\n");
if (scanf ("%d",&optionC) == 1)
{
switch (optionC)
{
case 1:
{
clrscr();
getchar();
addCustomer();
break;
}
case 2:
{
printf ("Edit a Customer\n");
break;
}
case 3:
{
clrscr();
listCustomers();
getchar();
while (getchar()!='\n')
{
}
break;
}
case 4:
{
printf ("Customer's Last Order\n");
break;
}
case 5:
{
system ("PAUSE");
break;
}
default:
{
if (optionC != 1 || optionC != 2 || optionC != 3 || optionC != 4 || optionC !=5)
{
clrscr();
printf ("Invalid option!\n");
system ("PAUSE");
customerMainMenu();
}
break;
}
}
}
return TRUE;
}
/**
* This following method will append a customer to the
* database at the end of the file
*
* */
void addCustomer ()
{
char ch;
copyright();
printf ("\n\n\n\n\t\t ************* Add Client **********\n \n \n");
if ((cfp = fopen ("customers.dat","a+b")) == NULL)
{
fputs("Can't open customers.dat file\n",stderr);
}
printf ("\tThis will add another customer to the the database\n");
printf ("\tPress 'Y' to confirm or 'N' to return to the Client Main Menu\n\tWITHOUT adding a customer\n");
ch = getchar();
if (ch == 'n' || ch == 'N')
{
customerMainMenu();
}
else if (ch == 'y' || ch == 'Y')
{
clrscr();
printf ("\n\n\n\n\t\t ************* Add Client **********\n \n \n");
printf ("Please enter Name:\n");
while (scanf ("%s", c.name) == 0 || cCheck(c.name,100) == FALSE);
{
}
printf ("Please Enter Surname: \n");
while (scanf ("%s",c.surname) == 0 && cCheck (c.surname,100) == FALSE);
{
}
printf ("Please Enter ID Card, [NOTE! Only numbers are allowed!]\n");
int cID;
cID = 0;
while (scanf ("%d",&cID)==0)
{
printf ("Only Numbers are allowed!\n");
while (getchar() != '\n')
{
}
}
if (searchID(cID) == 1)
{
printf ("This ID already exists. Client already exists!\n");
printf ("Do you want to input another ID or return to Main Menu?\n");
printf ("Press 'Y' if you enter another ID, press any other key to return to Main Menu\n:");
ch = getchar();
if (ch == 'y' || ch == 'Y')
{
printf ("Enter another ID:\n");
while (scanf ("%d",&cID)==0)
{
printf ("Only Numbers are allowed!\n");
while (getchar() != '\n')
{
}
}
searchID(cID);
}
else if (searchID(cID) == -1)
{
cID = c.ID;
getchar();
}
}
while (getchar()!='\n')
{
}
printf ("Please Enter Address:\n");
gets(c.address);
fwrite (&c,STRUCTSIZE, 1, cfp);
printf ("For Testing purposes:\n");
printf (" %s\n %s\n %s\n %d\n", c.name, c.surname, c.address, c.ID);
askAnother();
}
else
{
printf ("\nInvalid choice! Either Y or N is accepted\n");
system ("PAUSE");
getchar();
addCustomer();
}
}
void listCustomers()
{
if ((cfp = fopen ("customers.dat","rb")) == NULL)
{
fputs("Can't open customers.dat file\n",stderr);
printf ("Returning to Customer Main Menu");
system ("PAUSE");
customerMainMenu();
}
rewind (cfp);
while (fread (&c,STRUCTSIZE,1,cfp)==1)
{
printf ("Customer: %s %s ID: %d\n", c.surname, c.name, c.ID);
}
fclose (cfp);
// system ("PAUSE");
}
void askAnother()
{
printf ("Do you want to add another Customer?\n");
printf ("Enter 'Y' for yes and 'N' to return to the Main Menu\n");
char input;
input = getchar();
if (input == 'Y' || input == 'y')
{
getchar();
addCustomer();
}
else if (input == 'N'|| input == 'n')
{
fclose (cfp);
customerMainMenu();
}
else
{
printf ("Invalid Option! Only Y or N are allowed\n");
system ("PAUSE");
askAnother();
}
}
boolean cCheck(char *test, int max)
{
int x;
for (x =0; x<max; x++)
{
if (isdigit(test[x]))
{
return FALSE;
}
if (x==max)
{
return TRUE;
}
x++;
}
return TRUE;
}
int fileSize()
{
int lengthOfFile;
int file;
file = open("Customers.dat",O_RDONLY,0);
lengthOfFile = lseek (file,0, SEEK_END);
return lengthOfFile;
}
int getNoOfRecords()
{
return (fileSize()/(STRUCTSIZE));
}
/**
* This method will compare the ID passed from the ID of the customer to check
* whether it is exists or not. If it exists it will output 1 otherwise it
* will output -1. This will make sure that the Person's ID is unique
*
*/
int searchID (int cID)
{
// for the while loop
int index;
index = 0;
//gets the number of records currently held in the file.
int records;
records = getNoOfRecords();
//User will input the ID into this variable and it will be checked
//whether it exists or not
int IDstatus;
IDstatus = 0;
while (index != records)
{
fread (&c,STRUCTSIZE,1,cfp);
if (c.ID == cID)
{
IDstatus = 1;
}
else
{
IDstatus = -1;
}
}
return IDstatus;
}
EDIT:
There are either 2 things:
Either the Method is not working the SearchID() method because even though I have 2 IDs which are 0 now, they are still accepting it
or else because of the c.ID which is staying 0.
When I'm inputting the data, it is accepting it BUT when I try to output the whole record, the Client ID stays 0.
Added to that, it IS letting me having Two IDs which are 0 so most probably the method is not working.... Thanks for all the help until now!
You missed to increment index, and of course you should exit the loop when you found the id:
while (index != records)
{
fread (&c,STRUCTSIZE,1,cfp);
if (c.ID == cID)
{
IDstatus = 1;
break; // <<<< otherwise IDStatus will be overwritten by next iteration
}
else
{
IDstatus = -1;
}
index++; // <<< otherwise endless loop
}

My code is looping once more than I want it to, I suspect something is wrong with my getchar statement

Firstly, I would like to thank everyone here in advance. I look very forward to advancing in the realm of computer science, and helping others as I become more proficient.
Now here is my code:
#include <stdio.h>
#include <stdlib.h>
#define RECORDS 30
/*Questions
Formatting display() - can we use spaces to format?
Is the patient structure supposed to be global or local in enter()?
*/
void enter();
void display();
void update();
void loadDisk();
void writeDisk();
void emptyDisk();
void sort();
void clear();
struct patient
{
char * name;
int age;
double highBP, lowBP, riskFactor;
};
struct patient * db[RECORDS];
int counter = 0;
main()
{
int flag = 1;
while (flag == 1)
{
printf("---------------------------------------------------------\n");
printf("|\t(N)ew record\t(D)isplay db\t(U)pdate record |\n");
printf("|\t(L)oad disk\t(W)rite disk\t(E)mpty disk |\n");
printf("|\t(S)ort db\t(C)lear db\t(Q)uit |\n");
printf("---------------------------------------------------------\n");
printf("choose one: ");
char selection = getchar();
printf("selection %c\n", selection);
if ((selection == 'n') || (selection == 'N'))
{
//New record
enter();
}
else if ((selection == 'd') || (selection == 'D'))
{
//Display db
//printf("display %d\n", flag);
display();
}
else if ((selection == 'u') || (selection == 'U'))
{
//Update db
update();
}
else if ((selection == 'l') || (selection == 'L'))
{
//Load disk
loadDisk();
}
else if ((selection == 'w') || (selection == 'W'))
{
//Write disk
writeDisk();
}
else if ((selection == 'e') || (selection == 'E'))
{
//Empty disk
emptyDisk();
}
else if ((selection == 's') || (selection == 'S'))
{
//Sort db
sort();
}
else if ((selection == 'c') || (selection == 'C'))
{
//Clear db
clear();
}
else if ((selection == 'q') || (selection == 'Q'))
{
//Quit
flag = 0;
}
else
{
printf("not a vaild input\n");
}
}
}
void enter()
{
/*struct patient temp;
printf("name: "); sscanf("%s", temp.name);
printf("age: "); scanf("%d", temp.age);
printf("high bp: "); scanf("%f", temp.highBP);
printf("low bp: "); scanf("%f", temp.lowBP);
db[counter] = (struct patient *) calloc(1, sizeof(temp));
*db[counter] = temp;
//printf("%s, %d, %f, %f", db[counter]->name, db[counter]->age, db[counter]->highBP, db[counter]->lowBP);
counter++;*/
}
void display()
{
}
void update()
{
}
void loadDisk()
{
}
void writeDisk()
{
}
void emptyDisk()
{
}
void sort()
{
}
void clear()
{
}
The issue I am having when running it is that the menu displays twice after I enter an option. I am having trouble understanding what is going wrong, but I suspect it has something to do with getchar which storing the selection and the new line character, hence running it twice. This would also mean the final else statement would run, which it does.
I think I have triangulated the problem, just unsure how to fix it. Thank you in advance!
If the problem is with getchar, which it does look to be, why not use a different function?
Try replacing:
char selection = getchar();
With this:
char selection;
scanf("%c",&selection);
If you're worried about overflow in the single character, then do a scanf() for a string and only use the first character in your checks:
char selection, selectionstr[20];
scanf("%s",selectionstr);
selection = selectionstr[0];
getchar also returns '\n' character.
Yeah, the problem is that your input is always a string, at least one character followed by a newline. I would either change your loop so that it terminates if selection is 'q' or use a function other than getchar and prune your input.
I think you can do this using curses! Here is a a website which you may find useful. Curses is a cursor control library for c.
From the manual:
Initially the terminal may or may not be in cbreak mode, as the mode is
inherited; therefore, a program should call cbreak or nocbreak explic-
itly. Most interactive programs using curses set the cbreak mode.
Note that cbreak overrides raw.

Resources