Ignore whitespace getchar() - c

I am having trouble ignoring the whitespace/tab. When a user enters a character from a command prompt, it should only accept any characters except whitespace or tab spaces.
eg:
$ ./a.out Character: =
Then, it's =
if
$ ./a.out Character: =
With bunch of spaces, then it should detect as =
I have already declared variable a.
char a;
printf("Character: ");
a = getchar();
Code:
while((a = getchar()) != EOF){
if( a != ' ' || a != '\t'){
a = getchar();
break;
}
}
Any help would be great. Thanks.

Update: As chux observed, getchar() returns type int, and you cannot successfully read the full range of possible characters if you assign that result to a variable of type char. In fact (I add), you risk invoking implementation defined behavior by doing so. In short, variable a should have type int.
With that said, it looks like you want something along these lines:
do {
a = getchar();
} while (a == (unsigned char) ' ' || a == (unsigned char) '\t');
Note that EOF, differs from both ' ' and '\t', so you can safely defer testing for it until after the loop.
Note also that if you want to ignore newlines and other whitespace characters too, then you might get good use out of the standard isspace() library function.

How about:
#include <ctype.h>
int a;
do
{
a = getchar();
} while (isspace(a));
as EOF is not a whitespace character, you don't need to handle it specially.
You can put that in a little function of its own if you like:
int
getcharnospace()
{
int a;
do
{
a = getchar();
} while (isspace(a));
return a;
}

int a;
while(a=getchar()){
if(a==' ' || a=='\t')
continue;
else
putchar(a);
}

By using break, you stop the while loop. Use continue instead:
while((a = getchar()) != EOF){
if( a != ' ' || a != '\t') continue;
[...]
}

You can modify the while() loop body as
while((a = getchar()) != EOF){
if( a == ' ' || a == '\t')
continue; // if space ot tab is detetected, scan for next input
else
{
putchar(a); //neither a space nor a tab, print it.
break;
}
}
Also, as the return type of getchar() is int, you should use int a.

Space ' ' is not the only whitespace char in C.
Tab '\t' is one of C's whitespace char.
Use int ch rather than char ch to distinctly save all the different results from getchar().
isspace(EOF) is always false.
Use issapce(), it is the C standard function for detecting white-space.
// char a;
int a;
printf("Character: ");
// All that is needed to consume white-space characters
while(isspace(a = getchar()));

Related

The answer outputs blanks

Program task -
Enter a string, display it word for word on the screen.
The problem is that if you type a lot of spaces between words, they will show up when you check. How can this be fixed?
#include <stdio.h>
int main()
{
int inw = 0, i = 0, count = 0;
char s[10000];
printf("Print string (max 10000 sb):\n");
gets(s);
while (s[i] != '\0') {
if (s[i] != ' ' && s[i] != '\t') {
putchar(s[i]);
}
else if (s[i] == ' ') {
printf("\n");
}
i++;
}
return 0;
}
Ugly, but this gets the job done. Just need a flag to keep track of whether or not you just printed a new line. Also cleaned up unused variables and changed to using fgets
#include <stdio.h>
#include <stdbool.h>
int main()
{
int i = 0;
char s[10000];
bool justPrintedNewline = false;
printf("Print string (max 10000 sb):\n");
fgets(s, sizeof s, stdin);
while (s[i] != '\0') {
if (s[i] != ' ' && s[i] != '\t') {
putchar(s[i]);
justPrintedNewline = false;
}
else if (s[i] == ' ' && justPrintedNewline == false) {
printf("\n");
justPrintedNewline = true;
}
i++;
}
return 0;
}
Demo
You did a great job in the algorithm just fix a little thing.
You can create a flag and after space you increase the flag to 1.
Then you will know you will print just one space.
After printing " " check for a char that isn't " " for update the flag to 0.
When the flag is 1 DONT print anything just wait for another valid char.
Take care,
Ori
Only print a line-feeed when starting a word and after all is done.
Change code to:
If a space
-- print a '\n' when the prior character is a non-white-space.
Else
-- if (prior character is white-space) print a '\n'
-- print it
char prior = 'a';
while (s[i]) {
char ch = s[i];
if (ch != ' ' && ch != '\t') {
if (prior == ' ' || prior == '\t') {
putchar('\n');
}
putchar(ch);
}
prior = ch;
i++;
}
putchar('\n');
There is a bit of a trick to it: use a second, inside loop to skip past spaces and another to print words. The outer loop should only terminate if you have reached the end of the string.
while (s[i] != '\0')
{
// skip all spaces
while ((s[i] != '\0') && isspace( s[i] )) ++i;
// print the word
while ((s[i] != '\0') && !isspace( s[i] ))
{
putchar( s[i] );
}
// print the newline after a word
putchar( '\n' );
}
By the way, gets() is a really, really dangerous function. It should never have been included in the language. You are OK to use it for a homework, but in reality you should use fgets().
char s[1000];
fgets( s, sizeof(s), stdin );
The fgets() function is a bit more fiddly to use than gets(), but the above snippet will work for you.
Your other option for solving this homework is to use scanf() to read a word at a time from user input, and print it each time through the loop. I’ll leave that to you to look up. Don’t forget to specify your max string length in your format specifier. For example, a 100 char array would be a maximum 99-character string, so you would use "%99s" as your format specifier.

Read single key input from keyboard and evaluate it

I want to read one keyboard input - and depending whether it is valid or not proceed with the operation or do something else. If it's invalid the input should be repeated.
At this point I'm aware already scanf is not the tool of my desire, but that here would be the default-code (if scanf would work as intended):
char val;
int incorrect = 0;
printf("Do you wish to proceed?: <Yy/Nn>");
do
{
incorrect = 0;
scanf(" %c", &val); //Changed to " %c" alread from "%c"
//getchar(); //Tried already, doesn't solve the problem
if (!(val == 'y' || val == 'Y' || val == 'n' || val == 'N'))
{
printf("Invalide Input!\n");
incorrect = 1;
}
} while (incorrect);
The problem is if instead of a one-character input there is a longer input the error-message will be repeated by the number of the characters.
Also, if instead of for instance 'n' the input is "nasdlfjas" it is still considered as a valid input.
Changing the scanf to val = getchar(); if (kind != EOF) (with or without the EOF-part) as suggested here doesn't change the behavior. But the Error-message is added right after the question.
The "GetStuff()" from this solution suffers from the same problem. The error-output is multiple and one single correct character in the whole input determines the result.
This variant however is doing better, but evaluates the result on the first character of the entire string.
Other variants which include a while((c = getchar()) != EOF); which is the preferred variant to use getchar have similar issues of going through the loop-body before the input of the character (and therefore printing the error).
I decided to read a string instead of a character and then just evaluate the result by dealing with the string itself. Something like:
do{
int c, line_length = 0;
int i = 0;
while ((c = getchar()) != EOF && c != '\n' && line_length < MAX_LINE - 1)
{
sentence[i++] = c;
line_length++;
}
// String Stuff
if (!(val == 'y' || val == 'Y' || val == 'n' || val == 'N'))
{
printf("Invalide Input!\n");
incorrect = 1;
}
} while (incorrect);
But again there will "Invalide Input!" be printed before entering anything.
What exactly would be the proper way to evaluate just the input of a single character?

K&R C Exercise 1-9 *almost* solved

K&R C Exercise 1-9 states:
Write a program to copy its input to its output, replacing each string of one or more blanks by a single blank.
I have nearly solved this exercise, but the code I've written (see below) always prints an extra space before the first nonspace character. So input that looks like this
X(space)(space)X(space)(space)X(space)(space)X
results in output that looks like this
(space)X(space)X(space)X(space)X
#include <stdio.h>
int main()
{
int c; //current input character
int s; //consecutive input space counter
c = getchar();
s = 0;
while ((c = getchar()) != EOF){
if (c == ' '){
++s;
if (s == 1) //uses the counter to print only the
putchar(' '); //first space in each string of spaces
}
else {
putchar(c);
if (s != 0) //resets the space counter when it
s = 0; //encounters a non-space input character
}
}
return 0;
}
Why does my code always print a leading space when I run it?
How can I modify this code to print the first input character first instead of a leading space?
Do not throw away the first char. #David Hoelzer
// Commented out
//c = getchar();
s = 0;
while ((c = getchar()) != EOF){
Also note unbalanced } near return 0;

' ', '\n' , scanf() and output screen

I wrote the following code to accept characters from user and enter into an array till he inputs a free space (' ') or a line \n. But code is not functioning. As in, when space bar or return key is pressed in the input, my computer is still accepting values without exiting the loop.
char X[99];
printf ("Type the string without spaces\n");
for (i=0;i<99;i++) {
scanf ("%c",&m);
if(m!=' '&&m!='\n')
X[i]=m;
else i=99;
}
Please explain the error.
First the issue: the default tty mode is canonical, meaning input is made available line by line (see man termios)
Once you fix that, you can use getchar() or read() to get one character at a time. The tty setting, example straight out of the man page of termios .
#include <stdio.h>
#include <termios.h>
int ttySetNoncanonical(int fd, struct termios *prev)
{
struct termios t;
if (tcgetattr(fd, &t) == -1)
return -1;
if (prev != NULL)
*prev = t;
t.c_lflag &= ~ (ICANON);
t.c_cc[VMIN] = 1; // 1-char at a go
t.c_cc[VTIME] = 0; // blocking mode
if (tcsetattr(fd, TCSAFLUSH, &t) == -1)
return -1;
return 0;
}
void main(void) {
printf ("\nType the string without spaces\n");
ttySetNoncanonical(0,NULL); // set to non-canonical mode
char X[1000];
int m, ec=0;
int i;
X[0] = 0;
for (i=0;i<1000;i++) {
//ec = read(0,X+i,1); // read one char at a time
m = getchar();
if(m == EOF || m==' ' || m=='\n') {
X[i] = 0;
break;
}
X[i] = m;
}
printf("You entered %s. Bye.\n\n", X);
}
HTH. You might want to check the boundary condition, in case your user typed in 1000 characters. It works for me on a GNU Linux.
use getch(), scanf() will not work that way.
it would be something like :
for(i=0;i<99;i++)
{
char ch=getch();
if(m!=' ' && m!='\n' && m!='\r')
X[i]=m;
else i=99;
printf("%c",ch);
}
The scanf function reads and ignores any whitespace characters encountered before the next non-whitespace character (whitespace characters include spaces, newline and tab characters). So, instead of
scanf("%c",&m);
use
m = getchar();
The function int getchar ( void ); gets character from stdin, returns the next character from the standard input (stdin). It is equivalent to calling getc with stdin as argument.
Also, the condition should use logical-AND as in:
if(m!=' '&& m!='\n')
Also, outside the loop, write,
X[i] = '\0';
Lets look into the if condition
if(m!=' '||m!='\n')
1. When m is space m=' ' (i.e. ASCII value 32)
m=' '
As per your if condition (Cond1 || Cond2), Cond1 will fail and o/p will be 0 but Cond2 will be TRUE, because it is not ' '.
if(FALSE || TRUE)
will be if(TRUE).
When your input is newline (i.e ASCII value 10).
m='\n'
Here Cond1 will be TRUE because it is not SPACE, due to this it will not check the second condition as per C. and will execute the if(TRUE) statement.
Please try to code it by yourself.... It will help you to clear few C doubts and u will get to know how || and && condition works.
Better to use getchar() instead of scanf in here as you read character by character. Usually we use scanf for get strings as input.
Using the logical operators: && (AND) operator checks for one condition to be false, while or || (OR) operator checks for one condition to be true. So if you use && operator, it checks whether it is a space, and if not, it returns false, without even checking the second condition(EOF). But if you use || operator, as used below, it checks for both cases. Check for more details in operators here
You also have to increment the counter (i) after adding an item to the array (Inside the if) as if you don't, it will continuously add items to the same place of the array, which means you will lost the precious inputs.
So, here's my code:
char X[99];
char m;
printf ("Type the string without spaces\n");
for (i=0;i<99;i++) {
m = getchar();
if(m == ' ' || m=='\n') {
X[i]=m;
i++;
}
else i=99;
}
With the function getch(); it ends if your pressing space or enter!
#include <stdio.h>
int main(void) {
char m, X[99];
int i;
printf("Type the string without spaces\n");
for (i = 0; i < 99; i++) {
m = getch();
if (m == ' ' || m == '\n' || m == '\r')
i=100;
else
X[i] = m;
printf("%c", m);
}
}
try this
#include <stdio.h>
int main(){
int i;
char m, X[99];
printf("Type the string without spaces\n");
for (i=0;i<98;i++){//98 --> sizeof(X) -1
scanf("%c",&m);
if(m!=' ' && m!='\n')
X[i] = m;
else
break;
}
X[i] = '\0';
puts(X);
return 0;
}
Here's a working code:
#include <stdio.h>
int main ()
{
char x[100] = {0};
char m;
int i, j;
printf ("Type:\n");
for (i=0; i<99; i++) {
m = getchar();
getchar();
if ((m != ' ') && (m != '\n')) {
x[i] = m;
} else {
printf ("Breaking.");
break;
}
}
printf ("\n");
for (j=0; j<i; j++)
printf ("%c\n", x[j]);
return 0;
}
Here I have used an extra getchar() to consume the newline used to enter the character m. And so (please note) you will also need to enter a newline after a space (' ') and a newline ('\n') to enter and store these in m and compare them in the next lines.
First error, as everyone has pointed out is the logical operator in the if() statement. It should be
if(m!=' ' && m!='\n')
As you want to check if the entered character is neither a (space) nor a \n, so you have to use the && operator.
Next, the error you are getting is because of something called the trailing character. When you enter a letter and press enter (at the point where your scanf("%c",&m) is asking for input). That letter gets stored in the variable m, but the newline character \n caused by the enter pressed is still in the stdin. That character is read by the scanf("%c",&m) of the next iteration of the for loop, thus the loop exits.
What you need to do is consume that trailing character before the next scanf() is executed. for that you need a getchar() which does this job. So now your code becomes something like this..
#include<stdio.h>
int main()
{
char X[99];
char m;
int i;
printf("Type the string without spaces\n");
for (i=0;i<99;i++)
{
scanf("%c",&m);
if(m!=' ' && m!='\n')
{
X[i]=m;
getchar(); // this statement is consuming the left out trailing character
}
else
i=99;
}
printf("%s",X);
}
Now, the program works exactly as you want.

Only print words that start with a specified letter out of a string in C language

I need to write a function that will print words that start with specified letter inside a string.. my problem is that once i try to print a words, the function never stop.
Here is the code: (printWords is the functions, printWord is a helper)
#include <stdio.h>
#include <string.h>
typedef char string[50];
void printWord(int *index, string sentence)
{
while (sentence[*index] != ' ' || sentence[*index] != '\0')
{
printf("%c", sentence[*index]);
*index += 1;
}
}
void printWords(char letter, string sentence)
{
int i = 0, *iPtr = &i;
if (sentence[0] == letter || sentence[0] == letter + 32)
printWord(iPtr, sentence);
for (; sentence[i] != '\0'; i++)
if ((sentence[i] == ' ' && sentence[i+1] == letter) || (sentence[i] == ' ' && sentence[i+1] == letter + 32))
printWord(iPtr, sentence);
}
void main()
{
char ex1_letter;
int menu;
string ex1_sentence;
printf("\n\nPlease enter a string: ");
gets(ex1_sentence);
printf("\nPlease enter a letter: ");
scanf("%c", &ex1_letter);
printWords(ex1_letter, ex1_sentence);
}
The condition in the loop never seems to happen and i just don't know why..
Any help would be appreciated!
Your main error is using || insted of && in printWord. With || the condition will always be true since the character will always not be either space or the null character.
Some other points:
It's more portable for main to return an int (and have a return 0; at the end).
Use of gets is discouraged as it allows buffer overruns. fgets is more secure, but beware that it leaves the newline character at the end of the string.
Don't do things like letter + 32. Instead, use the functions in ctype.h. In this case, use tolower or toupper.
Instead of passing i as a pointer, just pass it as an int and return the changed value.
Don't use printf and scanf to print/scan a single character. Instead use putchar and getchar.
Use ++i instead of i += 1.
Your typedef just obscures things. If the declaration of (e.g.) printWords is void printWords(char letter, char *sentence) then a C programmer knows what's going on right away without having to know what string is. The typedef really adds nothing.
In your printWord method:
while (sentence[*index] != ' ' || sentence[*index] != '\0')
This conditions will always be true. Change it to &&: print as long it is not a space AND not the end of string, like this:
while (sentence[*index] != ' ' && sentence[*index] != '\0')

Resources