簡體   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