Empty string ends for loop - c

What's wrong in the below program (What's happening here)? It should break the for loop after the user inserts empty string (presses only ENTER), but in my case it ends in endless for loop. I tried what is in the comments with no success.
#include <stdio.h>
#include <string.h>
struct S {
char str [10];
};
int main(void)
{
int n;
struct S strings [10];
for (n = 0; n < 10; n++) {
# fflush(stdout);
scanf("%s", strings[n].str);
if (strlen(strings[n].str) == 0)
break;
# getchar();
}
printf("done");
return 0;
}
When I replace scanf with gets(strings[n].str); done is never printed. How would you fix it?
This sample solution works. Is there a difference in comparison to my code?

The enter key is not empty string, it is an ascii character or rather two characters a CR and LF (on Windows).

You shouldn't use strlen to find out if the input is empty. As others have said, when you press ENTER you get one or two characters sent to you.
You could instead check the first character in the string and see if it is '\n' or '\r'

scanf returns exactly what you've input... i.e. a crlf pair I'd imagine!

The problem with using scanf is that it expects something, not an empty string. You solve this by using e.g. fgets instead of scanf:
if (fgets(strings[n].str, sizeof(strings[n].str), stdin))
{
/* You got a string, it will contain the newline! */
}

Related

Palindrome in C using scanf and no string library functions

the assignment is to get an input string, and using no string library functions to be able to handle the string. this code at the moment doesn't even print out the string i get in. when I remove the functions from main it magically starts to print. any help would be greatly appreciated
#include <stdio.h>
#include <string.h>
#define SIZE 32
int isQuit(char str[]);
void isPalindrome(char str[]);
int main (){
int cont = 0;
char str[SIZE];
fflush(stdin);
printf("please enter a word:\n");
scanf("%s\n", str);
printf("%s\n", str);
while(cont == 0)
{
scanf("%s\n", str);
printf("%s\n", str);
cont = isQuit(str);
isPalindrome(str);
}
return 0;
}
You most likely are suffering from line buffering in your terminal. Until you write a newline character, any characters written are not displayed.
Try adding a newline when displaying your input:
printf("%s\n", str);
The same goes for any other printf calls you do that you want to ensure are displayed.
By the way, your null-termination test is incorrect. The escape character is \, not /. Change your loop to:
while (str[h] != '\0')
Or simply:
while (str[h])
There are a few things wrong with your code here:
while(isQuit(str) == 0)
{
isPalindrome(str);
return 0 ;
}
Since you have the return keyword in your loop body (unconditionally), the loop will execute at most one time.
Also, neither isQuit nor isPalindrome take input from the user. This means that even if you were to fix the loop by removing the return statement, it still wouldn't be right; you'd have an infinite loop of isQuit and isPalindrome being passed the same str that the user got asked for on line 15.
What you have to do is change your while loop to continually poll the user for input and act upon it, in addition to the issues pointed out in #paddy's answer.

scanning a line of strings with spaces using scanf

I was using scanf for all my inputs in C. Now I saw other similar questions about scanf() and they suggested using fgets() instead of scanf(). I will do so in the future. However, at the moment this particular part of code with scanf() never seems to work. I know there is a solution.
My code is:
#define LENGTH 1000
#define WORD 100
int main(){
int i = 0;
char s[WORD][LENGTH];
do {
scanf("%s", s[i]);
i++;
}
while (s[i][strlen(s[i])] != EOF);
printf("%s\n", s);
return 0;
}
There should be something instead of EOF in the while loop which checks for the end of line. The final result should be an array of words in s[] and the program should print that array of words without spaces.
Unfortunately scanf() does not read the character you need to check for end of line, or at least not using "%s" as the specifier.
Instead, use the following
char line[100];
if (scanf("%99[^\n]", line) == 1) {
fprintf(stdout, "%s\n", line);
}
This way, it does not stop at white space characters, and it behaves similar to fgets(), except that it does not read the '\n' character and that might be a problem if you call it again.

Can't find space in string and specified char , even by simple method

I am using this method to find a space or specified word in string.
but this method doesn't works. I've checked the flow many times.
#include <stdio.h>
int main()
{
char text[50], find;
int i = 0, sp = 0;
printf("Enter text: \n");
scanf("%s", text);
printf("Enter a char to find:\n");
scanf("%c", &find);
while ( text[i] != '\0') // to receive a value untill enter is pressed.
{
if (text[i] == find) // count if text[i] is the specified value.
{ sp++; }
i++;
}
printf("%d", sp); // prints 0 always. how to fix this.
}
The find in your code is always assigned with \n or the new line character that you enter at the end of scanning your string text .Try giving a space in scanf statement of find :
scanf(" %c",&find)
Why to give a space?
By giving a space,the compiler omits the '\n' character from the previous scanf
Note: scanf("%s",string) ends scanning when it encounters white space i.e, '\n' or '\0' or '\t' but to account for spaces, try
using this scanf("%[^\n]s",string")
You cannot use scanf() to read a string of characters with space. As soon as the space is encountered, scanf() exits.
Use fgets() instead.
And as for finding a word in the string, to compare strings use strcmp().
SIDE NOTE:
1) Check the return values of scanf()
2) Use the standard definition of main()
int main(void) //if no command line arguments.
I found a solution for that:
scanf("%[^\n]", fullName);
works fine. and receives whole line

Scanning until new line

I want to read all the text entered until a new line character is entered.
This is my code.
int i=0;
char ch[MAX];
printf("Enter the text\n");
while(true)
{
scanf("%c",&ch[i]);
if(ch[i]=='\n')
break;
i++;
}
But when I try to execute it reads only one word.
I have also tried scanf("%s",ch); but the result is the same.
Transferring comment to answer.
Your code will work. The code you posted scans everything until a newline character(\n) is found. But as Jonathan Leffler commented, you never NUL-terminate your string. To do it just use
ch[i]='\0';
after the loop. Also, the user could enter more characters than MAX-1(One extra for the \0 at the end) and this could cause a buffer overflow. You should add a check like
if(i==MAX-1)
break;
just before your scanf in order to prevent it from overflowing.
Note that scanf("%s",ch); will scan until it encounters a space or a newline character.
Instead of looping and scanning character by character, just use
scanf("%[^\n]",ch);
getchar();
The above scanf scans everything until a newline character is found and puts them in ch. The getchar() then discards the \n from the stdin. You can also improve safety by limiting the amount of characters that scanf reads into ch.
scanf("%49[^\n]",ch);
The above scanf will scan a maximum of 49 characters and will add a \0 at the end. You can substitute the value of MAX-1 there. I've used 50 as an example.
You're not checking that scanf() succeeds before relying on ch[i] to have a valid value, that's not a good idea.
Just use fgets() to read a whole line at once.
As commented by #Jonathan Leffler, OP 's code does not null terminate the string or prevent buffer overflow.
Since code fetches 1 char at a time, use the much simpler fgetc().
int i=0;
char ch[MAX];
int single; // Important that this in an int to distinguish EOF from input.
printf("Enter the text\n");
while((single = fgetc(stdin)) != EOF) {
if (i >= (MAX-1)) {
; // Too many, do not save or maybe indicate error
} else {
ch[i++] = single;
}
if (single == '\n') {
break;
}
}
ch[i] = '\0'; // Add termination
your code working fine . I checked, it reads a line not a word.
I hope it will be better for you with respect to your code :
int main()
{
int i=0;
char ch[100];
printf("Enter the text\n");
gets(ch); // input text
puts(ch); // output text
return 0;
}
input : asdf ghjkl zxcvb
output: asdf ghjkl zxcvb

scanning until EOF in c

I am writing a decryption program and I need to scan in an unknown number of strings and decode each string as it is entered. The program must end once it reaches EOF.
I am having difficulty getting the program to end. when I scan in the first char in the string in my while loop condition statement, it is doing this but when I scan in the actual string bellow the condition statement the string is missing the first char. Should I scan in the first char and then somehow put that char at the beginning of the string?
How do I properly test for EOF in my situation?
#include <stdio.h>
#include<string.h>
int main(void)
{
int i;
char code[300];
while(scanf("%c", &code[0])!=EOF)
{
scanf("%s", code);
for(i=0; i<strlen(code); i++)
{
decrypt message one char at a time
}
printf("\n");
}
return 0;
}
while (scanf("%s", code) == 1)
{
// no need for second scanf call
...
while (scanf("%c", &code[0]) == 1)
{ scanf("%s", &code[1]);
...
Using scanf at all is a bad idea for this particular problem.
while(scanf("%c", &code[0])!=EOF)
This scanf call reads a single character. Just use getchar().
scanf("%s", code);
for(i=0; i<strlen(code); i++)
{
decrypt message one char at a time
}
The scanf call can read arbitrarily many characters (after skipping whitespace; are you sure you want to skip whitespace?). That means that if there are too many characters to be read from stdin, you have a buffer overflow, one that you can't avoid unless you have complete control over what appears on stdin.
You then loop over the code array, calling strlen() for each character you process. Since strlen() generally has to scan from the beginning of the array to the terminating '\0', this is inefficient. If you need to traverse the characters of a string, either call strlen() once and save the value, or look for the terminating '\0' character.
But you're just processing one character at a time, so just read one character at a time:
while ((c = getchar()) != EOF) {
/* process a character */
}
Don't worry about reading one character at a time being inefficient; buffering will take care of that.

Resources