112

I'm using Ubuntu and I'm also using Geany and CodeBlock as my IDE. What I'm trying to do is reading a string (like "Barack Obama") and put it in a variable:

#include <stdio.h>

int main(void)
{
    char name[100];

    printf("Enter your name: ");
    scanf("%s", name);
    printf("Your Name is: %s", name);

    return 0;
}

Output:

Enter your name: Barack Obama
Your Name is: Barack

How can I make the program read the whole name?

1
  • 1
    just a simple answer, use: scanf("%[^\n]", char_variable_name); Commented Jun 22, 2019 at 7:42

13 Answers 13

205

Use:

fgets (name, 100, stdin);

100 is the max length of the buffer. You should adjust it as per your need.

Use:

scanf ("%[^\n]%*c", name);

The [] is the scanset character. [^\n] tells that while the input is not a newline ('\n') take input. Then with the %*c it reads the newline character from the input buffer (which is not read), and the * indicates that this read in input is discarded (assignment suppression), as you do not need it, and this newline in the buffer does not create any problem for next inputs that you might take.

Read here about the scanset and the assignment suppression operators.

Note you can also use gets but ....

Never use gets(). Because it is impossible to tell without knowing the data in advance how many characters gets() will read, and because gets() will continue to store characters past the end of the buffer, it is extremely dangerous to use. It has been used to break computer security. Use fgets() instead.

Sign up to request clarification or add additional context in comments.

10 Comments

@Stallman: You cannot declare the string as char name[], so that is not a valid C syntax. A C-string is a sequence of bytes terminated by null character. Therefore we can always know the end of the string. Even if we point at a memory location which does not represent a starting of a string, the string will be considered from starting of the address upto the first occurnce of a null character.
Ok... Do we must initialize the size of a C-string, like char name[number]="somestring here"; or char name[]="";//even nothing is created, it still exist a null character? And if I don't explicitly declare the size of the C-String, can I input any length of characters?
@phoxis Why the %*c ? Any reason to use c, and not any other letter? Because I couldn't find a reference to it on the net. Also, I've been doing scanf("%[^\n]\n", name) to discard the newline character and works pretty well.
@Djack: %*c just gets rid of any character, lets say when it is not \n .
%c represents a character just like %d represents a integer, %*c all characters. So totally it means read all characters until you encounter a new line character @NathanProgrammer
|
24

Try this:

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

\n just sets the delimiter for the scanned string.

1 Comment

Also the s does not make sense here. %[^\n] already asks for all characters but a new-line.
9

The correct answer is this:

#include <stdio.h>

int main(void)
{
    char name[100];

    printf("Enter your name: ");
    // pay attention to the space in front of the %
    //that do all the trick
    scanf(" %[^\n]s", name);
    printf("Your Name is: %s", name);

    return 0;
}

That space in front of % is very important, because if you have in your program another few scanf let's say you have 1 scanf of an integer value and another scanf with a double value... when you reach the scanf for your char (string name) that command will be skipped and you can't enter value for it... but if you put that space in front of % will be ok everything and not skip nothing.

2 Comments

Also the s does not make sense here. %[^\n] already asks for all characters but a new-line.
This thing bugged me for a long time. Thanks for providing the solution. Putting space at the beginning of [^\n] prevented skipping of the input.
6

Here is an example of how you can get input containing spaces by using the fgets function.

#include <stdio.h>

int main()
{
    char name[100];
    printf("Enter your name: ");
    fgets(name, 100, stdin); 
    printf("Your Name is: %s", name);
    return 0;
}

Comments

6
scanf(" %[^\t\n]s",&str);

str is the variable in which you are getting the string from.

1 Comment

Also the s does not make sense here.
2

NOTE: When using fgets(), the last character in the array will be '\n' at times when you use fgets() for small inputs in CLI (command line interpreter) , as you end the string with 'Enter'. So when you print the string the compiler will always go to the next line when printing the string. If you want the input string to have null terminated string like behavior, use this simple hack.

#include<stdio.h>
int main()
{
 int i,size;
 char a[100];
 fgets(a,100,stdin);;
 size = strlen(a);
 a[size-1]='\0';

return 0;
}

Update: Updated with help from other users.

2 Comments

There will not be \n if input length exceeds available space, in your example, 100 characters.
@user694733 yes, but at times we use fgets with CLI for small inputs. This note was targeted for that scenario, thank you for pointing that out,.
1
#include <stdio.h>
// read a line into str, return length
int read_line(char str[]) {
int c, i=0;
c = getchar();
while (c != '\n' && c != EOF) { 
   str[i] = c;
   c = getchar();
   i++;
}
str[i] = '\0';
return i;
}

2 Comments

a bit of description about what you are writing in your code and what the OP should do to achieve the required functionality would make your answer more efficient
Your code does not take into account the size of the array. It can overflow.
0

"%s" will read the input until whitespace is reached.

gets might be a good place to start if you want to read a line (i.e. all characters including whitespace until a newline character is reached).

4 Comments

-1/2: gets is useful only for introducing points of failure in your code. Use fgets instead.
@John, scanf is just as unsafe, especially with "%s". The OP is clearly not writing production code, and presumably by the time they will be, they'll be aware that fgets provides protection against buffer overruns. And all of that I tried to sum up in the words "good place to start"
need to flush the standard input first before use gets if you've used scanf before =)) while((c=getchar())!='\n' && c!=EOF);
Using gets() is a complete no-no! It's a route into disaster, as it does not provide a way to avoid buffer overflows. It's not even part of the C language anymore.
0

Using this code you can take input till pressing enter of your keyboard.

char ch[100];
int i;
for (i = 0; ch[i] != '\n'; i++)
{
    scanf("%c ", &ch[i]);
}

Comments

0

While the above mentioned methods do work, but each one has it's own kind of problems.

You can use getline() or getdelim(), if you are using posix supported platform. If you are using windows and minigw as your compiler, then it should be available.

getline() is defined as :

ssize_t getline(char **lineptr, size_t *n, FILE *stream);

In order to take input, first you need to create a pointer to char type.

#include <stdio.h>
#include<stdlib.h>

// s is a pointer to char type.
char *s;
// size is of size_t type, this number varies based on your guess of 
// how long the input is, even if the number is small, it isn't going 
// to be a problem
size_t size = 10;

int main(){
// allocate s with the necessary memory needed, +1 is added 
// as its input also contains, /n character at the end.
    s = (char *)malloc(size+1);
    getline(&s,&size,stdin);
    printf("%s",s);
    return 0;
}

Sample Input:Hello world to the world!

Output:Hello world to the world!\n

One thing to notice here is, even though allocated memory for s is 11 bytes, where as input size is 26 bytes, getline reallocates s using realloc().

So it doesn't matter how long your input is.

size is updated with no.of bytes read, as per above sample input size will be 27.

getline() also considers \n as input.So your 's' will hold '\n' at the end.

There is also more generic version of getline(), which is getdelim(), which takes one more extra argument, that is delimiter.

getdelim() is defined as:

ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream);

Linux man page

Comments

0

If you need to read more than one line, need to clear buffer. Example:

int n;
scanf("%d", &n);
char str[1001];
char temp;
scanf("%c",&temp); // temp statement to clear buffer
scanf("%[^\n]",str);

Comments

-1

"Barack Obama" has a space between 'Barack' and 'Obama'. To accommodate that, use this code;

#include <stdio.h>
int main()
{
    printf("Enter your name\n");
   char a[80];
   gets(a);
   printf("Your name is %s\n", a);
   return 0;
}

2 Comments

Your gets() will induce security problems! Buffer overflow if I'm not wrong. The other answer here explains what I mean.
Why is the gets function so dangerous that it should not be used?. gets() have been deprecated since C99 and removed from C11, long before 2016
-7
scanf("%s",name);

use & with scanf input

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.