Enter key in a while loop - c

#include <stdlib.h>
#include <stdio.h>
int main ()
{
char word[100];
while (word != "hello") {
system("clear");
printf("\nSay hello to me : ");
scanf(" %s", word);
}
printf("congrats, you made it !");
return 0;
}
In this code : if i enter anything but hello, the loop continue. However, entering the ENTER key will not loop again, it will just add a line.
I read somewhere that using getchar() might help but I'm kinda new to the C developpement and I'm stuck here searching for hours how to make it works.
EDIT 0 :
Removed
while (word != "hello")
char word[100];
scanf(" %s", word);
Added
#include <string.h>
while (strcmp(word, "hello") != 0)
char word[100] = {0};
fgets(word, 6, stdin);
EDIT 1 :
I tried to include in my code something like that
fgets(word, 6, NULL);
But it got me a segmentation fault.
**EDIT 2 : **
The correct working input is :
fgets(word, 6, stdin);
So it worked, but adding more than 6 character to the question like :
Say hello to me : hello from the inside
Will just print :
Say hello to me :
Say hello to me :
So I just modified the function like that :
fgets(word, 100, stdin);
But now it will not get me any input to work

Three things:
You don't need the space in the scanf format string. The %s format specifier already ignores leading whitespace. So instead of " %s" use "%s".
The main problem is word != "hello". That's not how strings are compared. What you're actually doing is comparing the address of word with the address of the string constant "hello". To do a string comparison, use strcmp. If it returns 0, the strings are the same, so your while loop should check for non-zero:
while (strcmp(word,"hello")) {
Be sure to #include <string.h> to get the declaration of strcmp.
Finally, you need to initialize word so that the initial string comparison doesn't invoke undefined behavior by reading uninitialized data:
char word[100] = {0};

#dbush well answered OP initial concerns.
OP is now using fgets(word, 100, stdin); and types in h e l l o Enter. word[] is then filled with "hello\n" and this does not pass strcmp(word, "hello") != 0.
Solution: strip final '\n'.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE 100
int main() {
char word[BUFFER_SIZE] = { 0 };
while (strcmp(word, "hello") != 0) {
system("clear");
printf("\nSay hello to me : ");
// insure buffered output is flushed
fflush(stdout);
// Avoid magic numbers, use `sizeof word`
// Test if input was received
if (fgets(word, sizeof word, stdin) == NULL) {
fprintf(stderr, "\nInput closed\n");
return 1;
}
// lop off potential trailing \n
word[strcspn(word, "\n")] = '\0';
}
printf("congrats, you made it !\n");
return 0;
}

Related

How to parse through a string of STDIN word by word in C

I would like to read standard input of a command and its argument in a C program, for instance:
ATTACK 50 30
I would like my program to parse through the input using whitespace and assign each word to a variable but right now I would just like to print each word. However, when I tried the program only returned ATTACK and not ATTACK 50 30.
I tried:
int main(){
// Grid size declaration //
int *x, *y;
char command[20];
char user_input[100];
scanf("%s", user_input);
printf("%s", user_input);
return 0;
}
As I said I used ATTACK 50 30 as my STDIN but my printf function only returned ATTACK. I thought of maybe using a while loop to keep scanning until the character interpreted is the return key (which I believe in this case would just be the null character?). I tried it using the code below:
int main(){
// Grid size declaration //
int *x, *y;
char command[20];
char user_input[100];
while(scanf("%s", user_input)!="\0"){
scanf("%s", user_input);
printf("%s", user_input);
}
return 0;
}
This did not work, the error produced declared I was comparing a pointer to an integer.
Since you are dealing with stdin it would probably be a better idea to utilize the fgets function in lieu of the scanf function, and then parse the inputted line of data utilizing the strtok string function.
Utilizing that strategy, following is a snippet of code allowing for the parsing of entered text where each word or data group is identified.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 64
int main()
{
char line[MAX + 1];
const char delim[2] = " ";
char * wd;
printf("Enter some text or type \"quit\" to end: ");
while (fgets(line, MAX, stdin))
{
line[strlen(line) - 1] = ' '; /* Replace newline character at the end with a space */
wd = strtok(line, delim);
while (wd != NULL)
{
if (strcmp(wd, "quit") == 0)
{
return 0;
}
printf("%s\n", wd);
wd = strtok(NULL, delim);
}
printf("Enter some text or type \"quit\" to end: ");
}
return 0;
}
Testing out this code utilizing your text example yielded the following terminal output.
#Dev:~/C_Programs/Console/ParseWord/bin/Release$ ./ParseWord
Enter some text or type "quit" to end: ATTACK 50 30
ATTACK
50
30
Enter some text or type "quit" to end: quit
#Dev:~/C_Programs/Console/ParseWord/bin/Release$
This is just a springboard from where you might go, but test that out and see if it meets the spirit of your project.

How to extract the string after a word in C

I am trying to add a functionality in my program that gets the specific word or sentence after a particular word in C.
E.g.
When I try to type:
"say Hello World", the program will print "Hello World" only.
My code runs like this:
int main(){
char command;
do{
printf("MyOS>");
scanf("%s", &command);
if(strncmp(&command, "say", 3) == 0){
//enter code here
}
} while (strncmp(&command, "exit", 4));
return 0;
}
when running, the program asks for an input string, and in the case that my string starts with "say", I want it to output the next words/string.
You have two problems
scanf("%s", &command); here variable command requires a buffer of some size greater than 1.
Use as below
#define COMMAND_SIZE 1024 and declare some thing like char command[COMMAND_SIZE] = {0}
I think you are trying to read multiword string, that is not possible with the way you used scanf("%s", command); even if command has sufficient size.
Better use fgets(command, sizeof(command), stdin); to read multiword strings.
In short you need some thing like this:
#include <stdio.h>
#include <string.h>
#define COMMAND_SIZE 512
int main(){
char command[COMMAND_SIZE] = {0};
do{
printf("MyOS>");
fgets(command,sizeof (command), stdin);
if(strncmp(command, "say", 3) == 0) {
printf(" %s\n", command+3);
}
} while (strncmp(command, "exit", 4));
return 0;
}
Note: Make sure you allocate sufficient buffer to store your input command, and enter the input which is less than COMMAND_SIZE characters , so that it will have enough space the \n, else you will face problems with leftover \n characters.

Why is strtok printing only first word?

I am using strtok for converting string into individual words. I have done the following:
int main() {
char target[100];
char *t;
scanf("%s",target);
t = strtok(target," ");
while (t!= NULL)
{
printf("<<%s>>\n", t);
t = strtok (NULL, " ");
}
return 0;
}
The input is a string such as 'this is a string', the output I am getting is<<this>>.
The way you have written scanf it will accept string till white space only
scanf("%s",target);
SO You need to change the way you take input from console
scanf("%99[^\n]",target);
Change:
scanf("%s",target);
to:
fgets(target, 100, stdin);
since the first won't stop when encounters the whitespace in your input.
Output:
this is a string
<<this>>
<<is>>
<<a>>
<<string
>>
Notice how the newline fgets() stores affects the output. You can simply discard it if you want, like this:
fgets(target, 100, stdin);
target[strlen(target) - 1] = '\0';
and now the output is:
this is a string
<<this>>
<<is>>
<<a>>
<<string>>
If you want to continue using scanf(), then you can use the below code snippet:
#include<stdio.h>
#include <string.h>
int main() {
char target[100];
char *t;
//scanf("%s",target);
scanf("%99[0-9a-zA-Z ]", target);
printf("%s\n",target);
t = strtok(target," ");
while (t!= NULL)
{
printf("<<%s>>\n", t);
t = strtok (NULL, " ");
}
return 0;
}
Working code here.
Just writing scanf("%s",target); will read the input only till the first white space; which is why you get only the first word as the output. By writing scanf("%99[0-9a-zA-Z ]", target);, you are reading 99 characters (including numbers 0-9, a-z or A-Z and white space) from the input stream.
Hope this is helpful.

Why scanf() can't filter double quatation mark, although set format to [A-Za-z]

I am trying to extract only letter words except the other characters in the sentence.
For this, I use two scanf() as bellow.
scanf("%s", word);
sscanf(word, "%[A-Za-z]", word);
Problem is that, double quatation mark on is not removed, although I set format to %[A-Za-z]
Curiously, however, if this mark on the last location on the word, it removed.
Is there anyone know reason?
Test case
- "Disneyland
- Left."
#include <stdio.h>
#include <string.h>
#define MAX_WORD 128
int main(int argc, char* argv[]) {
char word[MAX_WORD];
/* Read all of contents */
while (EOF != scanf("%s", word)) {
printf("origin word: %s\n", word);
sscanf(word, "%[A-Za-z\"]s", word);
printf("transformed: %s\n", word);
}
}
It's stripping off the end of the second line because of the period, not the quote, hence it's stripping both the period and the quote.
You have asked it to scan a string consisting of the letters A-Za-z^" so the presence of the period causes it to stop at that point.
I'm not sure if you totally understand how that works. It won't give you all characters in the string that match the ones you've specified, throwing away the rest. Instead it will accept characters up to the first valid one and then throw everything else away. You can see this if you type in some perfectly valid characters with an invalid one in the middle:
abcdefg.hijklmnop
origin word: abcdefg.hijklmnop
transformed: abcdefg
From that, it's evident that it stops at the first invalid character rather than just stripping out the invalid characters.
If you want a string with only matching characters, you can use something like:
#include <stdio.h>
#include <string.h>
#define MAX_WORD 128
static void strip(char *word, char *allow) {
char *d = word;
while (*word != '\0') {
if (strchr (allow, *word) != NULL)
*d++ = *word;
word++;
}
*d = '\0';
}
int main (void) {
char word[MAX_WORD];
while (EOF != scanf ("%s", word)) {
printf("origin word: %s\n", word);
strip (word, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz^\"");
printf("transformed: %s\n", word);
}
}
and, with a sample set of runs:
"Disneyland
origin word: "Disneyland
transformed: "Disneyland
Left."
origin word: Left."
transformed: Left"
dvsdhjshhvsdf6553785365^%%$$###*&*&mjdvsdddhvjhdfvb
origin word: dvsdhjshhvsdf6553785365^%%$$###*&*&mjdvsdddhvjhdfvb
transformed: dvsdhjshhvsdf^mjdvsdddhvjhdfvb
sscanf(word, "%[A-Za-z\"]s", word);
Programming languages — C - The sscanf function - Description:
… If copying takes place between objects that overlap, the behavior is
undefined.
So, your usage of sscanf is invalid. That said, the outcome of your test case is what is to be expected even from a correct usage; an explanation is embedded in paxdiablo's answer.

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.

Resources