10

无论出于何种原因,以下代码都会打印(null):

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

int main(void)
{
    char *foo; 
    scanf("%ms", &foo);
    printf("%s", foo);
    free(foo);
}

我正在尝试为字符串动态分配内存,但正如我之前所说,我的程序只是输出(null)。我通过使用 getche 和 realloc 创建一个函数来解决这个问题,但这似乎几乎毫无意义,因为我还必须编写如果用户输入退格、制表符等会发生什么。但正如我所说,这只是一项工作周围,​​我宁愿知道为什么上面的代码不起作用......

附加信息:

我正在使用 Pelles C IDE v7.00 并使用 C11 标准进行编译

4

5 回答 5

10

我在C11 标准草案%m的第 7.21.6.2节(关于 的部分)中没有看到。我建议你避免它并像在 C99 中那样调用它。fscanfmalloc()

于 2012-08-13T01:08:40.880 回答
1

%m 是一个 POSIX 扩展,这可能是它在 Pelles C 中不可用的原因。

于 2013-04-16T18:06:31.177 回答
1

在 scanf/sscanf 的手册页中有一个示例(第 3 页,第 270-290 行),说明如下:

例子

要使用动态分配转换说明符,请将 m 指定为长度修饰符(因此为 %ms 或 %m[range])。调用者必须释放(3)返回的字符串,如下例所示:

char *p;
int n;

errno = 0;
n = scanf("%m[a-z]", &p);
if (n == 1) {
   printf("read: %s\n", p);
   free(p);
} else if (errno != 0) {
   perror("scanf");
} else {
   fprintf(stderr, "No matching characters\n");
}

如上例所示,只有在 scanf() 调用成功读取字符串时,才需要调用 free(3)。

来源:SCANF(3) - Linux 程序员手册 - GNU - 2013-01-30

于 2020-03-14T22:23:36.377 回答
0

我正在使用 Linux 3.2.0 amd 64 和gcc 4.7.2。使用代码:

char *s; 
scanf("%ms", &s);
printf("%s", s);
free(s);

工作正常,但它不会接受空格。

对于静态分配,您可以改为使用:

char s[100];
printf("Enter string (max 99 characters): ");
scanf("%100[^\n]s", &s);
printf("You entered: %s\n", s);

希望能帮助到你!

于 2014-12-31T14:02:17.090 回答
0

正如Arun所说,这个解决方案是正确的,而Meninx的观点是错误的:

char *s;
scanf("%ms", &s);
printf("%s", s);
free(s);

我读过'man scanf',它说:

可选的“m”字符。这与字符串转换(%s、%c、%[)一起使用,
并且使调用者无需分配相应的缓冲区来保存输入:相反,scanf() 分配了一个足够大小的缓冲区,并分配了地址这个buffer对应的指针 参数,应该是一个char*变量的指针(这个变量在调用前不需要初始化)。当不再需要此缓冲区时,调用者应随后释放(3)此缓冲区。

于 2016-05-24T10:17:34.367 回答