繁体   English   中英

使用 sscanf 读取带空格的字符串

[英]Reading a string with spaces with sscanf

对于一个项目,我试图从一个字符串中读取一个 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;
}

它打印的是: cool is 19 years old where I need cool kid is 19 years old 有谁知道如何解决这一问题?

以下行将开始读取一个数字( %d ),然后是与制表符或换行符( %[^\\t\\n] )不同的任何内容。

sscanf("19 cool kid", "%d %[^\t\n]", &age, buffer);

您需要%c转换说明符,它只读取一个字符序列而无需对空格进行特殊处理。

请注意,您需要先用零填充缓冲区,因为%c说明符不写入空终止符。 您还需要指定要读取的字符数(否则默认仅为 1):

memset(buffer, 0, 200);
sscanf("19 cool kid", "%d %199c", &age, buffer);

如果你想扫描到字符串的末尾(如果有的话,去掉一个换行符),只需使用:

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 )。

由于您想要来自输入的尾随字符串,您可以使用%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

我想这就是您想要的,它完全符合您的要求。

#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;
}

该格式要求:首先是一个数字(并将其放在 &age 指向的位置),然后是空格(零个或多个),然后是文字字符串“cool”,然后又是空格(零个或多个),最后是一个字符串(和把它放在任何缓冲区指向的地方)。 您忘记了格式字符串中的“cool”部分,因此格式仅假定这是您想要分配给缓冲区的字符串。 但是您不想分配该字符串,只需跳过它。

或者,你也可以有一个格式字符串,如:“%d %s %s”,但你必须为它分配另一个缓冲区(使用不同的名称),并将其打印为:“%s %s is %d years旧\\n”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM