2

を使用して、長い文字列を空白で分割しようとしていますsscanf()

例:これを分割する必要があります

We're a happy family

の中へ

We're
a
happy
family

私は次のアプローチを試しました

char X[10000];
fgets(X, sizeof(X) - 1, stdin); // Reads the long string
if(X[strlen(X) - 1] == '\n') X[strlen(X) - 1] = '\0'; // Remove trailing newline
char token[1000];
while(sscanf(X, "%s", token) != EOF) {
    printf("%s | %s\n", token, X);
}

前のコードは無限ループに入り、出力しますWe're | We're a happy family

sscanf()C ++に置き換えてみましたがistringstream、問題なく動作しました。

Xがその価値を維持する理由は何ですか?通常のストリームのようにバッファから削除するべきではありませんか?

4

1 に答える 1

2

sscanf()以前に読み取ったバッファに関する情報を格納し、常に渡されたアドレス(バッファ)から開始します。考えられる解決策は、%nフォーマット指定子を使用して、最後sscanf()に停止した位置を記録X + posし、最初の引数としてに渡すことsscanf()です。例えば:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    const char* X = "hello again there";
    char token[1000];
    int current_pos = 0;
    int pos = 0;
    while (1 == sscanf(X + current_pos, "%999s%n", token, &pos))
    {
        current_pos += pos;
        printf("%s | %s\n", token, X + current_pos);
    }
    return 0;
}

http://ideone.com/XBDTWmのデモを参照してください。

または単に使用istringstreamしてstd::string

std::istringstream in("hello there again");
std::string token;
while (in >> token) std::cout << token << '\n';
于 2013-01-18T11:56:59.217 に答える