C - How to use a string with scanf multiple times - c

Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char terminal[100];
printf("Enter cmds: ");
scanf(" %s", terminal);
if(strcmp(terminal, "help") == 0){
printf("test");
scanf(" %s", terminal); // trying to detect if a user types
// "help" the menu will pop up again
}
return 0;
}
When a user types "help", the menu pops up, (good so far). But when they type "help" again, the menu does not pop up. Does anybody know what is going on?

The initial comments hit the nail on the head here. You need to loop over new input multiple times. This can be done fairly easily.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char terminal[100];
printf("Enter cmds: ");
// this expression will return zero on invalid input, exiting the loop
while (scanf("%99s", terminal) == 1) {
// your if statement and other code you want to repeat go here.
}
}
To better encapsulate this kind of behaviour, defining some sort of function that compares strings and returns an element of an enum is a very common practice, but not required in this question.

Related

Is there a way to put a time limit to fgets()?

I'm running a console using fgets() in a microcontroller. If I leave the console idle for too much time while fgets() is prompting for commands the watchdog timer would get triggered.
I wonder if it is possible to set a time limit on fgets() so that if the user doesn't provide commands after certain amount of time, fgets() expires?
Note
This answer might be completely useless if you are writing microcontroller code using something like HI-TECH C or Keil C51. In those cases, you will have to use some platform dependent solution.
There are a lot of things wrong with this example, but it shows how to interrupt fgets:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <setjmp.h>
sigjmp_buf context;
volatile int alarm_occurred = 0;
void alarm_handler(int signum) {
alarm_occurred = 1;
siglongjmp(context, -1);
}
int main() {
char buffer[80];
signal(SIGALRM, alarm_handler);
while (1) {
char *result;
if (sigsetjmp(context, 1) == 0) {
// The call to sigsetjump will cause flow to go here
alarm(3);
printf("Enter a string: ");
result = fgets(buffer, sizeof(buffer), stdin);
}
else {
// The call to siglongjump will cause flow to go here
printf("\n");
continue;
}
}
return 0;
}
Output
Enter a string:
Enter a string:
...
Enter a string:
I've never used sigsetjmp or siglongjmp before, and I know better than to do anything other than set a flag in a signal handler, but hopefully the people who do know how to use these properly can edit the answer to fix the problems.

Why isn't my code terminating within a loop when checking for 'exit' string?

My program is supposed to exit when the user types in exit similar to how its done in a shell. First I checked online to see if syscall could be called in a loop, but then I noticed the indices of the characters in the array are wrong. Why are these changing; when I ran the program and typed in exit I had my program shoot out the 3rd index for testing purposes and it returned 'e'. So I thought it might've been flipped and flipped all values and my exit still did not work. Any thoughts on what the underlying issue may be?
#include <stdio.h>
//Abstract: This program runs a script to emulate shell behavior
#define MAX_BIN_SIZE 100
int main() { //Memory allocation
char * entry[MAX_BIN_SIZE];
while(1)
{
printf("msh>");
fgets(entry,MAX_BIN_SIZE,stdin); //Getting user input
if(entry[0]=='t' && entry[1]=='i' && entry[2]=='x' && entry[3]=='e')
{
//printf("Exiting");
exit(0); //exit(system call)
break;
printf("Inside of exit");
}
printf("msh> you typed %s %c %c %c %c",entry,entry[3],entry[2],entry[1],entry[0]); //returning user input
}
return 0;
}
I am sorry I don't have enough reputation points to add a comment, but #lundman is correct. I don't think you need to create a pointer to entry. Also, you are checking for "exit" in the reverse order. I tried and edited the code; this seems to work:
#include <stdio.h>
//Abstract: This program runs a script to emulate shell behavior
#define MAX_BIN_SIZE 100
int main()
{ //Memory allocation
char entry[MAX_BIN_SIZE];
while(1)
{
printf("msh>");
fgets(entry,MAX_BIN_SIZE,stdin); //Getting user input
if(entry[0]=='e' && entry[1]=='x' && entry[2]=='i' && entry[3]=='t')
{
printf("Inside of exit");//printf("Exiting");
exit(0); //exit(system call)
}
printf("msh> you typed %s %c %c %c %c\n",entry,entry[3],entry[2],entry[1],entry[0]); //returning user input
}
return 0;
}

Printing several \t in one line

For some weird reason my little program over here doesn't show up the way I want to.The last \t before Quit for a weird reason doesn't do anything.
Can anyone explain me why?
#include <stdio.h>
int n,litera;
void main (void)
{ n=1;
printf("File\tEdit\tView\tCompile\tQuit\n");
printf("Selectati optiunea aleasa:");
}
There's nothing really weird about it. Since Compile is more than 4 letters long, it eats up three spaces into the next tab block. Hence the result. Use two \t\t otherwise.
Here's a Q&D solution:
#include <stdio.h>
#define TAB " "
int n,litera;
int main (void)
{ n=1;
printf("File"TAB"Edit"TAB"View"TAB"Compile"TAB"Quit\n");
printf("Selectati optiunea aleasa:");
return 0;
}

c: strcmp Not Stopping At Conditional Statement It Should Hit

I'm learning to create multi-file programs for one of my classes. Ultimately I need to implement a stack and do some stuff with the stack. Before I began implementing the stack I wanted to make sure my files were all linked together properly with a header file. For some reason when the user inputs "pop" or "print" the conditional statement is not triggered and the method in stack.c is not called. I've been looking at this for awhile and haven't gotten anywhere. Thank you for the help
MAIN.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stack.h"
void pop(char list[]);
void print(char list[]);
void push(char list[]);
int main(void)
{
char input[5];
char test[5];
while( strcmp("exit",input) != 0)
{
printf("Please enter a command. \n");
fgets(input,sizeof(input),stdin);
if(strcmp("pop",input)==0)
{
pop(test);
}
else if(strcmp("push",input)==0)
{
push(test);
}
else if (strcmp("print", input)==0)
{
print(test);
}
}
return 0;
}
STACK.c
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
void pop(char list [])
{
printf("This is in the stack file in pop\n");
}
void push(char list [])
{
printf("This is in the stack file in push\n");
}
void print(char list[])
{
printf("This is in the stack file in print\n");
}
Console Output
Please enter a command.
push
This is in the stack file in push
Please enter a command.
Please enter a command.
pop
Please enter a command.
print
Please enter a command.
Please enter a command.
exit
I will suggest use of strstr() instead of strcmp(). If you use strstr() then there is no need to mention '\n' in the string to be searched.
The strstr() function finds the first occurrence of the substring needle in the string haystack.
For better understanding you can visit,
http://man7.org/linux/man-pages/man3/strstr.3.html
Code will look like,
while( strstr(input,"exit") == NULL)
{
printf("Please enter a command. \n");
memset(input,0,sizeof(input));
fgets(input,sizeof(input),stdin);
if(strstr(input,"pop"))
{
printf("pop\n");
}
else if(strstr(input,"push"))
{
printf("push\n");
}
else if (strstr(input,"print"))
{
printf("print\n");
}
}
I agree with #Govind Parmar that 5 bytes are not sufficient for input buffer. You need to declare input buffer with 7 bytes.
Three things:
The line read by fgets() will include \n at the end. Test for strcmp("word\n", input)==0.
5 is not sufficient size for input since you need to be testing for newlines ("push\n\0" is 6 bytes; "print\n\0" is 7 bytes)
You test for strcmp("exit", input) without input being initialized. This is undefined behavior. Set input to be all-zeroes before beginning your loop.

Print a message on a different location without interrupting input prompt in C

In the case that I have a "MessageLine" to display messages and an input prompt Input:
Like this:
MessageLine: Type 123!
Input:
Then, typing a wrong input, would display "Wrong!" on the MessageLine:
MessageLine: Wrong!
Input: somewronginput
Then, the user not knowing what to do next, I want the first message to be shown again after 3 seconds, BUT the cursor is still at the input prompt, means the MessageLine would change it's message without affecting the input prompt.
Could it happen to have an independent sequence for my "MessageLine" or whatever solution that would be?
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <string.h>
void msgline(int msg_var){
char *msg[]={
"Type Numbers \"123\"",
"Wrong! Try Again",
"Correct! Press Any Key to Exit..."
};
gotoxy(25,1);
clreol();
printf("Message: %s",msg[msg_var]);// Message Box
}
void main()
{
char inp[256]={0},
answr[]="123";
clrscr();
do{
msgline(0);
printf("\n\nInput: ");
clreol();
scanf("%s",&inp);
if(!strcmp(inp,answr));
else{
memset(inp,0,sizeof(inp));
msgline(1); // Wrong input
delay(3000);
/* delay function also delays the loop
and the cursor is at the message's end of line */
}
}
while(strcmp(inp,answr));
msgline(2); // Correct input
getch();
}
This level of control is not part of the standard C definition of the output stream(s).
Depending on your platform, you might be able to use GNU ncurses for instance.

Resources