2013-01-18 90 views
1

我想使用sscanf()分隔一個長的字符串與白色空間。使用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

我試圖用C++ istringstream替換sscanf(),它工作正常。

是什麼讓X保持它的價值?不應該像正常流一樣從緩衝區中移除它嗎?

+0

嘗試strtok的替代。但請注意,它不可重入。 – thang

+1

你爲什麼要求sscanf並用C++標記它?相信我,有c專家的頭腦裏有這樣的片段,許多C++的人在「istringstream」工作時不會打擾。 – luk32

+0

在這裏看到另一個選項[我如何在C++中標記字符串?](http://stackoverflow.com/questions/53849/how-do-i-tokenize-a-string-in-c) –

回答

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的演示。

或者只是使用istringstreamstd::string

std::istringstream in("hello there again"); 
std::string token; 
while (in >> token) std::cout << token << '\n'; 
+0

我想了。非常感謝幫助,以及有關sscanf的信息! –