0
int main (){
    char test1 [25];
    printf("Enter a string:\n");
    scanf("%s",&test1);
    printf("%s\n",test1);
}

This code should simply print and entered string. If I enter "Hello Wolrd" it only prints "Hello" as a result. How can I fix this?

ajay
  • 9,402
  • 8
  • 44
  • 71
user3078379
  • 19
  • 2
  • 6

5 Answers5

3

scanf with %s reads only until space or new line. Instead use fgets.

  char buffer[256];
  fgets(buffer, 256, stdin);
Sanketh
  • 1,247
  • 11
  • 18
0

scanf never reads spaces in input.

If there is a space in input than it will consider as end of input for the variable you are reading for.

Use fgets() to get your input into a string and sscanf() to evaluate it. Since you just want what the user entered, you don't really need sscanf() in this case anyway:

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

/* Maximum name size + 1. */
#define MAX_NAME_SZ 256

int main(int argC, char *argV[]) {
    /* Allocate memory and check if okay. */
    char *name = malloc (MAX_NAME_SZ);
    if (name == NULL) {
        printf ("No memory\n");
        return 1;
    }

    /* Ask user for name. */
    printf("What is your name? ");

    /* Get the name, with size limit. */
    fgets (name, MAX_NAME_SZ, stdin);

    /* Remove trailing newline, if there. */
    if ((strlen(name)>0) && (name[strlen (name) - 1] == '\n'))
        name[strlen (name) - 1] = '\0';

    /* Say hello. */
    printf("Hello %s. Nice to meet you.\n", name);

    /* Free memory and exit. */
    free (name);
    return 0;
}
coder hacker
  • 4,819
  • 1
  • 25
  • 50
  • "If there is a space in input than it will consider as end ..." ignores that `scanf("%s"` _does_ read white-space. It reads but does not save leading white-space. Then subsequently reads and saves non-white-space. It stops and does not consume trailing white-space. – chux - Reinstate Monica Apr 11 '14 at 16:45
0

Not only scanf!

The problem is related with the %s conversion. It says that on the documentation:

 %s  Matches a sequence of non-white-space characters;
     the next pointer must be a pointer to char, and the array
     must be large enough to accept all the sequence and the
     terminating NUL character. The input string stops at white
     space or at the maximum field width, whichever occurs first.

You could use only a fgets to do what you want.

AndreDurao
  • 5,600
  • 7
  • 41
  • 61
  • Its better not to use `gets` due to its unpredictable nature. For more info look [here](http://stackoverflow.com/questions/7423691/is-gets-officially-deprecated) – Sanketh Apr 11 '14 at 16:12
  • It's important to understand that it's not scanf's fault. And yes it says: "SECURITY CONSIDERATIONS The gets() function cannot be used securely. Because of its lack of bounds checking, and the inability for the calling program to reliably determine the length of the next incoming line, the use of this function enables mali- cious users to arbitrarily change a running program's functionality through a buffer overflow attack. It is strongly suggested that the fgets() function be used in all cases. (See the FSA.)" – AndreDurao Apr 11 '14 at 16:16
0

%s conversion specifier in the format string means scanf reads a string from the stdin buffer. Reading stops when a whitespace character is encountered and a terminating null byte is added to the buffer before scanf returns. This means when you enter

"Hello Wolrd
      ^ space here

scanf only read Hello and returns. The corresponding argument to scanf should be a pointer to the buffer, i.e., of type char *, which stores the string and must be large enough to contain the input string else scanf will overrun the buffer invoking undefined behaviour. However &test1 has type char (*)[25], i.e., a pointer to an array of 25 characters. What you need is

int main(void) {
    char test1[25];
    printf("Enter a string:\n");
    scanf("%24[^\n]", test1);
    printf("%s\n",test1);
    return 0;
}

%24[^\n] in the format string of scanf means that scanf will read an input string of length at most 24 and the string should not contain a newline. If either condition fails, scanf will return. One character space should be save for the terminating null byte added by scanf. Therefore we have 24 instead of 25 in the format string.

Alternatively, you can use fgets to read a line from a stream. The scanf call above can be replaced by

char test1[25];
fgets(test1, sizeof test1, stdin);

fgets reads at most one less than sizeof test1 characters from stdin (saves one character space for the terminating null byte) or till it reads a newline - whichever occurs first. If it reads a newline, it is stored in the buffer test1.

ajay
  • 9,402
  • 8
  • 44
  • 71
0

In C, strings end with '\0'.

In text files and console input, a different standard is used. Typically text up to and maybe including '\n' is a line or string.

scanf("%s", test1); saves non-white-space text. It skips leading white-space and than scans and saves non-white-space text. It continues until EOF condition or white-space (such as ' ' or '\n') is encountered. It does not save white-space. It then appends a '\0' to the destination.

Suggest not using scanf(), but fgets() and then parse the received buffer as needed with sscanf(), strto*(), strtok(), etc..

fgets() will save all text. It will stop after saving a '\n' or if the buffer is about full. It then appends a '\0' to the destination. It will not overfill the destination buffer.

int main (){
    char test1[25];
    printf("Enter a string:\n");
    fgets(test1, sizeof test1, stdin);
    printf("%s",test1);
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256