C - Return the first non-whitespace character - c

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.

Related

Issues with scanf() and accepting user input

I am trying to take in user input with spaces and store it in an array of characters.
After, I want to take in a single character value and store it as a char.
However, when I run my code, the prompt for the character gets ignored and a space is populated instead. How can I take in an array of chars and still be allowed to prompt for a single character after?
void main()
{
char userIn[30];
char findChar;
printf("Please enter a string: ");
scanf("%[^\n]s", userIn);
printf("Please enter a character to search for: ");
scanf("%c", &findChar);
//this was put here to see why my single char wasnt working in a function I had
printf("%c", findChar);
}
scanf("%c", &findChar); reads the next character pending in the input stream. This character will be the newline entered by the user that stopped the previous conversion, so findChar will be set to the value '\n', without waiting for any user input and printf will output this newline without any other visible effect.
Modify the call as scanf(" %c", &findChar) to ignore pending white space and get the next character from the user, or more reliably write a loop to read the read and ignore of the input line.
Note also that scanf("%[^\n]s", userIn); is incorrect:
scanf() may store bytes beyond the end of userIn if the user types more than 29 bytes of input.
the s after the ] is a bug, the conversion format for character classes is not a variation of the %s conversion.
Other problems:
void is not a proper type for the return value of the main() function.
the <stdio.h> header is required for this code.
Here is a modified version:
#include <stdio.h>
int main() {
char userIn[30];
int c;
char findChar;
int i, found;
printf("Please enter a string: ");
if (scanf("%29[^\n]", userIn) != 1) {
fprintf(stderr, "Input failure\n");
return 1;
}
/* read and ignore the rest of input line */
while ((c = getchar()) != EOF && c != '\n')
continue;
printf("Please enter a character to search for: ");
if (scanf("%c", &findChar) != 1) {
fprintf(stderr, "Input failure\n");
return 1;
}
printf("Searching for '%c'\n", findChar);
found = 0;
for (i = 0; userIn[i] != '\0'; i++) {
if (userIn[i] == findChar) {
found++;
printf("found '%c' at offset %d\n", c, i);
}
}
if (!found) {
printf("character '%c' not found\n", c);
}
return 0;
}
scanf("%[^\n]s", userIn); is a bit weird. The s is guaranteed not to match, since that character will always be \n. Also, you should use a width modifier to avoid a buffer overflow. Use scanf("%29[^\n]", userIn); That alone will not solve the problem, since the next scanf is going to consume the newline. There are a few options. You could consume the newline in the first scanf with:
scanf("%29[^\n]%*c", userIn);
or discard all whitespace in the next call with
scanf(" %c", &findChar);
The behavior will differ on lines of input that exceed 29 characters in length or when the user attempts to assign whitespace to findChar, so which solution you use will depend on how you want to handle those situations.

Program is not accepting second string and giving output directly

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).

stopping scanf on pressing enter

I am writing a C program which takes string input and print each word in a separate line. But the program is not stopping even after pressing enter. Please suggest a solution.
#include<stdio.h>
#include<string.h>
int main(void)
{
char str[50];
while(scanf("%s",str)&&strcmp(str,"\n"))
printf("%s\n",str);
}
You need to use fgets to read the line and if the input is just a single character which is newline character then break else keep continuing.
while(fgets(str,sizeof(str),stdin))
{
if(strcmp(str,"\n") == 0)
break;
else
{
size_t n = strlen(str);
if(n>0 && str[n-1] == '\n')
str[n-1] = '\0';
printf("%s\n",str);
}
}
PS: fgets() comes with a newline character and we need to supress the newline character as shown above.

Tokenizing a string

I am in the process of writing a C program that parses a string and tokenizing it by breaking the string characters into words that are seperated by white space. My question is when i run my current program:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char input[20];
printf("Please enter your word:\n");
scanf("%c", &input);
printf("%c", input[1]);
return 0;
}
If i was to enter the word "This", i would expect to get back "h" when i run the program but instead i get a downwards pointing arrow. However, when the input is set to print out input[0] i get back a "T".
Edit: I have modified my code so that it prints out the whole string now which i will show below
int main()
{
char input[20];
printf("Please enter your words:\n");
scanf("%s", input);
printf("%s", input);
return 0;
}
My goal is to be able to break that string into chars that i can search through to find whitespace and thus being able to isolate those words for example, if my input was "This is bad" i'd like the code to print out
This
is
bad
Edit:
I have modified my code to fit one of these answers but the problem i run into now is that it won't compile
int main()
{
char input[20];
printf("Please enter your words:\n");
size_t offset = 0;
do
{
scanf("%c", input + offset);
offset++;
}
while(offset < sizeof(input) && input[offset - 1] != '\n');
}
printf("%c", input[]);
return 0;
Problems:
1) scanf("%c", input); only set the first element of the array input.
2) printf("%c", input[1]); prints the second element of the array input, which has uninitialized data in it.
Solution:
Small state machine. No limit on string size like 20.
#include <ctype.h>
#include <stdio.h>
int main() {
int ch = fgetc(stdin);
while (ch != EOF) {
while (isspace(ch)) {
// If only 1 line of input allowed, then add
if (ch == '\n') return 0;;
ch = fgetc(stdin);
}
if (ch != EOF) {
do {
fputc(ch, stdout);
ch = fgetc(stdin);
} while (ch != EOF && !isspace(ch));
fputc('\n', stdout);
}
}
return 0;
}
scanf("%c", &input); does not do what you think it does.
First of all, %c scans only a single character: http://www.cplusplus.com/reference/cstdio/scanf/
Second, array's name is already a pointer to it's first element, so stating &input you make a pointer to a pointer, so instead of storing your character in array's first element you store it in pointer to the array which is a very bad thing.
If you really want to use scanf, I recommend a loop:
size_t offset = 0;
do
{
scanf("%c", input + offset);
offset++;
}
while(offset < sizeof(input) && input[offset - 1] != '\n');
Using scanf("%s", input") leaves you vulnerable to buffer overflow attacks if the word is longer than 20 characters http://en.wikipedia.org/wiki/Buffer_overflow
In my example I assumed, that you want to finish your word with a newline character.
EDIT: In scanf documentation is also a good example:
scanf("%19s", input);
It scans no more than 19 characters, which also prevent buffer overflow. But if you want to change input size, you have to change it two places.
You can use
char * strtok ( char * str, const char * delimiters );
to tokenize your string. If you have your input in input[] array and want to tokenize the string accoring to whitespace character, you can do the following :
char *ptr;
ptr = strtok(input, " ");
while(ptr != NULL) {
printf("%s\n", ptr);
ptr = strtok(NULL, " ");
}
Only the first call to strtok() requires the character array as input. Specifying NULL in the next calls means that it will operate on the same character array.
Your scanf only picks up the first character, input[1] contains random garbage. Use scanf("%19s", input) instead.

Printf printing everything in function before completing commands?

I have a piece of code here:
Tree *rangeprint(Tree *t) {
char first[20];
char last[20];
int f = 0;
int l = 0;
printf("First Entry?\n");
while(1) {
first[f] = getchar();
if(first[f] == '\n') {
first[f] = '\0';
break;
}
f++;
}
printf("Last Entry?\n");
while(1) {
last[l] = getchar();
if(last[l] == '\n') {
last[l] = '\0';
break;
}
l++;
}
printf("%s %s\n", first, last);
}
When I run this code, the output I get in the console is:
First Entry?
Last Entry?
Why is it skipping over the while loops and printing everything before executing them?
UPDATE - I changed the termination condition to 'x' instead of '\n' and sure enough it prints properly.
Adding a random getchar() before the loop starts fixes the problem, since the '\n' is read into there.
It is printing them, it's just that they are empty strings! (hint: f and l doesn't change - I assume the last loop using f is a typo!)
The getchar reads from the std in. If there is any newline character in previous input, It can cause the issue.
Just put,
fflush(stdin);
after
printf("First Entry?");
You are not advancing the pointer f while reading characters from the input. You are overwriting chatacter at location 0 all the times and in the end location 0 contains \0
try to put an \n at the end
printf("First Entry?\n");
printf("Last Entry?\n");

Resources