2

I'm new at C and I have a little problem. I need to write a program where the user enters text and the program shows how long it is.

I tried with strlen(), but it's not what I want.

char a[20];
scanf("%s",a)

And if I type "Hello world" the result is 5, but I need 11.

I need to use scanf, but maybe it's impossible to do that with it...

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
NewAtC
  • 55
  • 9
  • `%d` expects to match an integer, not a string. Check out the [docs](https://en.cppreference.com/w/c/io/fscanf). – 0x5453 Jan 25 '21 at 21:56
  • Does this answer your question? [multiple word string input through scanf( )](https://stackoverflow.com/questions/3555108/multiple-word-string-input-through-scanf) – Alexei Levenkov Jan 25 '21 at 22:02

4 Answers4

2

This call

scanf("%s",a)

fills the character array a until a white space is encountered. So this call will read only the word "Hello" and the input buffer will still keep the second word "world".

You can use either

char a[20];
scanf("%19[^\n]",a );
size_t n = strlen( s );
printf( "%zu\n", n );

Here is a demonstrative program

#include <stdio.h>
#include <string.h>

int main(void) 
{
    char a[20] = "";
    
    scanf( "%19[^\n]", a );
    
    size_t n = strlen( a );
    
    printf( "%zu: %s\n", n, a );
    
    return 0;
}

If to enter

Hello world

then the output is

11: Hello world

or

char a[20];

fgets( a, sizeof( a ), stdin );
a[strcspn( a, "\n" )] = '\0';

size_t n = strlen( s );
printf( "%zu\n", n );

Here is a demonstrative program.

#include <stdio.h>
#include <string.h>

int main(void) 
{
    char a[20] = "";
    
    fgets( a, sizeof( a ), stdin );
    a[strcspn( a, "\n" )] = '\0';
    
    size_t n = strlen( a );
    
    printf( "%zu: %s\n", n, a );
    
    return 0;
}

Again if to enter

Hello world                               

then the output will be the same as shown above

11: Hello world
Paul Bob
  • 441
  • 3
  • 10
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

%s is the correct specifier for strings:

char a[20];
scanf("%s", a);
printf("%d", strlen(a));

However %s stops on spaces. If you want to read spaces as well you should do:

scanf("%[^\n]", a);

vmp
  • 2,370
  • 1
  • 13
  • 17
  • 2
    this code is invalid. `%d` invokes Undefined Behaviour. Check what type `strlen` returns and how to print this type. – 0___________ Jan 25 '21 at 21:57
  • what are you talking about? – vmp Jan 25 '21 at 22:00
  • 1
    `strlen` returns a `size_t`, not necessarily an `int`. – Steve Summit Jan 25 '21 at 22:00
  • I'm aware of that, I just want an example where it would fail to use %d. – vmp Jan 25 '21 at 22:04
  • @vmp: Try this `printf("%d: %s", strlen(a), a);` for an example that will crash if ` sizeof(size_t) > sizeof(int)`, which is the case on all commonplace 64 bit environments. – datenwolf Jan 25 '21 at 22:17
  • @datenwolf thanks for the advice. I've never used strings that big so I never had that issue... For this example I guess %d is safe then, since 19 chars is far from the int limit. – vmp Jan 25 '21 at 22:29
  • 1
    @vmp is not safe because C standard says so. Your thoughts about it make no sense – 0___________ Jan 25 '21 at 23:42
  • @0___________ You mean I should stick with `aew.c:9:14: warning: unknown conversion type character 'z' in format [-Wformat=] 9 | printf("%zu", strlen(a));` instead? – vmp Jan 26 '21 at 00:12
  • @vmp you have not conforming compiler. https://godbolt.org/z/MMn6b6 – 0___________ Jan 26 '21 at 01:08
  • @vmp: The string length doesn't matter. It's broken regardless of if the string has a length of zero, or SIZE_MAX. The issue is, that when specifying a `%d` format specifier, it will treat the corresponding variadic element to be of type `int`. This not only effects the amount of bits read from it, but also the calculation of the placement of the elements that follows directly after. And if you put a variadic parameter there that doesn't match, everything after is mismatched as well. If you want to be absolutely safe, cast the parameter to a well known type. – datenwolf Jan 26 '21 at 13:12
0

scanf() is used for only one word. It takes a word when it see an white space character(space,new line) and the end. You should again use scanf() to take another word. You can use fgets() to take a line. But don't forget to read how to use fgets() function.

Also, you must use an adress to store with scanf.

int a;
scanf("%d",&a);

But you don't need it for char arrays because a char array's name is address.

char[10]a;
scanf("%s",a);
icolak
  • 51
  • 4
0

Change %d to %s because d is for integers, s is for strings.

Another problem is that scanf will scan the input until the first whitespace.

Read more about it here https://www.tutorialspoint.com/format-specifiers-in-c