在下面的代码中,我需要从格式为“ [double,double] string”的行中提取双精度字符和字符串,该字符串以第一个非白色字符开头,而在之后为任意数量的白色字符[
我确实关心正确加载数字,但不关心字符串(甚至可以为空)。
char *read;
size_t len=0;
double x,y;
int size;
getline(&read,&len,stdin);
char *name=(char*)malloc(strlen(read));
if(sscanf(read,"[ %lf, %lf ] %n",&x,&y,&size)!=2)
{
return 0;
}
sscanf(read,"%*.c%[^\n]s",size,name);
我已经实现了所有内容。我知道第二个sscanf不能像这样工作,只能代表我的想法。有什么办法可以使size变量成为不加载多少个字符的参数?我搜索了所有内容,唯一能找到的就是定义了编号,在这里无济于事。
而且我对编程还很陌生,所以请对我有所了解,也许不了解基本知识。
scanf
可能会忽略与*
格式化程序的匹配。有关转换规范here的更多信息。这样,您可以匹配并存储double并匹配并忽略以下字符串,即%*s
。一种更简单的方法可能是通过]
搜索strchr
,然后通过简单的指针算法仅将sscanf
传递给您真正感兴趣的字符串部分(现在您知道它的开始和结束位置)。
"[123.456, 789.34] Daffy Duck"
进入两个双打,并使用getline
和sscanf
的名称为name
分配存储,然后一次调用POSIX getline()
,一次调用sscanf
将名称读入一个临时数组,然后分配并复制到name
将使您可以完全根据需要调整name
的大小。例如:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 1024
int main (void) {
double x, y;
char *read = NULL, *name = NULL, tmp[MAXN];
size_t n = 0;
fputs ("input: ", stdout);
if (getline (&read, &n, stdin) == -1) {
fputs ("error: getline.\n", stderr);
return 1;
}
if (sscanf (read, " [%lf ,%lf ] %1023[^\n]", &x, &y, tmp) == 3) {
size_t len = strlen (tmp);
if (!(name = malloc (len + 1))) {
perror ("malloc-name");
return 1;
}
memcpy (name, tmp, len + 1);
printf ("x : %f\ny : %f\nname: %s\n", x, y, name);
free (name);
}
free (read);
}
无需强制转换malloc
的返回值,这是不必要的。请参阅:Do I cast the result of malloc?还请注意,当参数
n = 0
如上时,getline()
将根据需要分配存储空间以处理您的输入行。因此,在调用getline()
之后,read
已分配了存储时间。您将需要释放read
以避免内存泄漏,并且不能简单地将指针返回name
中read
的开头,因为必须保留指向read
开头的指针才能[ C0]。示例使用/输出
[free
format-string中包含适当的空格,您可以灵活地读取输入内容,而不用考虑前导空格或中间空格,例如]
sscanf
输入中没有空格:
$ ./bin/readxyname input: [123.456, 789.34] Daffy Duck x : 123.456000 y : 789.340000 name: Daffy Duck
在输入中带有任意空格:
$ ./bin/readxyname input: [123.456,789.34]Daffy Duck x : 123.456000 y : 789.340000 name: Daffy Duck
仔细检查,如果还有其他问题,请告诉我。