对于一个项目,我正在尝试从字符串中读取int和字符串。唯一的问题是sscanf在看到空格时似乎打破了读取%s。反正有没有解决这个限制?以下是我正在尝试做的一个例子:
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char** argv) {
int age;
char* buffer;
buffer = malloc(200 * sizeof(char));
sscanf("19 cool kid", "%d %s", &age, buffer);
printf("%s is %d years old\n", buffer, age);
return 0;
}
它打印的是:“酷是19岁”,我需要“酷孩子19岁”。有谁知道如何解决这个问题?
答案 0 :(得分:40)
以下行将开始读取一个数字(%d
),后跟与标签或换行符不同的任何内容(%[^\t\n]
)。
sscanf("19 cool kid", "%d %[^\t\n]", &age, buffer);
答案 1 :(得分:11)
你想要%c
转换说明符,它只读取一个字符序列而不需要特殊处理空格。
请注意,您需要先用零填充缓冲区,因为%c
说明符不会写入nul-terminator。您还需要指定要读取的字符数(否则默认为1):
memset(buffer, 0, 200);
sscanf("19 cool kid", "%d %199c", &age, buffer);
答案 2 :(得分:8)
如果你想扫描到字符串的末尾(如果有的话,剥去换行符),只需使用:
char *x = "19 cool kid";
sscanf (x, "%d %[^\n]", &age, buffer);
那是因为%s
只匹配非空白字符,并且会在它找到的第一个空格上停止。 %[^\n]
格式说明符将匹配给定选择中的每个字符(因为^
)(这是换行符)。换句话说,它将匹配任何其他角色。
请记住,您应该在缓冲区中分配足够的空间来获取字符串,因为您无法确定将读取多少内容(除非您使用特定的字段宽度,否则远离scanf/fscanf
的一个很好的理由)
你可以这样做:
char *x = "19 cool kid";
char *buffer = malloc (strlen (x) + 1);
sscanf (x, "%d %[^\n]", &age, buffer);
(您不需要* sizeof(char)
,因为根据定义总是 1。
答案 3 :(得分:2)
由于您需要输入中的尾随字符串,因此可以使用%n
(到目前为止消耗的字符数)来获取尾随字符串开始的位置。这样可以避免内存复制和缓冲区大小调整问题,但如果您需要副本,则可能需要明确地执行这些操作。
const char *input = "19 cool kid";
int age;
int nameStart = 0;
sscanf(input, "%d %n", &age, &nameStart);
printf("%s is %d years old\n", input + nameStart, age);
输出:
cool kid is 19 years old
答案 4 :(得分:-1)
我想这就是你想要的,它完全符合你的指定。
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char** argv) {
int age;
char* buffer;
buffer = malloc(200 * sizeof(char));
sscanf("19 cool kid", "%d cool %s", &age, buffer);
printf("cool %s is %d years old\n", buffer, age);
return 0;
}
格式需要:首先是一个数字(并将其放在where和age指向的位置),然后是空格(零或更多),然后是文字字符串&#34; cool&#34;,然后是空格(零或更多) )再次,然后最后一个字符串(并把它放在任何缓冲点)。 你忘记了&#34;酷&#34;部分在您的格式字符串中,因此格式然后假定这是您想要分配给缓冲区的字符串。但是你不想分配那个字符串,只能跳过它。
另外,你也可以有一个格式字符串,如:&#34;%d%s%s&#34;,但是你必须为它指定另一个缓冲区(使用不同的名称),并将其打印为:& #34;%s%s是%d岁\ n&#34;。