Nested While Loops in C - c

I am having issues making this nested while loop to work in this terminal application.I am trying to build a system with Clients and an Admin with certain
capabilities for each.
scanf("%s",sign_in_choice);
int admin_result, client_result, number_of_clients, x, c;
admin_result = strcmp(sign_in_choice,"Admin");
client_result = strcmp(sign_in_choice,"Client");
char client_choice[10];
int client_username;
int client_password;
int client_choice_log_in, client_choice_register;
while(x == 0)
{
if(admin_result == 0 )
{
printf("Welcome to Admin Page\n");
}
else if(client_result == 0)
{
printf("Testing");
while(c == 0)
{
//START OF CLIENT PAGE
printf("Welcome to Client Page\n");
printf("Register or Log in?\n");
scanf("%s",client_choice);
client_choice_log_in = strcmp(client_choice,"Login");
client_choice_register = strcmp(client_choice,"Register");
if(client_choice_register == 0)
{
// REGISTER
reg(client_number);
// END OF REGISTER
}
else if(client_choice_log_in == 0)
{
//LOG IN
printf("Please enter your credentials\n");
printf("Enter your afm:\n");
scanf("%d", &client_username);
printf("Enter your year of birth:\n");
scanf("%d", &client_password);
login(client_username, client_password, client_number, client_verify);
//END OF LOG IN
// PERSONAL CLIENT PAGE
i = client_number;
printf("Welcome to your Personal Client Page: %s \n", client_array[i].client_name);
printf("Verify : %d\n",client_verify);
// END OF PERSONAL CLIENT PAGE
}
else
{
printf("Invalid input.Please try again.\n");
scanf("%s",client_choice);
client_choice_log_in = strcmp(sign_in_choice,"Login");
client_choice_register = strcmp(sign_in_choice,"Register");
}
// END OF CLIENT PAGE
}
}
else
{
printf("Invalid input.Please try again.\n");
scanf("%s",sign_in_choice);
admin_result = strcmp(sign_in_choice,"Admin");
client_result = strcmp(sign_in_choice,"Client");
}
}
If I remove the while( c == 0) loop the code works.It allows me to select either Login or Register and continue.If I leave the loop as is when I input 'Client' the program goes into an infinite loop printing 'testing'.In addition if I enter 'Admin' the program again goes into infinite loop printing 'welcome to admin page' although the while loop appears later in the program.At least in my understanding the while(c == 0) loop should only affect what is contained within it not outside it,at least in this particular case.I am using Devc 5.11.Also I tried compiling and running through vs code and codeblocks and in those cases the program doesn't even go beyond the 'Admin Client' choice in the beginning.As you can see I have some functions and and structs not shown here but they should not affect my problem since everything works fine until I try to make this nested while loop work.

c is uninitialized, so it has an undefined behavior, which depends on your compiler. You will need to initialize your variables. And to make sure you do not have infinite loops, you must handle the case when you have a client and c is not 0. You can set it to 0, or something, just don't leave there an else which will always be entered, will not change c and will have a loop inside it, which depends on the value of c.
Maybe I missed it, but I do not see how you set the value of c inside the while (c == 0) loop, so if c happens to be 0, that inner loop seems to be infinite as well.

Related

Variable loses its value C

I'm working on this project where a user has to guess a word (wordToGuess) and he has a number of attempts.
The problem is that the variable "wordToGuess" loses its value when the code arrives in the point marked ("HERE LOSES ITS VALUE). I don't know how to solve this problem, I've tried in many ways. Thank u for your help!
(checkExistence is a function that checks if the word is present in the dictionary)
void newGame(node* head){
char wordToGuess[10];
char attempt[10];
int numberOfAttempts = 0;
if (scanf("%s" , wordToGuess) != 1){
printf("error1");
}
getchar();
if (scanf("%d", &numberOfAttempts) != 1){
printf("error2");
}
getchar();
while(numberOfAttempts > 0){
if (scanf("%s", attempt) != EOF){
if (attempt[0] != '+'){
if (checkExistence(head, attempt) == false){
printf("not_exists\n");
}else{
if (strcmp(wordToGuess, attempt) == 0){
printf("ok\n");
return;
}else{
//code
numberOfAttempts--;
}
}
}else{
if (attempt[0] == '+' && attempt[1] == 's'){
//HERE LOSES ITS VALUE
}else if (attempt[0] == '+' && attempt[1] == 'i'){
//other code
}
}
}else{
printf("ko");
return;
}
}
return;
}
Here a test case:
2rj9R (wordToGuess)
18 (numerAttemps)
DP3wc (attempt)
7PGPU (attempt)
2rz9R (attempt)
+print_list (from this point I lose the value of wordToGuess)
2rj9R (attempt)
As the others have point, you're probably causing a buffer overflow in your attempt buffer which overwrites your wordToGuess buffer since your attempt and wordToGuess buffer is stored like this in your memory:
<attempt buffer> | <word To Guess>
You have two possible fixes for this (as the comments have said...):
A little fix would be to set a limit of how many characters should be read from stdin to scanf like this:
scanf("%9s" , wordToGuess) // you need 9, because your buffer can store up to
// 10 bytes but don't forget that `scanf` is also
// addinng `\0` for you!
and don't forget to flush the rest of the user input if you want that the user should be only able to insert at most 9 characters!
Increase the buffer size of your attempt (and wordToGuess) buffer but also add those read-limits for scanf which is described in the first point.
At the indicated point of the code where wordToGuess appears to lose its value, it is a dead variable. If you're looking at optimized code in a debugger, you may find that the variable doesn't exist there any more.
At a given point in a program, a dead variable is one which is never used past that point. All control flows out of that point reach the termination of that code, without ever using the variable again. Simple example:
{
int x = 3;
// x is live here: there is a next reference
printf("%d\n", x);
// x is now dead: it is not referenced after the above use
printf("foo\n");
}
In the generated code, the compiler may arrange to re-use the resources tied to a dead variable as soon as it is dead: give its register and memory location to something else.
In the debugger, if we put a breakpoint on the printf("foo\n") and try to examine x, we might get a strange result.
To have the best chance of seeing the expected result (that x still exists, and is retaining its most recent value), we have to compile with optimizations disabled.

I am trying to use function admin inside the switch case but it displays error. I am using Visual Studio 2017

How can I make admin function works inside the switch?
I tried doing it but still got an error using Visual Studio 2017
My program is about creating a pharmacy management system that has 2 access as admin and user. Admin can add or update or delete and the user can search or see expiry date.
Error C1075 '': no matching token found
Here is my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int admin(int1);
int main()
{
char username[50];
int password;
int choice;
int mainmenu = 1;
printf(" \n\n\n\t\t\t\t\tWELCOME TO THE PHARMACY MANAGMENT SYSTEM\t\t\t\t\t");
while (mainmenu == 1) {
printf("\n\n\n\nPlease choose from the current choices\n \n1.ADMIN \n\n2. "
"CUSTOMER\n\n3. EXIT\n\n");
scanf("%d", &choice);
do {
switch (choice) {
case 1:
admin(1);
break;
case 2:
break;
case 3:
printf(
"\n System Closes ...Press Any Key to turn off the system ....");
mainmenu = 0;
break;
}
}
while (choice = 1);
{
printf("\nplease enter your username\t");
scanf("%s", username);
printf("\nplease enter your password\t");
scanf("%d", &password);
if ((strcmp(username, "admin") == 0) && (password == 123123)) {
printf("\n\n\t\t\tYou have logged in succefully....\t\t\n");
break;
} else {
printf("\n\t\tThe username or password is incorrect.\n\t\tPlease "
"verify that CAPS LOCK is not on,and then retype the current "
"username and password.\n\n \a");
}
getch();
return (0);
}
}
You have at least following problems (in decreasing importance):
The final } is missing at the very end of the progran
You havce declared the function int admin(int1) but you havent implemented the function.
int admin(int1) should be declared int admin(int)
the warning for getch is because you forgot to include the conio.h header. This header is Microsoft specific.
Consider also platinum95's answer.
You have some issues with your loops, I think you expect them to do something different.
while (mainmenu == 1)
This loops the program until '3' is entered. This seems fine.
do {
...
}
while (choice = 1);
I think you need to look up how do-while loops work. This loop will never exit, as you assign choice to 1 rather than compare it with 1.
while (choice = 1);
{
...
}
This is not a loop. That while(choice = 1) belongs to the previous do-while loop. You therefore just have a block of code here (which is never executed since the previous loop never exits).
It also seems like the block of code here is intended to be the admin(int) function, (which you didn't include, so I presume this is supposed to be it).
Your best option is to go find a tutorial online of how while and do-while loops work, as well as a tutorial on writing and using functions.

C - segmentation fault when comparing integers

here is a part of my code. When I run my code, it's requesting an input from user and then matching it with another integer which recorded in my structure. When user input is matching, it is working correct. But when user enters a wrong input, it gives a segmentation fault. In where, I should make changes on my code?
long int userInput,endCheck; // Input from user
int flag=0; // check for match
int status;
int c; // controlling ctrl+D
int position= 999; // position of where the user input and data matched
LABEL:
printf("\n\t---------------------------------------\n");
printf("\n\nPlease enter the student ID which you want to find(3-times CTRL+D for finish):\n");
scanf("%d",&userInput);
if( (c=getchar()) == EOF){
exit(0);
}
for(i=0;i<lines,flag==0;i++){
if(index[i].id == userInput){
position=i;
flag=1;
}else{
position=999;
}
}
if(flag==0){
printf("id not found");
}
studentInfo info; // for storing the information which we will take between determined offsets
if(position!= 999){
if ( (pos = lseek(mainFile,index[position].offset , SEEK_SET)) == -1)/*going to determined offset and setting it as starting offset*/
{ perror("classlist"); return 4; }
while ( (ret= read(mainFile,&info, sizeof(info))) > 0 ){
printf("\n\nStudent ID: %d, Student Name: %s\n\n",info.id,info.name);
break;// to not take another students' informations.
}
}
flag=0;
goto LABEL;
printf("Program is terminated");
The right way to do that loop with the unwanted comma is like this. When you find the right index[i].id you can exit the loop early by using break.
for(i=0;i<lines;i++){
if(index[i].id == userInput){
position=i;
flag=1;
break;
}
}
You don't need the else branch as position is set to 999 from the outset of the code. But really you shouldn't use position in this fashion. What if you have more than 999 records? You're already using flag to identify if you've set position to a valid value. You should replace any instance of if(position!= 999) with if(flag).
Or since position is a signed int, you could use a negative value and ditch the flag.
The reason can be the fact that you are reaching an index that doesn't exist in the end of cycle, in the moment of the "if" statement with iterator "i".
Or in the last if, where you access a "position" index of the array. Check those limits.
Also, try GDB, is useful for solving this kind of problems.

Unable to stop the function when the condition its true

I'm doing a program where you can add items for a shop. Before the user can be allowed to do that, theres a subfunction which will ask for a user and password; if they are correct then allows the user to add any item as far he wants, also there's a variable called count if this variable goes to "0" should print and error and several noises and after that bring back the user to the main function and close the program.
The problem is after the condition is 0 the noises and error shows correctly but the program backs to ask for user and password and the count variable starts at 0 and every try rest the int...-1 -2 -3.
So I try this, even its working I think it's a pretty bad way:
The call
while(credencial !=1)
{
credencial=checkout(&counter);
if(counter==88)
{
goto error;
}
}
Function
int checkout(int *counter){
char login[10], password[10];
int c = 0;
printf("\nNumero de intentos restantes: %d\n", *counter);
puts("\nIntroduce un usuario con credenciales: \n");
scanf("%10s", login);
puts("\nIntroduce la contraseƱa: \n");
scanf("%10s", password);
(*counter)--;
if (*counter == 0)
{
system("cls");
for (c = 0 ;c < 3 ;c++)
{
puts("\n\aACCESSO DENEGADO\n");
}
*counter=88;
}
if (strcmp(strlwr(login), "admin") ==0 && strcmp(strlwr(password),"admin")==0)
{
return 1;
}
}
You can either use break; to leave the while loop (then you need to have a way to decide after the loop if it is a normal or error exit, for example by checking credential value) or add an additional condition to the while, like
while(credentiel != -1 && !abort) {
....
if (*counter == 88)
abort = true;
Or cou can use the goto, it is not that bad. Especially if the error label is used by other places as well.
BTW: I don't know why you mix out variables with return types and why you use 88 as a special number. Thats all quite untypical. You can keep the counter in the outer loop and make the crendtial check stateless, let it return pass/fail only. It is more common to use negative values (-1) for special "signals". In all cases make sure nobody can force the special value with other tricks.

Advice on Segmentation Fault, using gdb effectively, C Programming (newbie)

I am having a problem with a segmentation fault working in C, and I cannot figure out why this is occurring. I think it has something to do with misuse of the fget(c) function.
while((ch = fgetc(fp))!= EOF) {
printf("Got inside first while: character is currently %c \n",ch); //**********DELETE
while(ch != '\n') {
char word[16]; //Clear out word before beginning
i = i+1; //Keeps track of the current run thru of the loop so we know what input we're looking at.
while(ch != ' ') {
printf("%c ",ch); //**********DELETE
//The following block builds up a character array from the current "word" (separated by spaces) in the input file.
int len = strlen(word);
word[len] = ch;
word[len+1] = '\0';
printf("%s",word);
ch = fgetc(fp);
}
//The following if-else block sets the variables TextA, TextB, and TextC to the appropriate Supply Types from the input.
//This part may be confusing to read mentally, but not to trace. All it does is logically set TextA, B, and C to the 3 different possible values SupplyType.
if(word!=TextB && word!=TextC && i==1 && TextB!="") {
strcpy(TextA,word);
}
else if(word!=TextA && word!=TextC && i==1 && TextC!="") {
strcpy(TextB,word);
}
else if(word!=TextB && word!=TextA && i==1) {
strcpy(TextC,word);
}
switch(i) {
case 1:
if(TextA == word) {
SubTypeOption = 1;
}
else if(TextB == word) {
SubTypeOption = 2;
}
else if(TextC == word) {
SubTypeOption = 3;
}
break;
case 2:
//We actually ultimately don't need to keep track of the product's name, so we do nothing for case i=2. Included for readibility.
break;
case 3:
WholesalePrice = atof(word);
break;
case 4:
WholesaleAmount = atoi(word);
break;
case 5:
RetailPrice = atof(word);
break;
case 6:
RetailAmount = atoi(word);
break;
}//End switch(i)
ch = fgetc(fp);
}//End while(ch != '\n')
//The following if-else block "tallys up" the total amounts of SubTypes bought and sold by the owner.
if(SubTypeOption == 1) {
SubType1OwnersCost = SubType1OwnersCost + (WholesalePrice*(float)WholesaleAmount);
SubType1ConsumersCost = SubType1ConsumersCost + (RetailPrice *(float)RetailAmount);
}
else if(SubTypeOption == 2) {
SubType2OwnersCost = SubType2OwnersCost + (WholesalePrice*(float)WholesaleAmount);
SubType2ConsumersCost = SubType2ConsumersCost + (RetailPrice *(float)RetailAmount);
}
else if(SubTypeOption == 3) {
SubType3OwnersCost = SubType3OwnersCost + (WholesalePrice*(float)WholesaleAmount);
SubType3ConsumersCost = SubType3ConsumersCost + (RetailPrice *(float)RetailAmount);
}
}//End while((ch = fgetc(fp))!= EOF)
Using gdb (just a simple run of the a.out) I found that the problem is related to getc, but it does not tell which line/which one. However, my program does output "Got in side the first while: character is currently S". This S is the first letter in my input file, so I know it is working somewhat how it should, but then causes a seg fault.
Does anyone have any advice on what could be going wrong, or how to debug this problem? I am relatively new to C and confused mostly on syntax. I have a feeling I've done some small syntactical thing wrong.
By the way, this snippet of the code is meant to get a word from a string. Example:
Help me with this program please
should give word equaling "Help"
Update: Now guys I am getting kind of a cool error (although cryptic). When I recompiled I got something like this:
word is now w S
word is now w Su
word is now w Sup
... etc except it goes on for a while, building a pyramid of word.
with my input file having only the string "SupplyTypeA 1.23 1 1.65 1" in it.
UPDATE: Segmentation fault was fixed (the issue was, I was going past the end of the file using fgetc() ). Thanks everyone.
If anyone still glances at this, could they help me figure out why my output file does not contain any of the correct numbers it should? I think I am probably misusing atof and atoi on the words I'm getting.
Make sure you compile the program with -g -O0 options
Next step through the program line by line in GDB, watch and understand what your program is doing. Look at the various variables. This is the essential debugging skill.
WHen it dies type the command 'k' this will give you a stack trace the last line of the trace will have the failing line number, but you know that anyway because you were on the line shen you did a step command
There is no "fget" in good old C, but maybe you're using a more modern version that has something named "fget". Most likely, you meant to use "fgetc". When a C I/O function starts with "f", it usually wants a FILE* handle as an argument, as "fgetc" does. Try using "fgetc" instead, after reading the documentation for it.

Resources