繁体   English   中英

如何将整行读入字符串?

[英]How do I read a whole line to a string?

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 failed\n");
        }
        return SUCCESS;
    }
    return FAILURE;
}

我希望sscanf读取commandextra的所有内容,但它只占用第一个单词。 例如,如果我有:

  • 命令:“add_line_after 1 0 *文档的第一行”

我想看看:

  • com:“add_line_after”
  • 段落编号:1
  • 行号:0
  • 额外:“文件的第一行”

但相反,我得到:

  • com:“add_line_after”
  • 段落编号:1
  • 行号: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 failed\n");
        } else {
            return SUCCESS;
        }
    }
    return FAILURE;
}

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

- 编辑 -

但是,当然,这并不完全符合您的要求。 将一些功能移动到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")] = '\0';
        if( add_line_after(doc, paragraph_num, line_num, line) == FAILURE) {
            fprintf(stderr, "add_line_after failed\n");
        } else {
            return SUCCESS;
        }
    }
    return FAILURE;
}

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

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

暂无
暂无

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

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