163

使用以下代码:

char *name = malloc(sizeof(char) + 256); 

printf("What is your name? ");
scanf("%s", name);

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

用户可以输入他们的名字,但是当他们输入一个带有空格的名字时,就会Lucas Aardvark切断scanf()后面的所有内容Lucas。如何使scanf()允许空间

4

11 回答 11

227

人们(尤其是初学者)不应该使用scanf("%s")orgets()或任何其他没有缓冲区溢出保护的函数,除非您确定输入将始终是特定格式(甚至可能不是)。

请记住scanf,“扫描格式化”的意思是“扫描格式化”,而且格式化比用户输入的数据少一些。如果您可以完全控制输入数据格式但通常不适合用户输入,这是理想的选择。

使用fgets()具有缓冲区溢出保护)将您的输入转换为字符串并sscanf()对其进行评估。sscanf()由于您只想要用户输入的内容而不进行解析,因此在这种情况下您实际上并不需要:

#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;
}
于 2009-08-08T04:59:36.630 回答
141

尝试

char str[11];
scanf("%10[0-9a-zA-Z ]", str);

希望有帮助。

于 2009-08-08T04:39:18.967 回答
63

这个例子使用了一个倒置的扫描集,所以 scanf 一直在接收值,直到它遇到一个 '\n'-- 换行符,所以空格也被保存了

#include <stdio.h>

int main (int argc, char const *argv[])
{
    char name[20];

    // get up to buffer size - 1 characters (to account for NULL terminator)
    scanf("%19[^\n]", name);
    printf("%s\n", name);
    return 0;
}
于 2009-08-09T14:31:26.317 回答
26

你可以用这个

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

或这个

void getText(char *message, char *variable, int size){
    printf("\n %s: ", message);
    fgets(variable, sizeof(char) * size, stdin);
    sscanf(variable, "%[^\n]", variable);
}

char name[20];
getText("Your name", name, 20);

演示

于 2013-08-22T03:24:47.387 回答
8

不要在未scanf()指定字段宽度的情况下读取字符串。您还应该检查返回值是否有错误:

#include <stdio.h>

#define NAME_MAX    80
#define NAME_MAX_S "80"

int main(void)
{
    static char name[NAME_MAX + 1]; // + 1 because of null
    if(scanf("%" NAME_MAX_S "[^\n]", name) != 1)
    {
        fputs("io error or premature end of line\n", stderr);
        return 1;
    }

    printf("Hello %s. Nice to meet you.\n", name);
}

或者,使用fgets()

#include <stdio.h>

#define NAME_MAX 80

int main(void)
{
    static char name[NAME_MAX + 2]; // + 2 because of newline and null
    if(!fgets(name, sizeof(name), stdin))
    {
        fputs("io error\n", stderr);
        return 1;
    }

    // don't print newline
    printf("Hello %.*s. Nice to meet you.\n", strlen(name) - 1, name);
}
于 2009-08-08T16:04:16.887 回答
7

您可以使用该fgets()函数来读取字符串或使用scanf("%[^\n]s",name);这样的字符串读取将在遇到换行符时终止。

于 2012-09-17T12:17:31.217 回答
5

getline()

现在仍然是 POSIX 的一部分。

它还处理了您之前询问的缓冲区分配问题,尽管您必须free处理内存。

于 2009-08-08T16:39:58.453 回答
4

如果有人还在寻找,这对我有用 - 读取任意长度的字符串,包括空格。

感谢网络上的许多海报分享这个简单而优雅的解决方案。如果它有效,那么功劳归于他们,但任何错误都是我的。

char *name;
scanf ("%m[^\n]s",&name);
printf ("%s\n",name);
于 2017-11-06T01:57:37.203 回答
1

你可以用scanf一个小技巧来达到这个目的。实际上,您应该允许用户输入,直到用户按下 Enter ( \n)。这将考虑每个字符,包括空格。这是示例:

int main()
{
  char string[100], c;
  int i;
  printf("Enter the string: ");
  scanf("%s", string);
  i = strlen(string);      // length of user input till first space
  do
  {
    scanf("%c", &c);
    string[i++] = c;       // reading characters after first space (including it)
  } while (c != '\n');     // until user hits Enter
  string[i - 1] = 0;       // string terminating
return 0;
}

这是如何工作的?当用户从标准输入输入字符时,它们将存储在字符串变量中,直到第一个空格。之后,其余条目将保留在输入流中,并等待下一个 scanf。接下来,我们有一个for循环,它从输入流(直到\n)中逐个字符地获取它们并将它们附加到字符串变量的末尾,从而形成一个与用户从键盘输入相同的完整字符串。

希望这会对某人有所帮助!

于 2015-01-18T11:06:05.747 回答
0

虽然你真的不应该使用scanf()这种东西,因为有更好的调用,比如gets()or getline(),它可以做到:

#include <stdio.h>

char* scan_line(char* buffer, int buffer_size);

char* scan_line(char* buffer, int buffer_size) {
   char* p = buffer;
   int count = 0;
   do {
       char c;
       scanf("%c", &c); // scan a single character
       // break on end of line, string terminating NUL, or end of file
       if (c == '\r' || c == '\n' || c == 0 || c == EOF) {
           *p = 0;
           break;
       }
       *p++ = c; // add the valid character into the buffer
   } while (count < buffer_size - 1);  // don't overrun the buffer
   // ensure the string is null terminated
   buffer[buffer_size - 1] = 0;
   return buffer;
}

#define MAX_SCAN_LENGTH 1024

int main()
{
   char s[MAX_SCAN_LENGTH];
   printf("Enter a string: ");
   scan_line(s, MAX_SCAN_LENGTH);
   printf("got: \"%s\"\n\n", s);
   return 0;
}
于 2016-09-29T23:52:19.940 回答
0
/*reading string which contains spaces*/
#include<stdio.h>
int main()
{
   char *c,*p;
   scanf("%[^\n]s",c);
   p=c;                /*since after reading then pointer points to another 
                       location iam using a second pointer to store the base 
                       address*/ 
   printf("%s",p);
   return 0;
 }
于 2019-05-15T13:58:18.357 回答