I am creating a c shell and having an issue where I am stuck in an infinite loop. Example input/ouput: I type "ls -a" and the results of the command continually print over and over to console. If I remove the label (I called start:) and the goto statement then my shell will just execute the command and then exit the shell program entirely. I have also tried using while(1) and for(;;) loops but these resulted in the same output I am currently getting. How can I accomplish my goal here? all help is appreciated. see code below.
int main( int argc, const char* argv[]){
char whole[1024];
int cmdCount = 1;
start:
scanf("%1023[^\t\n]", whole);
//....
goto start;
return 0;
}
Your scanf will read everything except newline or tab. You never check if it reads anything. So the first time it succeeds, the next time there's a newline so it can't read anything. You don't check this and just use the buffer which contains the previously read line. This will cause the same command to be run over and over again.
Rather read lines from stdin and parse them, don't read with scanf.
The problem is you didn't check return of value of your scanf function. First it scans everything up to \n character and executes your code. But the \n character is still left in buffer; So next scanf will do nothing, leaving old whole value intact. That's why it's executing the same command over and over again. Check the following code:
#include <stdio.h>
#include <string.h>
int main(void) {
char whole[1024];
strcpy(whole, "override whole string");
scanf("%1023[^\t\n]", whole);
printf("%s\n", whole);
strcpy(whole, "override whole string");
scanf("%1023[^\t\n]", whole);
printf("%s\n", whole);
return 0;
}
It won't allow you to enter two lines. Second scanf will just fail, leaving old "overridden" value.
Use fgets function to get whole lines of input.
Related
I am trying to read every word in a file and print it to the screen. I want The program to accept spaces but it gives me an infinite loop when I use this %[^\n]
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *DoThis;
DoThis = fopen("Encrypppc.txt", "r");
char word2[48];
while(!feof(DoThis)){
fscanf(DoThis,"%47[^\n]s",word2);
printf("%s\n", word2);
}
return 0;
}
Try to create a file and input spaces in the first sentence. It gives an infinite loop in the first sentence when there's space so it never reaches eof.
I found the answer I supposed to
add a space in the fscanf function.
this is what gives me the infinite loop
fscanf(DoThis,"%47[^\n]s",word2);
after I add a space before the sign % there's no infinite loop and the loop stops at EOF
fscanf(DoThis," %47[^\n]s",word2);
notice the change
You have an 's' that doesn't belong in the format string. Try this:
fscanf("%47[^\n]%*c", word2);
That will get you past the failure to read the end of file and on to the next problem. I added the %*c format to read and ignore the next character (either a \n newline or the end of file). That does (more precisely) what you accomplish with the leading space (which discards all spaces and tabs up to the next nonblank character.)
That "next problem" is the one mentioned in comment that feof() only goes true after an attempt to read past the end of file. You'll see your last line twice. The leading space in the format might work for you, but a better solution is to use the return value from fscanf() to tell you if the input read anything:
while (1)
{
int n = fscanf("%47[\n]%*c", word2);
if (n != 1) break;
...do something with word2
}
The ?scanf functions return the number of fields successfully converted and stored. There's only one such field in your format, so the return will be 1 whenever the input succeeded, or something else if it didn't. (Both 0 and EOF are possible returns, depending on the state of the file beforehand.)
I want to scan a line until newline is pressed. I'm aware of gets() function, but I wanted to learn it with scanf(). The problem is, that my program falls into an infinite loop, where it scans the input from user and then infinitely prints it out, where it should print once after each scan. Can anybody explain why is it behaving like this?
#include<stdio.h>
int main()
{
char str[100];
while(str[0]!='\0')
{
scanf("%[^\n]",str);
printf("%s\n",str);
}
}
If you insist on using scanf, then change format specifier:
" %[^\n]"
The space in front will skip any previous "dangling" \n
Also you should initialize the str array before checking the contents of it, better yet use a do-while-loop instead .
Something like this should work
char str[100] = {0};
do
{
scanf(" %[^\n]",str);
printf("%s\n",str);
}
while(str[0]!='q');
Personally I prefer to use fgets(...) in combination with sscanf(...)
Also it is good practice to check the return value of scanf, there is a return value for a purpose.
added another while condition, loops until "q" or "quit"
Since %[^\n] does not accept newline, input is not accepted in the second loop.
Probably, this will do what you want.
#include<stdio.h>
int main(void){
char str[100];
while(1== scanf("%99[^\n]%*c",str)){//%*c consumes newline. Also In case of only newline terminates the loop
printf("%s\n",str);
}
}
BLUEPIXY is absolutely correct. The first return from scanf() is leaving the \n in the input buffer. Subsequent scanf() calls will return right away without reading any characters from stdin because scanf() stops reading on a \n. So a loop ensues. One way to avoid the loop is to read the \n from the input after the call to scanf() as shown below:
#include <stdio.h>
int main()
{
char str[100] = {0};
do
{
scanf("%[^\n]",str);
getchar();
printf("%s\n",str);
}while( str[0] != '\0' );
}
You seem to be under some false beliefs regarding how input works. So I'm going to explain below.
You don't need to do this in a loop because scanf() doesn't read and return one character at a time when you specify a string format. The input is buffered by the terminal. When you ask scanf() to return a string, the terminal will only send the input string to scanf() when it a newline is received. When that happens scanf() returns the string without the newline.
You'll need to do extra work to turn off terminal line buffering. The below example code shows how to turn off terminal I/O buffering.
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
int main()
{
struct termios old_tio, new_tio;
unsigned char c;
/* get the terminal settings for stdin */
tcgetattr(STDIN_FILENO,&old_tio);
/* we want to keep the old setting to restore them a the end */
new_tio=old_tio;
/* disable canonical mode (buffered i/o) and local echo */
new_tio.c_lflag &=(~ICANON & ~ECHO);
/* set the new settings immediately */
tcsetattr(STDIN_FILENO,TCSANOW,&new_tio);
do {
c=getchar();
printf("%c ",(char)c);
} while(c!='q');
/* restore the former settings */
tcsetattr(STDIN_FILENO,TCSANOW,&old_tio);
return 0;
}
I'm writing a basic program to learn how to use basic input/output in C, and it works just fine. The only problem I have is when it prints, there is a "%" at the end of the string on the terminal. Here's my code:
#include <stdio.h>
int main(int argc, char **argv) {
char name[32];
printf("Enter your name: ");
scanf("%s", name);
printf("Hello, %s", name);
return 0;
}
When I run the program, the output is Hello, Andrew%
Any help?
There's nothing in your code that should explain this behavior. However, it seems likely that if you are running this from a shell, that may be your shell prompt.
Add a newline to your output:
printf("Hello, %s\n", name);
This should cause the prompt to print on the next line as you probably expected.
The stdout stream is line buffered. What this means is the output does not appear on the console until a newline is output or the buffer is full. This may be a cause why you are seeing a % on the screen. '\n' causes printf to print the output immediately on the screen.
Note that if the input string is larger than 31 characters, then scanf will overrun the buffer name invoking undefined behaviour. This may crash the program due to segfault. You should safeguard against it by providing the maximum field width which should be 1 less than the array length to accommodate for the terminating null byte added by scanf.
#include <stdio.h>
// if your not using command line argument, use the below
// signature of main
int main(void) {
char name[32];
printf("Enter your name: \n"); // add a newline to output
scanf("%31s", name); // -1 for the terminating null byte
printf("Hello, %s\n", name); // add a newline to output
return 0;
}
As you have not output a new line - that is your shell prompt character being shown after the specified output. Try printf("Hello, %s\n", name);
Run this command line PROMPT_EOL_MARK='' into your zsh shell, that should be enough to fix it.
I write this code, which takes an integer number (t) as input from the user. A loop will be executed just 't' times. But I find that it runs for (t-1) times. For example, if I give input 3, it runs only 2 times. Can anyone please explain why this is happening?
I tried and used scanf("%s", &str), it works, but then I can't take a string as input that contains spaces.
#include <stdio.h>
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
char str[100];
gets(str);
printf("%s\n", str);
}
return 0;
}
scanf("%d", &t) consumes only the numeral in the input stream and leaves the remaining characters. When you enter a numeral and press enter, there is a newline character after the numeral.
The first gets reads this newline and returns a string that is empty except for the newline. The first iteration of the loop prints this blank line.
Loop is iterating 3 times as it should.But it seems that it is iterating 2 times only because of the reason that the \n character left behind by gets in the buffer is read in second iteration.
For first iteration, when you enter a string and the press Enter, the \n character go to the buffer with the string. gets stop reading when it encounters \0, leaving \n in the buffer. On next iteration this \n (non printable character) is read by gets and then printed to terminal.
NOTE: Never use gets function. It is no longer is the part of standard C. Use fgets instead.
I guess you can also use the scanf function to resolve your problem that the string is not accepting anything after a SPACE . Also, the loop is running (t-1) times because the buffer is not being cleared due to the use of gets() . In order to resolve this, you can use the getch() function to clear the buffer. The following code should work I guess,
#include <stdio.h>
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
char str[100];
scanf("%[^\n]c",&str);
printf("%s\n", str);
getch();
}
return 0;
}
In this code, the getch() will clear the buffer by accepting the useless value. Also as far as scanf() is considered, the ^ inside the scanf tells the function that it needs to take the input till the character after the ^ is encountered which in this case is an escape sequence of NEW LINE . I have tried using some small words as well instead of the newline and it has worked as well. Hope this clears your issue :)
Sorry for asking such a simple question, I'm still learning C and going through the basics first.
I'm creating a character counting program and yet when I execute the program and try to input "h" for example and then press enter a new line appears and nothing is outputted onto that line?
Code:
#include <stdio.h>
/* Copy input and count characters 2nd version */
main() {
double cc;
for(cc = 0; getchar() != EOF; ++cc);
printf("%.0f\n", cc);
}
Once you have finished entering characters, you have to signal the end of input stream by pressing Ctrl-D. Otherwise your program will continue waiting for more input.
P.S. Why are you using a double variable for the counter? An integer type would be more appropriate.
Maybe (I'm not sure what exactly do you want) you have an extra ; after the for(), which mean an empty statement. So your program will run the empty statement (in other words, do nothing) until the end of input (if the input is terminal, you may need a CTRL+D), and then print (once) the number of characters.
If you want your program to print the counter after every char in the input, remove that ;, so the printf will be in the loop.
Include this line at the end you will get output:
return 0;