Why does the following C code does not ouput 10
#include<stdio.h>
#include<stdlib.h>
void get_length(char s[]);
int main( )
{
char buff[128];
printf("\nEnter buffer data: ");
scanf("%s",buff);
get_length(buff);
}
void get_length(char *s){
int count;
for(count = 0 ; *s != '\0' ; s++)
count++;
printf("count = %d\n",count);
}
The input is I am Rohit
The output is
count = 432
Can anyone please explain that.
You appear to have a 5 instead of a % in your scanf format string. (Perhaps your keyboard's shift key needs cleaning.)
That means that scanf isn't actually reading anything into your buffer. Your code doesn't check the return value from scanf (it should!) and therefore never notices that it failed. So you're then trying to calculate the length of ... a buffer full of uninitialized junk. It could give you 432, or 0, or anything else at all.
[EDITED to add:] ... Oh. And even if you fix that, it still won't work because scanf will stop reading when it sees a whitespace character, including a newline, and therefore the \n your get_length function is looking for will not be in the buffer.
Incidentally, do you know about the strlen function in the C standard library?
I think you meant %s, not 5s.
BTW, value-initialising your array (char buff[128] = {}) will prevent your array from being unbounded (count = 432 is arbitrary for you).
You should then check for *s != '\0', not \n, in get_length โ C-style strings are bounded by the NULL character (\0), not newlines, regardless that you took the data from user input. The newline is lost from that input.
I think that scanf is reading your string in and setting the last char to '\0', but you are searching for '\n', which I don't think is implicit in the scanf implementation.
That is, check for '\0' instead of '\n'.
The scanf call is failing because you have used an invalid format. If you want a string of length 5, then the format should be "%5s" instead of "5s", or just "%s" if the five is a complete typo. So, the character buffer is uninitialized and you are getting the number of bytes before the first random '\n' character is encountered on the stack. Also, scanf ignores newline characters. So, your get_length function will never work as expected.
Related
I'm trying to set up a code that counts the whole string and doesn't stop after the first space that it finds. How do I do that?
I tried this kind of code but it just counts the first word then goes to display the number of letters in that first word.
So far this is what I have tried.
int main(){
char get[100];
int i, space=0, len=0, tot;
scanf("%s", get);
for (i=0; get[i]!='\0'; i++)
{
if (get[i] == ' ')
space++;
else
len++;
}
tot = space + len;
printf("%i", tot);
}
And
int main(){
char get[100];
int len;
scanf("%s", &get);
len = strlen(get);
printf("%i", len);
}
But would still get the same answer as the first one.
I expected that if the
input: The fox is gorgeous.
output: 19
But all I get is
input: The fox is gorgeous.
output: 3
strlen already includes spaces, since it counts the length of the string up to the terminating NUL character (zero, '\0').
Your problem is that that the %s conversion of scanf stops reading when it encounters whitespace, so your string never included it in the first place (you can verify this easily by printing out the string). (You could fix it by using different scanf conversions, but in general it's easier to get things right by reading with fgets โ it also forces you to specify the buffer size, fixing the potential buffer overflow in your current code.)
The Answer by Arkku is correct in its diagnose.
However, if you wish to use scanf, you could do this:
scanf("%99[^\n]", get);
The 99 tells scanf not to read more than 99 characters, so your get buffer won't overflow. The [^\n] tells scanf to read any character until it encounters the newline character (when you hit enter).
As Chux pointed out, the code still has 2 issues.
When using scanf, it is always a good idea to check its return value, which is the number of items it could read. Also, indeed the \n remains in the input buffer when using the above syntax. So, you could do this:
if(scanf("%99[^\n]", get) == 0){
get[0] = 0; //Put in a NUL terminator if scanf read nothing
}
getchar(); //Remove the newline character from the input buffer
I will take one example to explain the concept.
main()
{
char s[20], i;
scanf("%[^\n]", &s);
while(s[i] != '\0') {
i++;
}
printf("%d", i);
return 0;
}
i have used c language and u can loop through the ending the part of the string and you will get the length. here i have used "EDIT SET CONVESRION METHOD" to read string, you can also gets to read.
using the cprogrammingsimplified tutorial for writing my own stringcompare.
Finished reformatting it and ran it.
works fine for single words,
But
typing space bar skips the second scan and immediately outputs
'words aren't the same'
anyone any idea how to allow the use of even a single space bar?
Thanks in advance.
#include <stdio.h>
int mystrcmp(char s1[], char s2[]);
int main(){
char s1[10], s2[10];
int flag;
printf("Type a string of 10\n\n");
scanf("%s",&s1);
printf("type another string of 10 to compare\n\n");
scanf("%s",&s2);
flag = mystrcmp(s1,s2);
if(flag==0)
printf("the words are the same\n\n");
else
printf("the words are not the same\n\n");
return 0;
}
int mystrcmp(char s1[], char s2[]){
int l=0;
while (s1[l] == s2[l]) {
if (s1[l] == '\0' || s2[l] == '\0')
break;
l++;
}
if (s1[l] == '\0' && s2[l] == '\0')
return 0;
else
return -1;
}
Use fgets() to read full lines, rather than scanf() to read space-separated words.
Remember that fgets() will include the linefeed in the string, though.
It is not strcmp that wouldn't allow space bar, it's scanf with %s format specifier. The input is truncated at the space, so the second string that you read is actually the continuation of the first string.
You can fix this by using %9[^\n] instead of %s in your format specifier:
printf("Type a string of 10\n\n");
scanf("%9[^\n]",s1); //s1 is char [10]
printf("type another string of 10 to compare\n\n");
scanf("%9[^\n]",s2); //s2 is char [10]
9 limits input to nine characters, because you are using a ten-character buffer.
Many answers have told you that scanf("%s",s1) only reads word by word. This is because by default scanf("%s",s1) is delimited by all white spaces, this includes \t, \n, <space>, or any other you can think of.
What scanf("%[^\n]s",s1) does is set the delimiter to \n. So in effect reads all other spaces.
#dasablinklight has also specified a 9 before the '[^\n]' this denotes that scanf() takes 9 values from input buffer.
IMO scanf() is a really nice function due to it's hidden features. I suggest you read more about it in it's documentation.
The problem is that if you type abc def on the first line, the first scanf("%s", s1) (no ampersand required โ it should be absent) reads abc and the second reads def. And those are not equal. Type very very and you'd find the words are equal. %s stops reading at a space.
Your buffers of size 10 are too small for comfort.
Fix: read lines (e.g. char s1[1024], s2[1024];) with fgets() or POSIX's getline(), remove trailing newlines (probably: s1[strcspn(s1, "\n")] = '\0'; is a reliable way to do it) and then go ahead compare the lines.
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.
My objective is to change the delimiter of scanf to "\n".
I tried using scanf("%[^\n]s",sen); and works fine for single inputs.
But when i put the same line inside a for loop for multiple sentences it gives me garbage values.
Does anyone know why?
Here's my code:
char sen[20];
for (i=0;i<2;i++)
{
scanf("%[^\n]s",sen);
printf("%s\n",sen);
}
Consider this (C99) code:
#include <stdio.h>
int main(void)
{
char buffer[256];
while (scanf("%255[^\n]", buffer) == 1)
printf("Found <<%s>>\n", buffer);
int c;
if ((c = getchar()) != EOF)
printf("Failed on character %d (%c)\n", c, c);
return(0);
}
When I run it and type in a string 'absolutely anything with spaces TABTABtabs galore!', it gives me:
Found <<absolutely anything with spaces tabs galore!>>
Failed on character 10 (
)
ASCII (UTF-8) 1010 is newline, of course.
Does this help you understand your problem?
It works in this case (for a single line) but if I want to take multiple lines of input into an array of arrays then it fails. And I don't get how scanf returns a value in your code?
There are reasons why many (most?) experienced C programmers avoid scanf() and fscanf() like the plague; they're too hard to get to work correctly. I'd recommend this alternative, using sscanf(), which does not get the same execration that scanf() and fscanf() do.
#include <stdio.h>
int main(void)
{
char line[256];
char sen[256];
while (fgets(line, sizeof(line), stdin) != 0)
{
if (sscanf(line, "%255[^\n]", sen) != 1)
break;
printf("Found <<%s>>\n", sen);
}
int c;
if ((c = getchar()) != EOF)
printf("Failed on character %d (%c)\n", c, c);
return(0);
}
This reads the line of input (using fgets() which ensures no buffer overflow (pretend that the gets() function, if you've heard of it, melts your computer to a pool of metal and silicon), then uses sscanf() to process that line. This deals with newlines, which are the downfall of the original code.
char sen[20];
for (i=0;i<2;i++)
{
scanf("%[^\n]s",sen);
printf("%s\n",sen);
}
Problems:
You do not check whether scanf() succeeded.
You leave the newline in the buffer on the first iteration; the second iteration generates a return value of 0 because the first character to read is newline, which is the character excluded by the scan set.
The gibberish you see is likely the first line of input, repeated. Indeed, if it were not for the bounded loop, it would not wait for you to type anything more; it would spit out the first line over and over again.
Return value from scanf()
The definition of scanf() (from ISO/IEC 9899:1999) is:
ยง7.19.6.4 The scanf function
Synopsis
#include <stdio.h>
int scanf(const char * restrict format, ...);
Description
2 The scanf function is equivalent to fscanf with the argument stdin interposed
before the arguments to scanf.
Returns
3 The scanf function returns the value of the macro EOF if an input failure occurs before
any conversion. Otherwise, the scanf function returns the number of input items
assigned, which can be fewer than provided for, or even zero, in the event of an early
matching failure.
Note that when the loop in my first program exits, it is because scanf() returned 0, not EOF.
%[^\n] leaves the newline in the buffer. %[^\n]%*c eats the newline character.
In any case, %[^\n] can read any number of characters and cause buffer overflow or worse.
I use the format string %*[^\n]%*c to gobble the remainder of a line of input from a file. For example, one can read a number and discard the remainder of the line by %d%*[^\n]%*c. This is useful if there is a comment or label following the number, or other data that is not needed.
char sen[20];
for (i=0;i<2;i++)
{
scanf("%[^\n]s",sen);
printf("%s\n",sen);
getchar();
}
Hope this helps ... actually "\n" remains in stream input buffer... Ee need to flush it out before scanf is invoked again
I know I am late, but I ran into same problem after testing C after a long time.
The problem here is the new line is considered as input for next iteration.
So, here is my solution, use getchar() to discard the newline the input stream:
char s[10][25];
int i;
for(i = 0; i < 10; i++){
printf("Enter string: ");
scanf("%s", s[i]);
getchar();
}
Hope it helps :)
While using scanf("%[^\n]", sen) in a loop, the problem that occurs is that the \n stays within the input buffer and is not flushed. As a result next time, when the same input syntax is used, it reads the \n and considers it as a null input. A simple but effective solution to address this problem is to use:
char sen[20];
for (i=0;i<2;i++)
{
scanf("%[^\n]%*c",sen);
printf("%s\n",sen);
}
%*c gets rid of the \n character in the input buffer.
Still in learning mode and may be the following question is a really dumb but I dont have any idea why it is happening..
#include<stdio.h>
int main()
{
/* code to accept string and then a character from stdin */
char str[20], inp;
/*take string from stdin */
printf("string:\n");
scanf("%s",str);
fflush(stdin);
/*input a character */
printf("char:\n");
scanf("%c",&inp);/* code does not reach this point and exits */
}
As mentioned in the comment, after I input the string , for eg. 'strng' the code just exits after printing char: but it does not wait for me input the character. As per my understanding, I have given the size of the array large enough to store the string and if the string entered is smaller than the size of the str array, the compiler will automatically add null character at the end of the string and proceed further. Am I missing something or is there a mistake in my code. Please suggest.
Thanks.
Try removing fflush(stdin);
and put a space before %c in scanf(" %c",&inp);
First of all fflush(stdin) is wrong. Many people recommend it but it is plain and simple undefined.
The problem is caused by scanf leaving \n in the input buffer because "%s" doesn't read whitespace characters. When scanf("%c"..) is reached, it is immediately "satisfied" and fills inp with \n and calls it a day.
The problem is common enough, see these C FAQs:
Scanf interlace
Scanf problems
One (possibly dangerous) solution is to discard \n input:
while((c = getchar()) != '\n' && c != EOF)
;
Another solution might be to use fgets and parse that, or possibly read one character at a time with getc, or maybe tweak the second scamf to discard whitespace characters.
Put a space before the %c in the second scanf like this:
scanf(" %c",&inp)
And as stated by others fflush is defined only for output streams.