c - 使用 sscanf 读取字符串

标签 c input scanf

我正在尝试将一个字符和两个字符串保存到变量中。 我使用 sscanf 读取具有以下形式的字符串:

N "OldName" "NewName"

我想要的:char character = 'N' , char* old_name = "OldName" , char* new_name = "NewName" .

这就是我尝试这样做的方式:

sscanf(mystring,"%c %s %s",&character,old_name,new_name);
printf("%c %s %s",character,old_name,new_name);

问题是,我的问题在没有任何输出的情况下停止工作。 (我也想忽略引号,只保存它的内容)

最佳答案

当你做的时候

char* new_name = "NewName";

您使指针 new_name 指向包含常量字符串文字的只读字符串数组。该数组恰好包含 8 个字符(字符串的字母加上终止符)。

首先,使用该指针作为 scanf 的目标将导致 scanf 写入只读数组,从而导致未定义的行为。如果您提供的字符串长度超过 7 个字符,则 scanf 也会尝试越界写入,再次导致未定义的行为

简单的解决方案是使用实际的数组,而不是指针,并告诉 scanf 不要读取超出数组容量的内容。像这样:

char old_name[64];  // Space for 63 characters plus string terminator
char new_name[64];

sscanf(mystring,"%c %63s %63s",&character,old_name,new_name);

要跳过引号,您有两种选择:使用指针和指针算法跳过前导引号,然后在最后一个引号处设置字符串终止符以“删除”它。另一种解决方案是 move覆盖前导引号的字符串,然后按照前面的解决方案删除最后一个引号。

或者您可以依赖 scanf (and family)有限模式匹配功能:

sscanf(mystring,"%c \"%63s\" \"%63s\"",&character,old_name,new_name);

请注意,上面的 sscanf 调用将起作用iff字符串实际上包含引号。

第二个注意事项:正如 Cool Guy 在评论中所说,由于 scanfgreedy,因此上述内容实际上不起作用。它会一直读取到文件/字符串的末尾或空白,因此它实际上不会在结束的双引号处停止读取。使用 scanf 和 family 的唯一可行解决方案如下。

还要注意 scanf 和 family,当使用 "%s" 读取字符串时停止读取 white-space,所以如果字符串是 "New Name" 那么它也不会工作。如果是这种情况,那么您要么需要手动解析字符串,要么使用奇怪的 "%[" 格式,例如

sscanf(mystring,"%c \"%63[^\"]\" \"%63[^\"]\"",&character,old_name,new_name);

关于c - 使用 sscanf 读取字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36769480/

相关文章:

c - 如何在 C 中读取 fortran 二进制文件?

jquery - HTML 输入搜索找不到大写字母,反之亦然

c - 使用 sscanf 从文件中读取

c++ - 排队的事件数量? (Win32 事件队列)

c - 带有 WSL 的 NCurses 显示框不正确

mysql - 如何在没有mysql_free_result(res)的情况下在c中运行查询

css - W3CSS : centering input field

winapi - CreateFile ("CONIN$"..) 做什么?

C返回字符串计数和字符串问题(rusty in C....)

c - scanf 的异常行为