How do I allow spaces to be read during execution? - c

The program is to compare the string but however there's a problem with the spacing when I execute it. As I input the first string with spacing, the program just jump to comparing the strings, not allowing me to input the second string as follows:
>>"Enter first string":
"Hello Hey"
">>Enter second string:"
">>First string is more than the second string."
Here is my code:
#include<stdio.h>
#include<string.h>
int main (void) {
int result; //store results
char input1[50];
char input2[50];
printf("Enter first string:\n");
scanf("%[^\n]s",input1);
printf("Enter second string:\n");
scanf("%[^\n]s",input2);
result = strcmp(input1, input2);
if (result==0)
printf("First string is equal to second string\n");
if (result>0)
printf("First string is greater than second string\n");
if (result<0)
printf("First string is less than the second string\n");
return 0;
}

Add spaces:
scanf(" %[^\n]s",input1);
scanf(" %[^\n]s",input2);
It will consume all the white spaces encountered in previous inputs.
When you enter any input, you also enter a new line character (white space) with your input. And that newline character is being read by second scanf in your code.
The Question:
How do I allow spaces to be read during execution? (the question)
You are already doing it using [^\n] in scanf("%[^\n]s",input1); which means to read the input until a new line (\n) is encountered. Also, not that \n itself doesn't get read in this way.
Output:
Enter first string:
Strings in C
Enter second string:
Strings in C
First string is equal to second string

I think you can do it with the stdlib.h with this function:
gets(input1);
gets(input2);
For sure, the POSIX way will work, you can use read to get the line from stdin:
read(STDIN_FILENO, input1, 50)

Related

Scanning Only the First Character in C

I know that adding a space in front of %c in scanf() will scan my second character; however, if two letters were inputted in the first character, it will input the second letter into the second character. How do I scan a single character only?
#include <stdio.h>
int main(void)
{
char firstch, secondch;
printf("Enter your first character: ");
scanf("%c", &firstch);
printf("Enter your second character: ");
scanf(" %c", &secondch);
printf("\n Fisrt character : %c \n Second character : %c \n", firstch, secondch);
return 0;
}
This is my result after running:
Enter your first character: ab
Enter your second character:
First character : a
Second character : b
I only want to read the first character 'a', but the second letter 'b' was inputted right away before I enter my second character.
When you are reading a line of user-input, use a line-oriented input function like fgets() or POSIX getline(). That way the entire line of input is read at once and you can simply take the first character from the line. Say you read a line into the array used as buffer called buf, e.g.
#define MAXC 1024 /* if you need a constant, #define one (or more) */
int main (void) {
char buf[MAXC]; /* buffer to read each line into */
You can simply access the first character as buf[0], or since buf[0] is equivalent to *(but + 0) in pointer notation, you can simply use *buf to get the first character.
As a benefit, since all line-oriented functions read and include the '\n' generated by the user pressing Enter after the input, you can simply check if the first character is '\n' as a way of indicating end-of-input. The user simply presses Enter alone as input to indicate they are done.
Using a line-oriented approach is the recommended way to take user input because it consumes and entire line of input each time and what remains in stdin unread doesn't depend on the scanf conversion specifier or whether a matching failure occurs.
Using " %c%*[^\n]" is not a fix-all. It leaves the '\n' in stdin unread. That's why you need the space before " %c". Where it is insidious is if your next input uses a line-oriented function after your code reading characters is done. Unless you manually empty the '\n' from stdin, before your next attempted line-oriented input, that input will fail because it will see the '\n' as the first character remaining in stdin.
A short example using fgets() for a line-oriented approach would be:
#include <stdio.h>
#define MAXC 1024 /* if you need a constant, #define one (or more) */
int main (void) {
char buf[MAXC]; /* buffer to read each line into */
for (;;) { /* loop continually */
fputs ("enter char: ", stdout); /* prompt for input */
/* read/validate line, break on EOF or [Enter] alone */
if (!fgets (buf, sizeof buf, stdin) || *buf == '\n')
break;
printf (" got: %c\n\n", *buf); /* output character read */
}
}
Where you simply take input continually isolating the first character as the value you want until the user presses Enter alone to break the read-loop.
Example Use/Output
$ ./bin/fgetschar
enter char: a
got: a
enter char: ab
got: a
enter char: a whole lot of stuff you don't have to deal with using fgets()
got: a
enter char: banannas
got: b
enter char: cantelopes
got: c
enter char:
Look things over and let me know if you have further questions.
Using a space before the %c will skip whitespace before scanning the next non-whitespace character. %c itself just scans a single character -- the next character in the input after whatever else was scanned or skipped previously.
So the question is, what do you want to do? Do you want to skip over all extraneous input on the line after the first character (up to newline?) fgets or scanf("%*[^\n]"); scanf("%c"); will do that (but be careful -- if firstch was itself a newline, this will skip the next line.) Do you want to check the input and make sure it is exactly one character on a line? If so, use fgets (not scanf) and check that the line read is exactly two characters (a character and a newline). Or perhaps you really want to read keystrokes without having the user hit Enter after esch one? That requires changing the input source setup, which is OS dependent.
I'm still new to C coding, and I've found a suitable answer to my problem by using scanf("%*[^\n]");
#include <stdio.h>
int main(void)
{
char firstch, secondch;
printf("Enter your first character: ");
scanf(" %c%*[^\n]", &firstch);
printf("Enter your second character: ");
scanf(" %c%*[^\n]", &secondch);
printf("\n First character : %c \n Second character : %c \n", firstch,
secondch);
return 0;
}
Results after running:
Enter your first character: ab
Enter your second character: c
First character : a
Second character : c
Thanks to #Eraklon #Chris Dodd #David C. Rankin

interesting behaviour when using scanf on string with space in a loop

I was fiddling with C and happen to wrote code below. When I input a string with spaces, program receives all of the input but outputs them as if they were inputted as single words at different times. I thought scanf stopped when first whitespace character is encounterd and ignored the rest. But that seems, is not the case.
I included the output when I enter "inputWithNoSpaces" and "input with spaces", below.
I tried to look into stdin. It receives all the input. But I could not figure out what scanf was doing. I would like to learn what is happening.
Code:
#include <stdio.h>
int main()
{
int i=0;
char word[64]="";
while(1)
{
printf("enter string:");
scanf("%s",word);
i++;
printf("%d:%s\n\n",i,word);
}
return 0;
}
Output:
enter string:inputWithNoSpaces
1:inputWithNoSpaces
enter string:input with spaces
2:input
enter string:3:with
enter string:4:spaces
enter string:
In scanf(), "%s" means "skip whitespace characters then read a sequence of non-whitespace characters". So when you give it the input input with spaces it will return "input", "with" and "spaces" in three sequential calls. That is the expected behavior. For more information read the manual page.
input with spaces
^^^^^ First scanf("%s", s) reads this
^ Second scanf("%s", s) skips over this whitespace
^^^^ Second scanf("%s", s) reads this
^ Third scanf("%s", s) skips over this whitespace
^^^^^^ Third scanf("%s", s) reads this

Output automatically taken as Input in C

This is simple code. In which I am taking a input, printing it, and taking again and printing it once more.
For the second time it doesn't let me give the input.
Can someone explain why ?
#include "stdio.h"
int main()
{
char buff[50];
printf("Enter a String\n");
scanf("%[^\n]s",buff);
puts(buff);
printf("Enter another String\n");
scanf("%[^\n]s",buff);
puts(buff);
return 0;
}
Output :
Enter a String
Hello // This I have entered
Hello // This is the output
Enter another String
Hello // This I haven't entered, It automatically takes this.
In the second scanf(), place a space at the beginning of your input specifier:
scanf(" %[^\n]s",buff);
^^^
This will eat the character that is currently satisfying scanf the second time, and allow you to enter a second string.
Using a different format helps
// scanf("%[^\n]s",buff);
scanf(" %49[^\n]",buff);
// ^ no s
// ^ width limit
// ^ consume previous line's leftover \n (and all white-space)
Note that scanf(" %[^\n]",buff); does not change buff when user enters only " \n".
But better to use fgets()
fgets(buff, sizeof buff, stdin);
buf[strcspn(buffer, "\n")] = 0; // to remove \n

Incorrect output, simple strings exercise - C

I am trying to write a function that gets a string of letters, either capital letters or small letters, and prints 2 other strings, one with only the capitals, and one only with the small letters. for example:
input: AaBbCcDD
Output: Capital string is ABCDD, non capital is abc
My code is not working correctly, it seems to skip over the last letter. To test it, I wrote the following code:
int length;
printf("Please enter length of string\n");
scanf("%d",&length);
string=create_string(length);
scan_string(string,length);
printf("The string entered is: \n");
print_string(string,length);
Where create_string is:
char* create_string(int size)
{
char* string;
string=(char*)malloc(size*sizeof(char));
return string;
}
Scan string is:
void scan_string(char* string, int size)
{
int i;
printf("Please enter %d characters\n",size);
for(i=0;i<size;i++)
scanf("%c",string+i);
}
And print string is
void print_string(char* string,int size)
{
int i;
for(i=0;i<size;i++)
printf("%c ",*(string+i));
}
When I try even just to print the string I entered, this is what I get, after I input aaAAB
The output is a a A A.
it skipped over the B.
The problem is with the scanf that reads characters using %c: it follows the scanf that reads the length using %d, which leaves an extra '\n' character in the buffer before the first character that you get.
If you modify the output to put quotes around your characters, you would actually see the \n:
void print_string(char* string,int size)
{
int i;
for(i=0;i<size;i++)
printf("'%c' ",*(string+i));
}
This prints
'
' 'a' 'a' 'A' 'A'
(demo on ideone)
You can change your first scanf to read '\n' as below. This will read the extra '\n'
scanf("%d\n", &length);
I think your code is unnecessarily elaborated. To read a string the function fget() with parameter stdin is a simpler choice.
For example, I wuold not ask to the user for the length of the string.
Perhaps it is better to use a buffer with fixed length, and to restrit the user to enter a string with the length less than which you have been previously stipulated.
#define MAXLEN 1000
char buffer[MAXLEN] = "";
fgets(buffer, MAXLEN, stdin);
If the user attempts to enter a string with more than MAXLEN characters, it would be necessary to handle the end-of-line in some way, but I think this is out of topic.
So, in general, let us suppose that MAXLEN is large enough such that buffer contains the \n mark.
Now, a call to your function print_string() can be done.
However, it would be better to do this:
printf("%s", buffer);
I think that you probably need to take in account the C convention for strings: a string is a char array whose last element is marked with the character '\0' (null character, having always code 0).
Even if you want to insist in your approach, I think that scanf() is a bad choice to read individual characters. it is more easy to use getchar(), instead.
By using scanf() you have to broke your brain figurating out all the stuff around the behaviour of scanf(), or how to handle the read of characters, and so on.
However, getchar() reads one char at a time, and that's (almost) all. (Actually, the console commonly not returns the control to the user until an end-of-line \n has been read).
string[i] = getchar();
The problem is because the scanf does not eat the "\n". Hence there is still one '\n' remaining at your first input. This will be counted at the next scanf.
Try to put an additional getchar() right after your first scanf.
printf("Please enter length of string\n");
scanf("%d",&length);
getchar(); // remove '\n'
string=create_string(length);

Replacing part of string with another substring in C

this code is working perfectly fine in my compiler(DEV C++) but not in Ideone.com . It is not accepting replacement string. is there anything wrong with my logic ? May I know whats wrong with my code?
//splitting a string and replace latter part of string by another string
#include<stdio.h>
#include<string.h>
int i,count=0,loc2=0,scount=0,rcount=0,loc=0; //scount represents counter for substring and rcount for replacement and loc from where we will split the string
char str[100],sub[100],newss[100]; //newss=new substr, rslt and rslt2=former and latter part of original string
int main()
{
String();
substring();
new_string();
concat();
return 0;
}
void String()
{
printf("Enter a String:\n");
gets(str);
printf("\nString Entered by User:\n");
puts(str);
printf("\nLoc Char\n"); //Creates Colums 'Char' and 'Loc'
for(i=0;str[i]!='\0';i++)
{
count++; //Counts length of String
printf("%d. %c\n",count,str[i]); //Prints Characters with it its Corresponding Location
}
printf("\n\nLength of String: %d\n\n",count);
}
void substring()
{
printf("Enter the locations of Characters from where substring will start and end: \n");
scanf("%d%d",&loc,&loc2); //stores indices of begining and end of substring
printf("\n\nSubset formed from Existing String:\n");
for(i=loc-1;i<loc2;i++)
{
scount++;
sub[i]=str[i]; //stores substring in "sub"
printf("%c",sub[i]);
}
printf("\n\nLength of substring: %d\n",scount);
}
void new_string()
{
printf("\n\nEnter a Replacement for substring(Of Equal Length as that of substring):\n");
fflush(stdin);
gets(newss);
for(i=0;newss[i]!='\0';i++)
rcount++;
printf("\n\nLength of New substring: %d\n",rcount); //-1 to subtract length of null char
}
void concat()
{
if(rcount!=scount) //to check whether replacement string and substring are of same length
printf("\nSince length of both substrings is not same. \nHence Replacement is Not Possible\n");
else //Concatination of 3 substrings
{
printf("\nResultant String:\n");
for(i=0;i<(loc-1);i++)
printf("%c",str[i]);
for(i=0;newss[i]!='\0';i++)
printf("%c",newss[i]);
for(i=loc2;str[i]!='\0';i++)
printf("%c",str[i]);
}
}
You're doing a number of strange things, and some bad things as well, one of the big problems is you're intermixing calls to gets() and scanf(), they handle new line characters differently and it's getting you in trouble.
When you call substring() it's using scanf() to get the two substring indexes, but it's leaving a newline character('\n') on stdin, then your call to gets() is reading that and using it as the string.
Change:
gets(newss);
To:
scanf(" %s", newss);
And things will work in ideone.com.
You maybe wondering why did you have this problem when you called fflush(stdin); just before reading newss. This is part of what I described as "bad things" before. fflush(stdin) should NEVER be done. This leads to undefined behavior, fflush() is well defined for stdout but not for stdin. This means calling it could flush the input buffer or it could not it depends on how that was implemented in the IDE you were using (or if it was at all). If it's not defined in the C standard, you can't assume it will work.
EDIT:
your example is using spaces in the substring you're entering so the answer is the same, but you need to use the negated scanset:
scanf(" %[^\n]", newss); // note my examples start with a blank space
// ^
// |
// here
The blank space will tell scanf() to ignore any remaining "white space" characters left on stdin, that means that left over '\n' will not be considered. However that ALSO means that if your replacement string starts with a space that space will be ignored. You can read the man page for scanf() and consider exactly what you want to use for your input string based on your assignment requirements.

Resources