我的问题与此one完全相同。也就是说,我试图使用scanf()
来接收一串不确定的长度,我想scanf()
为它动态分配内存。使用scanf动态分配()
但是,在我的情况下,我使用VS2010。据我所知,MS的scanf()在扫描字符串时没有a或m修饰符。有没有办法做到这一点(除了一次接收一个字符)?
我的问题与此one完全相同。也就是说,我试图使用scanf()
来接收一串不确定的长度,我想scanf()
为它动态分配内存。使用scanf动态分配()
但是,在我的情况下,我使用VS2010。据我所知,MS的scanf()在扫描字符串时没有a或m修饰符。有没有办法做到这一点(除了一次接收一个字符)?
如果你想使用scanf
你可以只分配一个足够大的缓冲区来存放任何可能的值,即1024个字节,然后用1024
的m
和a
最大字段宽度说明符是特定非标准的GNU扩展,这就是为什么微软编译器不支持它们的原因。人们可能希望视觉工作室做到。
下面是一个使用scanf
阅读设置,只打印他们回来了一个例子:
#include <stdio.h>
#include <errno.h>
#include <malloc.h>
int
main(int argc, char **argv)
{ // usage ./a.out < settings.conf
char *varname;
int value, r, run = 1;
varname = malloc(1024);
// clear errno
errno = 0;
while(run)
{ // match any number of "variable = #number" and do some "processing"
// the 1024 here is the maximum field width specifier.
r = scanf ("%1024s = %d", varname, &value);
if(r == 2)
{ // matched both string and number
printf(" Variable %s is set to %d \n", varname, value);
} else {
// it did not, either there was an error in which case errno was
// set or we are out of variables to match
if(errno != 0)
{ // an error has ocurred.
perror("scanf");
}
run = 0;
}
}
return 0;
}
下面是一个例子settings.conf
cake = 5
three = 3
answertolifeuniverseandeverything = 42
charcoal = -12
你可以阅读更多关于scanf
on the manpages。
而你当然可以使用getline()
,然后在字符之后解析字符。
如果你想进一步了解你想要达到的目标,你可能会得到更好的答案。
我会解释如何编写一个字段宽度说明符,因为OP很可能不知道,只是忽略这个建议,造成缓冲区溢出漏洞...... – 2010-10-12 05:49:39
对,我可能应该。但是OP代表什么? – Frank 2010-10-12 06:15:44
我认为,在现实世界中,需要对用户输入的长度有一些最大限制。
然后,您可以阅读整个行,如getline()
。请参阅http://www.cplusplus.com/reference/iostream/istream/getline/
请注意,如果您要从用户输入多个数据,则不需要为每个数组分别分配char
数组。你可以有一个大的缓冲区,例如char buffer[2048]
,与getline()
一起使用,并将内容复制到适当分配(和命名)的变量,例如,像char * name = strdup(buffer)
。
如果缓冲区不够大,那么让getline()为你分配一个缓冲区可能会更好,那么getline()会使它足够大。 – Frank 2010-10-12 04:28:04
绝对要用scanf
?是不是std::string s; std::cin >> s;
或getline(std::cin, s);
是您的选择?
请勿使用scanf
来读取字符串。它甚至可能不会做你认为它所做的事情; %s
只读直到下一个空格。
scanf()
的标准版本不会为其读取的任何变量分配内存。
如果您在某些scanf()
版本中使用非标准扩展名被忽略,那么您刚开始学习如何编写可移植代码的第一课 - 不使用非标准扩展。您可以细微地说,“不要使用在您感兴趣的所有平台上不可用的扩展”,但要意识到随着时间的推移,这组平台可能会发生变化。
+1,用于指出如何依赖不可移植的扩展来限制OP。 – 2010-10-12 05:48:46
GNU C Library支持'a'作为'分配内存'修饰符; GNU C Library版本2.8(我碰巧拥有的手册)没有提到'm'作为修饰符。这是自2.8以来的又一次增加吗? – 2010-10-12 04:05:35
从2008-07-12 3.23版我的手册中提到了两者。 'm'修饰符是GNU扩展'a'的替代品,因为它与匹配浮点数的c99修饰符'a'相冲突。 – Frank 2010-10-12 04:20:37
@Frank:下载更新的时间...谢谢。这是偶尔的非标准扩展的另一个缺点 - 标准通过标准化来改变非标准的含义。 – 2010-10-12 05:36:41