108

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?

alk
  • 66,653
  • 10
  • 83
  • 219
Hieu Nguyen
  • 1,457
  • 3
  • 12
  • 15

14 Answers14

188

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.

zuzak
  • 5
  • 5
phoxis
  • 52,327
  • 12
  • 74
  • 110
  • What if the length of the C-string is unknown? If I delete the number 100 in `char name[100];`, it becomes char name[] and `name` contains no white space. – Alston Nov 14 '13 at 11:42
  • @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. – phoxis Nov 14 '13 at 13:24
  • 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? – Alston Nov 14 '13 at 13:40
  • `char name[]="";` has a null character. We can do `char name[]="My name";`. – phoxis Nov 14 '13 at 13:56
  • 1
    @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. – John Strood Jul 24 '16 at 22:09
  • 1
    @Djack: `%*c` just gets rid of any character, lets say when it is not `\n` . – phoxis Jul 25 '16 at 10:22
  • what does this `%[^\n]%*c` mean? – OverloadedCore Jan 27 '17 at 17:22
  • 2
    %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 – Nobody Jul 05 '17 at 15:33
  • 1
    Just like on should never use `gets`, one should never use `scanf` with a bare `%s` or `%[` conversion -- you should ALWAYS use a size -- so `scanf("%99[^\n]%*c", name);` – Chris Dodd Jun 17 '18 at 20:46
20

Try this:

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

\n just sets the delimiter for the scanned string.

Angel Politis
  • 9,949
  • 12
  • 43
  • 62
Sridhar Iyer
  • 2,553
  • 1
  • 20
  • 27
  • 3
    Also the `s` does not make sense here. `%[^\n]` already asks for all characters but a new-line. – alk Nov 25 '18 at 18:54
7

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;
}
kyle k
  • 4,198
  • 7
  • 29
  • 45
5
scanf(" %[^\t\n]s",&str);

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

Raktim Biswas
  • 3,833
  • 5
  • 22
  • 29
animesh
  • 75
  • 1
  • 1
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.

  • 1
    There will not be `\n` if input length exceeds available space, in your example, 100 characters. – user694733 Jan 18 '17 at 12:05
  • @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,. – Ritesh Sharma May 31 '17 at 13:11
1

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.

Sudheesh Singanamalla
  • 2,025
  • 2
  • 16
  • 31
Cristian Babarusi
  • 1,039
  • 10
  • 16
  • 2
    Also the `s` does not make sense here. `%[^\n]` already asks for all characters but a new-line. – alk Nov 25 '18 at 18:52
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
    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 – Reborn Nov 21 '17 at 19:54
  • 1
    Your code does not take into account the size of the array. It can overflow. – Jazz Aug 30 '18 at 16:36
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]);
}
muXXmit2X
  • 2,595
  • 2
  • 14
  • 33
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

nilsocket
  • 1,209
  • 5
  • 14
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);
levan
  • 330
  • 6
  • 17
-1
#include<stdio.h>
int main()
{
   char name[100];
   printf("Enter your name: ");
   scanf("%[^\n]s",name);
   printf("Your Name is: %s",name);
   return 0;
}
  • 2
    Also the `s` does not make sense here. `%[^\n]` already asks for all characters but a new-line. – alk Nov 25 '18 at 18:53
-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;
}
Raktim Biswas
  • 3,833
  • 5
  • 22
  • 29
Koech
  • 405
  • 6
  • 5
  • 3
    Your gets() will induce security problems! Buffer overflow if I'm not wrong. The other answer here explains what I mean. – Parth Sane Jul 24 '16 at 13:15
  • 1
    [Why is the gets function so dangerous that it should not be used?](https://stackoverflow.com/q/1694036/995714). `gets()` have been deprecated since C99 and removed from C11, long before 2016 – phuclv Feb 06 '21 at 04:38
-1

"%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).

davin
  • 41,227
  • 7
  • 73
  • 77
  • 8
    -1/2: `gets` is useful only for introducing points of failure in your code. Use `fgets` instead. – John Bode Jun 08 '11 at 17:25
  • 1
    @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" – davin Jun 08 '11 at 17:31
  • need to flush the standard input first before use gets if you've used scanf before =)) while((c=getchar())!='\n' && c!=EOF); – Hieu Nguyen Jun 10 '11 at 07:14
  • 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. – alk Nov 25 '18 at 18:55
-5
scanf("%s",name);

use & with scanf input

Bhargav Rao
  • 41,091
  • 27
  • 112
  • 129
Vi_Hari
  • 111
  • 6