0

So, I want to get 5 string inputs from the user using array of pointers to strings. However, I want those strings to have white spaces and hence, I am using the %[^\n]s which accepts the string till a line break occurs. But, this code doesn't work :/ Can someone please explain why??

P.S-> If you use %s in scanf, the code works. But I want white spaces compulsorily. So, please suggest something.

Thanks in advance!

#include<stdio.h>
#include<malloc.h>

void main()
{
        char *f[5];
        int i;
        printf("\nEnter 5 strings:\n");
        for(i=0;i<5;i++)
            f[i]=malloc(20);
        for(i=0;i<5;i++)
            scanf("%[^\n]s",f[i]);
        printf("The 5 strings are:\n");
        for(i=0;i<5;i++)
        {
            printf("\n%s",f[i]);
        }
}
Syd
  • 15
  • 2

2 Answers2

2

One major problem is the trailing 's' in your format. If you read e.g. this reference you will see that the "%[" format is terminated by the ']' character. When you have that extra 's' in the format, scanf will wait until it matches a literal 's' in the input.

And to skip the ending newline, you can add a leading whitespace in the format and scanf will automatically read and skip all whitespace (including newline) that you don't want in the next iteration of the loop.

You also should limit the length of the input scanf reads, or you might have scanf read more than you have allocated. The limit should be 19 characters (which with the string terminator is 20, like you have allocated).

So the correct format should be " %19[^\n]".


As a side-note, since you allocate all strings equally, why not simply have an array of arrays? Like

char f[5][20];

And if you still decide to go with the pointers, don't forget to free them when you're done. You don't really need it in such a simple case such as your program, but it's better to get the good habits early.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Thank you so much for explaining :) And yes i realize that arrays are the better way to go but I took 20 just as an example.. Actually I'm gonna have variable length strings so i figured pointers were easier.. I'm making my first dictionary! yayyyyy ^_^ – Syd Sep 07 '14 at 15:06
0

You just need to 'consume' the '\n' character after you've read what you want. Use the following format directive:

"%[^\n]%*c"

Which will read everything up to the newline into the string you pass in, then will consume a single character (the newline) without assigning it to anything (that '*' is 'assignment suppression').

Prasanth Louis
  • 4,658
  • 2
  • 34
  • 47
  • That worked like a charm! Thanks so much :). But can you please explain why this [^\n]%s was the wrong choice? Pleaseee – Syd Sep 07 '14 at 14:58
  • When you use scanf() to read the strings, your format string (%[^\n]) tells the function to read every character that is not '\n'. That leaves the '\n' character in the input buffer. If this helped please vote it up – Prasanth Louis Sep 07 '14 at 15:04