I just want to read in a char from stdin, if it is a space, do something, if it is a newline, do something else. What is happening with my current code is if I enter a space, then hit enter, the ' ' case is satisfied which is what I want, but the '/n' case is also satisfied after that. I don't want to read in the space and the newline, all I care about is the space. How do I fix this? Here is my code:
int input = getc(stdin);
switch (input) {
case 'q':
return 1;
break;
case ' ':
printLines(fp);
break;
case '\n':
printLine(fp);
break;
default:
getResponse(fp);
break;
}
If you are reading each user provided space or q in a seperate line, thus expecting a newline after each character, remember to discard it after parsing the character:
int input = getc(stdin);
switch (input) {
case 'q':
getc(stdin);
return 1;
case ' ':
getc(stdin);
printLines(fp);
break;
case '\n':
printLine(fp);
break;
default:
getResponse(fp);
break;
}
Note that with this solution, if the user enters two characters followed by enter, the program will discard the second character but process the first one and the enter. Thus you may need to implement discarding not only the second character but the whole line.
Assume the following is your input to stdin:
a\n
b\n
\n
c\n
In order to distinguish whether or not a "line" of input is empty (only a '\n') or an actual character was input (a character followed by a '\n') you could either:
Store the previous char read from stdin, and if it was '\n' you could assume that an empty line was input (with the exception for the first time taking input). If not, you're still on the same line you were previously reading.
Continue reading from stdin after reading a char until you read the '\n', so that when you take input next time you won't read a '\n' unless an empty line was input.
Not sure if I understood your problem but this will print 1 if input contains ' ' (even if there has been a '\n' afterwards) and 2 if input has '\n' but no ' ':
#include <stdio.h>
int foo() { return 1; }
int bar() { return 2; }
int main()
{
char input = 'c';
while(input != ' ' && input != '\n')
input = getc(stdin);
(input == ' ') ? printf("%d\n", foo()) : printf("%d\n", bar());
return 0;
}
The first time I typed some words separated by space and then Enter, the second time the input deliberately lacked a ' '.
$ ./a.out
test test
1
$ ./a.out
asdsadasdasdasdsadasddsda
2
$
scanf("%c\n",&c);
if(c==' ')
{
//the input was a space
}
if(c=='\n')
{
//the input was a newline
}
Related
So I've tried so much but I can't input a string even using: fgets, gets, scanf, and scanf("%[^\n]%*c",pharse). I need a string with the spaces. It just jumps the code line of input I think.
Please answer with a explanation of why it doesn't work
https://repl.it/#YashKumar11/String#main.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
const int DIMMAX=100;
char pharse[DIMMAX+1];
int stringLength;
int choice=0;
while(choice != '5'){
printf("1)Enter a new pharse.");
printf("\n2)");
printf("\n3)");
printf("\n4)");
printf("\n5)\n");
scanf("%d",&choice);
switch(choice){
case 1:
printf("\n=====================\n");
scanf ("%[^\n]%*c",pharse); //<-----------------------It jumps here
printf("\n=====================\n");
stringLength = strlen(pharse);
printf("%s",pharse);
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
default:
printf("\nNot a valid option.\n\n");
break;
}
}
return 0;
}
the statement to input the parase fails because the input for choice leaves a \n in the input stream.
When the second call to scanf() is made, it immediately returns (with a returned value of 0) because the first character input is \n.
suggest following each call to scanf() with:
int ch;
while( (ch = getchar()) != '\n' && ch != EOF );
that also implies that the format string of the second call to scanf() should have the %*c removed.
Your problem is not in the line that you try to read the string, but in the previous call to scanf()
scanf() was written to scanf formatted input. Keyboard input is not that. It can be everything except formatted. The user has over 100 keys to choose from
When the user types a '1' to input a phrase scanf() does not consume the newline. In fact the user can type 1 here we go to enter some text!
and then ENTER. And scanf() will be ok with just the '1'. The rest of the chars would be left there for the program to read. scanf() has no way to know what is left there.
Also scanf() return an int with the number of values read, and it can be zero if the user entered no digits. And you did not tested in your code.
Compare with your code a bit modified below
#define DIMMAX 100
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
char phrase[DIMMAX + 1];
int stringLength;
printf("1) Enter a new phrase");
printf("\n2)");
printf("\n3)");
printf("\n4)");
printf("\n5) Exit\n\nOption: ");
fgets(phrase, DIMMAX, stdin);
while (phrase[0] != '5')
{
switch (phrase[0]) {
case '1':
printf("\n=====================\n");
fgets(phrase, DIMMAX, stdin);
printf("\n=====================\n");
stringLength = strlen(phrase);
phrase[strlen(phrase) - 1] = 0; // deletes the '\n'
printf("Phrase: '%s', len = %zd\n\n", phrase, strlen(phrase));
break;
case '2':
break;
case '3':
break;
case '4':
break;
case '5':
break;
default:
printf("\n'%c' (dec %d) is not a valid option.\n\n",
phrase[0], phrase[0]);
break;
}
printf("1) Enter a new phrase");
printf("\n2)");
printf("\n3)");
printf("\n4)");
printf("\n5) Exit\n\nOption: ");
fgets(phrase, DIMMAX, stdin);
}; // while()
return 0;
}
Maybe it helps to understand.
Note that instead of stopping rigth at the digit, like scanf(), fgets() read up to and including the newline, so if you are using printf() and not puts() to output it, you must take the last byte off the string read
Here I want to compare two strings in case2. case 1 works well but when I go to case 2 it's not asking for second string input and directly prints "Both strings are different"[1]
[1]: https://i.stack.imgur.com/l2J6L.jpg
#include <stdio.h>
#include <stdlib.h>
#define size 20
int main ()
{
char str1[size],str2[size];
int operation,error=0,i=0;
printf("Enter String: ");
fgets(str1, size, stdin);
do {
printf("1.Copy\n2.Compare\n3.Exit\nWhich operation you want to do:");
scanf("%d",&operation);
switch (operation) {
case 1:
for (int i=0; str1[i] != '\0'; i++) {
str2[i] = str1[i];
}
printf("First string: %s\n",str1);
printf("Second string: %s\n",str2);
break;
default:
printf("Error");
break;
case 2:
printf("Enter second string: "); // it's not executing (Not takin input) and directly i get o/p of line 39
fgets(str2, size, stdin);
for (i=0; str2[i] != '\0'; i++) {
if (str1[i] != str2[i]) {
error++;
}
}
if (error == 0) {
printf("Both strings are same.\n");
}
else
printf("Both strings are not same.\n");
break;
}
} while (operation != 3);
}
As scanf leaves behind a dangling newline character \n it causes the fgets to not wait for the input from the user. Try flushing the input buffer by using getchar.
Update: Added loop to remove all the characters which are skipped by the scanf but can be entered by the user like extra white spaces after the number.
...
do {
printf("1.Copy\n2.Compare\n3.Exit\nWhich operation you want to do:");
scanf("%d",&operation);
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
switch (operation) {
...
Reference: faq.cprogramming.com
Since your strings are lines, scanf() is not a good choice except for getting the integer value, and to clean the buffer of everything after that (might be all sorts of junk, never trust a user), do a fgets into str2. Your new lines will compare, too, if they are identical. You should also test the return from scanf is 1, saying you got a number! What if a user types in 'x' as the number? If you want to ask again, you need to clean the junk out of the buffer. Remember that, since you have 'cooked' input, nothing is sent until the user hits enter, so you always need to deal with the new line character. If all you do is scanf in numbers, scanf will got through an new line as white space seeking a digit, but you are doing mixed string and number input.
You need to compare a null to mis-compare if one string is a prefix of the other, so in 'for' test 'i < size' but break out of the loop if both strings have a null at the same point ( !str1[i] && !str2[i] ) or on the first miscompare (setting error). There is no point in comparing past the first miss! In the prefix case, the null mis-compares some other char value.
Since trailing spaces are part of your string, you might print them in single quotes (after removing the new line).
I'm trying to write a short program that puts each word on a new line. The new line can be confirmed by tabulator, space or enter. The end of program is putting "#" in console. I have the problem that when I put "enter" to the console it writes next characters in the same line.
The second idea is to make all of this in a table, so I can put formatted text all together in the end. I can't figure this out either.
#include<stdio.h>
#include <conio.h>
#define STOP '#'
int main()
{
char ch;
while ((ch = (_getch())) != STOP) {
switch (ch) {
case '\n':
printf("\n");
break;
case '\t':
printf("\n");
break;
case ' ':
printf("\n");
break;
default:
putchar(ch);
}
}
printf("\nEND");
_getch();
return 0;
}
Because hitting "enter" issues a carriage return char (\r), not a linefeed one.
I noticed it when the cursor jumped back at the start of the line when I pressed "enter".
Fix your code like this (factorize the case statements too):
#include<stdio.h>
#include <conio.h>
#define STOP '#'
int main()
{
char ch;
while ((ch = (_getch())) != STOP) {
switch (ch) {
case ' ':
case '\t':
case '\r': // what was missing
printf("\n");
break;
default:
putchar(ch);
}
}
printf("\nEND");
_getch();
return 0;
}
You probably get a carriage return ('\r') which is what Return typically generates.
So you need to check for that, too. Your code can be simplified:
int main(void)
{
while((ch = _getch()) != STOP)
{
if(ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')
ch = '\n';
putchar(ch);
}
}
Since we're always printing exactly one character per iteration, no need to use multiple printing functions. Also, using printf() to print a single constant character is overkill.
I have a problem with the input for a postfixed notation calculator in C.
My teacher asked me to use scanf("%s",token) to get the input. To stop reading tokens, I check if the value returned by scanf is EOF. It works if I use input redirection when testing, but if I write the expression on the Windows cmd I fall into an endless loop. How can I stop scanf when I simply press enter without entering a string?
Here's the code:
#include <stdio.h>
#include <ctype.h>
#include "stack.h"
int main(){
int a,b,t,stop;
char token[10],c;
do{
stop = scanf("%s",token);
if (stop == EOF){
break;
}
if (isdigit(token[0])){
t = atoi(token);
push(t);
}else{
a = top();
pop();
b = top();
pop();
c = token[0];
switch(c){
case '+': t = a + b;
break;
case '-': t = a - b;
break;
case '*': t = a * b;
break;
case '/': t = a / b;
break;
}
push(t);
}
} while(1);
printf("Result: %d\n",top());
}
The problem is in the if block after the stop variable inizialisation, I think. Sorry for my English, I'm an Italian student, I tried to be as neat as I can.
"How can I stop scanf when I simply press enter without entering a string?"
Using scanf() to read '\n' (Enter) is challenging. fgets() or fgetc() is a better approach. But the following shows how to nearly do it with scanf().
The %s in scanf("%s",token); first consumes leading white-space including '\n'. Code must first detect any potential '\n' before calling scanf("%s",token);.
char ws[2];
// Consume white-space, but not \n
scanf("%*[ \f\r\t\v]"); // Depending on locale, this may not be a complete list
if (1 == scanf("%1[\n]", ws) {
break;
}
stop = scanf("%s",token);
if (stop == EOF){
break;
}
A cleaner way to do this.
int ch;
while (isspace(ch = fgetc(stdin)) && ch != '\n');
if (ch == '\n') {
break;
}
ungetc(ch, stdin);
stop = scanf("%s",token);
if (stop == EOF){
break;
}
Only one more question: to stop the program, I had to type ctrl+z
twice. Can you tell me why?
Usually the C standard input in line buffered text mode is implemented by calling a system specific function which reads a line and returns the number of characters in it (including the newline character); when the number 0 is returned, this is considered EOF. Now, when you enter "3 5 +(crtl+z)(ctrl+z)", the first Ctrl-Z ends the input line and causes the reading function to return 5, but this does not indicate EOF to the standard input functions; only after the second Ctrl-Z ist pressed without intervening input, 0 is returned and recognized as EOF.
I have been asked to write a function that returns the first non-whitespace character in an inputted string.
It's working when I enter something like "hello" or anything that does not begin with a white space. But when I enter something like " hello", it returns a white space.
Here is my code:
int question6()
{
printf("Start typing stuff in \n");
char myChar = returnFirstNonWhite();
printf("First non-white space character is: %c",myChar);
}
int returnFirstNonWhite()
{
int ch,temp;
ch = getchar();
while (ch != 32)
{
temp = ch;
printf("Found first success %c\n", ch);
}
return temp;
}
ch = getchar();
while (ch == 32)
{
ch = getchar();
}
return ch;
One easy option would be to use scanf() instead of getchar(). scanf() will take a string (so there's no need to loop getting chars) and it will strip off any starting white space, so you just need to grab the first character it has.
int returnFirstNonWhite()
{
char str[50];
memset(str, '\0', 50);
scanf("%s", str);
return str[0];
}
so
>> hello
will return 104 (ascii 'h')
At first you are taking only one character input. And if it is not equal to 32 int value, the program should be in a infinite loop!!!! This is a nothing code.
Everything here appears to be okay, except in your while loop you don't continue to fetch the next character. In other words, it fetches the initial character, let's say a whitespace, and then continues in that while loop forever since the ch variable is never changed.
Try adding ch = getchar(); within your while loop so it continually fetches the next character to check. Also, I just realized you need to check that the character is equal to 32, not not equal so that if the character is a whitespace it continues to fetch the next character.