我正在尝试将一个字符和两个字符串保存到变量中。 我使用 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 在评论中所说,由于 scanf
是 greedy,因此上述内容实际上不起作用。它会一直读取到文件/字符串的末尾或空白,因此它实际上不会在结束的双引号处停止读取。使用 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/