C语言 如何将整行读取为字符串?


int run_add_line_after(Document *doc, char *command) {
int paragraph_num, line_num;
char com[MAX_STR_SIZE + 1], extra[MAX_STR_SIZE + 2], line[MAX_STR_SIZE + 1];
if (sscanf(command, " %s %d %d %s", com, &paragraph_num, &line_num, extra)
== 4 && paragraph_num > 0 && line_num >= 0 && extra[0] == '*') {
strcpy(line, &(extra[1]));
if (add_line_after(doc, paragraph_num, line_num, line) == FAILURE) {
printf("add_line_after failedn");
}
return SUCCESS;
}
return FAILURE;
}

我想让sscanf读取commandextra中剩下的所有内容,但它只取第一个单词。例如,如果我有:

  • 命令:"add_line_after 1 0 *文档的第一行">

I want to see:

  • com:"add_line_after"
  • paragraph_num: 1
  • line_num: 0
  • extra: "文档的第一行">

但是我得到:

  • com:"add_line_after"
  • paragraph_num: 1
  • line_num: 0
  • 额外:"至上">

因为%s在到达空格时停止。我如何阅读其余的行,同时仍然忽略'0''*'之间的任何空白?

作为参考,MAX_STR_SIZE是80和command是一个1025字符数组(虽然我不认为这很重要)。假设extra足够大,可以容纳行其余部分。

sscanf在这里确实是错误的工具。这是可以做到的,但可能不应该用你正在尝试的方式。幸运的是,您没有将com传递给add_line_after,这意味着没有必要确保com是一个正确的以null结尾的字符串,这允许您避免所有不必要的字符串复制。(如果你要传递com,你要么复制它,要么在command中写一个空终止符。)您根本不希望或不需要使用sscanf来移动数据。您可以使用它来解析数值。我不清楚是否要丢弃*后面的任何空白,而此代码没有。如果您想这样做,删除空白是微不足道的,留给读者作为练习:

int
run_add_line_after(struct document *doc, const char *command)
{
int paragraph_num, line_num, n;
const char *line;
if( 2 == sscanf(command, "%*s %d %d %n", &paragraph_num, &line_num, &n)
&& paragraph_num > 0 && line_num >= 0 && command[n] == '*' )
{
line = command + n + 1;
if( add_line_after(doc, paragraph_num, line_num, line) == FAILURE) {
fprintf(stderr, "add_line_after failedn");
} else {
return SUCCESS;
}
}
return FAILURE;
}

这里的想法是简单地使用sscanf来找出extra数据在字符串中的位置,并解析整数值。这绝对是一个错误的工具(scanf系列(几乎)总是错误的工具),这里只用于演示。

—edit—

但是,当然,这并不完全是您想要的。将一些功能移到add_line_after中来处理换行符会简洁得多,但由于还需要删除换行符,因此有必要执行以下操作:

int
run_add_line_after(struct document *doc, char *command)
{
int paragraph_num, line_num, n;
char *line;
if( 2 == sscanf(command, "%*s %d %d %n", &paragraph_num, &line_num, &n)
&& paragraph_num > 0 && line_num >= 0 && command[n] == '*' )
{
line = command + n + 1;
line[strcspn(line, "n")] = '';
if( add_line_after(doc, paragraph_num, line_num, line) == FAILURE) {
fprintf(stderr, "add_line_after failedn");
} else {
return SUCCESS;
}
}
return FAILURE;
}

这并不理想。如果你修改API,这样你就可以避免复制数据和修改给定的字符串。

明白了。格式字符串应该是" %s %d %d %[^n]s"。它将继续读取最后一个字符串变量,直到它按下回车键。

相关内容

  • 没有找到相关文章

最新更新