C language :Scanning input from Eclipse console [duplicate] - c

This question already has answers here:
C/C++ printf() before scanf() issue
(2 answers)
Closed 4 years ago.
I am a java programmer and started learning C recently. I was going through headfirst C and wrote one of the example programs in Eclipse (with CDT). Here is the program
#include <stdlib.h>
#include <stdio.h>
int main()
{
char card_name[3];
puts("Enter the card_name: ");
scanf("%2s",card_name);
int val = 0;
if(card_name[0] == 'K'){
val = 10;
}else if (card_name[0] == 'Q'){
val = 10;
}else if(card_name[0] == 'J'){
val = 10;
}else if(card_name[0] == 'A'){
val = 11;
}else{
val = atoi(card_name);
}
printf("The card value is: %i\n",val);
return 0;
}
When I run it on eclipse, the line containing puts should be executed and then the user should enter in eclipse console and then the scanf line should execute.
But it doesn't happen that way, when I run it, it just expects the user to enter first on the eclipse console, then execute the puts line and finally the scanf line. I couldn't understand this behavior. Can someone help me on this ?

Depending on how the buffering of the output is configured, you might nee to be very explicit about when to actually make the output.
Usually a newline at the end of text is sufficient, i.e. there must be something special in your environment, I suspect the Eclipse console, but that is just guessing.
Especially when attempting to do prompt and reading within one line, it is wise to use a
/* ... */
puts("Enter the card_name: ");
fflush(stdout);
/* ... */
at exactly the point where you need the output you have already send.
In your case the buffering causes this sequence:
put the prompt in output buffer
environment is configured not to automatically output immediatly
(this is where I propose to flush in order to get output)
scanf is executed
user input
your program does not do anythign visible, though executing completly
put the final message into output
ending the program causes final output of anything buffered
I.e. the scanf is not executed before the first puts, it is only the visible effect which gets delayed.

Related

C program command prompt closing within an if statement rather than pausing at the end of main()

I'm following along the Head First C (2012) and am running into an issue with their initial "cards.c" project in the first chapter.
Basically, the code asks for an input for a type of card then outputs a value based on whatever the user entered. However, I find that the command prompt exits automatically after executing the corresponding if statement even if I tell the program to pause or check for a key input at the end of the main() function.
I've made a half-fix by including the output of the card's value within the if statement such as
if (card_name[0] == 'K') {
val = 10;
printf("The card value is: %i\n", val);
system("pause");
}
Yet I find the output will occur twice if I leave the printf statement and system pause both within the for bracket and at the end of main. As such, I'm confused why the command prompt is automatically closing when I only output at the end of main rather than inside of each if/else if/else statement.
For reference, I am running through Visual Studio Code on Windows 10 and am using MinGW to compile (Which VSCode allows me to build with, but I run through a command prompt).
#include <stdio.h>
#include <stdlib.h>
int main()
{
char card_name[3];
puts("Enter the card name: ");
scanf("%2s", card_name);
int val = 0;
if (card_name[0] == 'K') {
val = 10;
} else if(card_name[0] == 'Q') {
val = 10;
} else if(card_name[0] == 'J') {
val = 10;
} else if(card_name[0] == 'A') {
val = 11;
} else {
val = atoi(card_name);
}
printf("The card value is: %i\n", val);
system("pause");
return 0;
}
For anyone reading, this is exactly how the code appears in the book outside of the system pause at the end of main(). I apologize if this is too basic of a question, but I have yet to find an answer after an hour of searching on this site.
I was able to get it working using the advice provided by paddy to use fgets instead of just printing as my character was being eaten by the buffer while passing. I also launched directly through the command line as my setup for VSCode wasnt done properly and was running into issues itself trying to run the compiled exe.

Why my little C game ignore player's first attempt? [duplicate]

This question already has answers here:
Why doesn't getchar() wait for me to press enter after scanf()?
(10 answers)
Closed 3 years ago.
I'm learning programmation in C and tried to create a program that asks the user his age. When the user writes his age (for example 18) he gets the message "So you're 18 years old". When I execute the .exe file it automatically closes after you see the message, so fast that you don't see it. Then I added getchar so that the user reads the message and then presses Enter to quite. Here's the program I wrote:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int age=0;
printf("How old are you?\n");
scanf("%d",&age);
printf("So you're %d years old", age);
getchar();
return 0;
}
Unfortunately, when I execute the .exe file, it still closes automatically like if the getchar() doesn't exist and I don't know why.
scanf("%d",&age);
When the execution of the program reaches the above line,you type an integer and press enter.
The integer is taken up by scanf and the \n( newline character or Enter )which you have pressed remains in the stdin which is taken up by the getchar().To get rid of it,replace your scanf with
scanf("%d%*c",&age);
The %*c tells scanf to scan a character and then discard it.In your case,%*c reads the newline character and discards it.
Another way would be to flush the stdin by using the following after the scanf in your code:
while ( (c = getchar()) != '\n' && c != EOF );
Note that c is an int in the above line
You're only having trouble seeing the result because you're starting the program from a windowing environment, and the window closes as soon as its internal tasks are completed. If you run the compiled program from a command line in a pre-existing shell window (Linux, Mac, or Windows), the results will stay on the screen after you're returned to the prompt (unless you've ended by executing a clear-screen of some sort). Even better, in that case, you don't need the extraneous getchar() call.
For Windows, after opening the command prompt window, you'd issue a "cd" command to change to the directory that contains the compiled program, and then type its name. For Linux (and, I presume, Mac, since Mac is UNIX under the hood), you'd need to type ./ ahead of the program name after changing to the appropriate directory with "cd".

Using control+D (EOF) but return an unexpected character D [duplicate]

This question already has answers here:
Simple program adding "D" to output
(3 answers)
Why does C program print 0D instead of 0? (When EOF sent as Ctrl+D) [duplicate]
(1 answer)
Closed 5 years ago.
I was coding a very simple programme to detect word pattern by entering to stdin and return the times found the pattern.
However the code return me the correct number but follow a char D.
#include <stdio.h>
#include "string.h"
#define MAXLINE 1000 /* maximum input line length */
char pattern[] = "ould"; /* pattern to search for */
/* print all lines from standard input that match pattern */
int main()
{
char line[MAXLINE];
int found = 0;
while (fgets(line, MAXLINE, stdin) != NULL)
if (strstr(line, pattern) != NULL) {
printf("%s", line);
found++;
}
printf("%d \n", found);
return 0;
}
Result:
glaroam2-180-76:Lab2 apple$ ./find0
fould
fould
1D
The code is correct (apart from the #include "string.h" which should be
#include <string.h>)1, the problem is that when you press
Ctrl+D on your terminal, your terminal might write
something on the terminal, which you cannot control and this output might be
^D
After fgets returns NULL, you do printf("%d \n", found); which prints the '1'.
But because there was ^D on the terminal, the ^ was replaced by the '1' and
you end up with:
1D
Change your last printf to this:
printf("\n\n%d \n, found);
And you might see only a '1' in the next lines of the output.
This has nothing to do with your C program, it's the behaviour of your terminal.
My terminal for example doesn't print when pressing Ctrl+D,
but when pressing Ctrl+C I get ^C. There's nothing you
can do.
edit
With There's nothing you can do I mean that you cannot control the way the
terminal from you C program without calling external tools like stty. While
this might solve your problem, you are loosing portability.
However, before you start you program, you can configure your terminal using a
program like stty. See Jonathan Leffler's answer for more info on that.
Fotenotes
1As Jonathan Leffler points out in the comments, using quotes instead
of angle brackets for system headers is not an error per se. For example my GCC
compiler searches in the same directory of the compiled file for headers that
were included with quotes. But in general, it's a good practice to include the
header files included provided by your system with angle brackets.
It's a terminal setting: echoctl. It means that when you type Control-D, the terminal echoes ^D, and then the 1 overwrites the ^. Try using:
stty -echoctl
and then rerunning your program.
With that said, I'm surprised that the D isn't wiped out by the blank after the %d in the format string. I suspect your actual code may be missing that. When I tested on my Mac, the program with the space after the %d did not show the D for long enough for me to spot it; when I removed that space, I got the output shown in the question.

Count number of blanks, spaces, and tabs in C [duplicate]

This question already has answers here:
How to send EOF via Windows terminal
(3 answers)
Closed 5 years ago.
I am working through K&R's exercises right now and I am at the one where you count the number of blanks, spaces, and tabs using the C language. I have built the following code:
#include <stdio.h>
#include <stdlib.h>
/*Write a program that counts blanks, tabs, and newlines*/
int main()
{
int c, numblanks, numtabs, numnewlines;
numblanks = 0;
numtabs = 0;
numnewlines = 0;
printf("Enter some text and press \"Enter\"\n");
while ((c = getchar()) != EOF) {
if (c == ' ')
++numblanks;
if (c == '\t')
++numtabs;
if (c == '\n')
++numnewlines;
}
printf("The total number of blanks is %i\n", numblanks);
printf("The total number of tabs is %i\n", numtabs);
printf("The total number of new lines is %i\n", numnewlines);
}
I am using Codeblocks and the built-in GCC compiler that is installed with it on a Windows 10 OS. When I run the program, I type some text into the program window that pops up and press "Enter" and nothing happens. I am not sure why. I was wondering if someone could help me get another pair of eyes on my code to see if there is something I am missing. Here is an image of what happens in the program when I run it:
Program window with typed text, but no reaction
I have not tried your solution but sometimes this can happen when the program is finished, the terminal closes. Try to put a getchar at the end of your program.
printf("Enter key to exit");
getchar();
This can help after string input (but sometimes require creating loop with getchar() and checking the result of this function)

I'm hitting a segmentation error when I scanf(%s,lastName); (body code inside)

EDIT: About to try intilizing my chars properly... [didnt work=( ]
EDIT: SOLVED (I can't answer my own question for another 7 hours...)
Thanks for the comment Brian, that's just a constant declared at the top.. (it = 20).
It turns out the error was happening because I forgot to add a next line after I took in the input name.
it's working now =D
:ENDEDIT (lol)
I've code my code below, Basically I put in the first name this is supposed to find
John
Then I put in the last name...
Locke
and as soon as I enter in "Locke" it hits this error, I feel like maybe it's the scanf and I should be using a better alternative ???
int findPatron(struct Library *lib,struct Patron **p)
{
int i;
char firstName[NAME_LENGTH], lastName[NAME_LENGTH];
printf("\nPlease enter the patron's first name: ");
scanf("%s",firstName);
printf("\nPlease enter the patron's last name: "); //this line prints...
scanf("%s",lastName); //SEGMENTATION ERROR happens here I'm pretty sure.
printf("deerrrr"); //this line never prints
for(i = 0; i<lib->totalPatrons;i++)
{
printf("checking %s %s to %s %s",lib->patrons[i].name.first,lib->patrons[i].name.last,firstName,lastName);
if((strcmp(lib->patrons[i].name.first, firstName) == 0) && (strcmp(lib->patrons[i].name.last, lastName) == 0))
{
**p = lib->patrons[i];
return 0;
break;
}
}
return 1; //No Match!
}
You're getting the segmentation fault after your scanf() statements.
If you remove everything after printf("deerrrr"); and add a \n to that output so the buffer is flushed, you'll find that it all works just fine (provided NAME_LENGTH is at least 6 given your example input).
Part of programming is knowing how to isolate and debug your problems.
Your issues are with your loop and lib struct - you're dereferencing something you shouldn't be.
SEGMENTATION ERROR happens here I'm pretty sure
this line never prints
C's printf is buffered, and only gets flushed by an explicit call to fflush or a blocking action (like scanf, which AFAIK flushes stdout as well), so the error could happen in another place. Learn to use debugger, that's the proper way of debugging C programs.

Resources