2012-04-23 66 views
0

我想將下面的C代碼翻譯成C++。fscanf C++等效

FILE *fp = NULL; 
fp = fopen("./filename", "r"); 
int i = 0; 
fscanf(fp, "%d\n", &i); 
uint16_t j = (uint16_t) i; 

這是我想出了這一點:

ifstream file; 
    string filename = "./filename"; 

    file.open(filename.c_str(), ios::in); 
    errno = 0; 
    if (file.fail()) { 
     int tmp = errno; 
     std::cout << file.c_str() << " not found: strerror(" << tmp << "): " << strerror(tmp)); 
    } 
    int i = 0; 
    file >> i >> std::endl;  
    uint16_t j = (uint16_t) i; 

我想知道的語法是否正確的或可改善,更重要的它是否是對各種輸入安全。

+0

首先,我會說試試看。如果有錯誤,那麼就特別提問那些問題,而不是「對社區來說這是正確的」。針對這兩種程序嘗試不同的輸入,並查看哪些程序失敗,以及它們爲什麼不同。 – 2012-04-23 15:23:58

+2

或者你可以保留原來的C代碼。 C++是C的超集。 – 2012-04-23 15:26:34

+0

@RogerLipscombe:取決於C++版本。 C++ 03沒有C99'uint16_t',但並不是每個人都已經切換到C++ 11。 – 2012-04-23 15:30:13

回答

2
int read_int(const std::string file_name) { 
    std::ifstream file(file_name); //the file will close itself on destruction 
    std::uint16_t i; 
    //extract type, don't worry about what it is it will either compile or not 
    if(!(file >> i)) { //Catch failure 
     //or however you wish to deal with it. 
     throw std::runtime_error("can't read file"); 
    } 
    return i; 
} 

int main() { 
    try{ 
     std::uint16_t i=read_int("./filepath"); 
     //do with i... 
    } 
    catch(const std::exception& e) { 
     std::cerr << e.what() << std::endl; 
     return EXIT_FAILURE; 
    } 
    return EXIT_SUCCESS; 
} 

注意,如果你沒有C++ 11,那麼你將需要使用c_str()打開該文件,但該字符串的方法是首選。

編輯:fstream的封閉自己,沒有必要給自己關閉它的功能是有櫃面你必須這樣做,但它遠不如依靠RAII語義:

http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization

RAII規定您應該在構建時打開該文件,並且它會在破壞時關閉,這可以確保沒有任何無效(排除EOF,找不到文件...)防止錯誤的fstream對象。 RAII是C++中的一個基本構造,應該在有關資源的地方使用。

爲fstream的析構函數的文檔是在這裏:

http://en.cppreference.com/w/cpp/io/basic_fstream

自毀的basic_fstream的和相關的緩衝區,關閉文件

+0

@Blastfurnace是的,我做 – 111111 2012-04-23 15:52:04

+0

@chris,再次感謝,我剛剛從雨中進來,這對於這個東西來說還爲時過早。 :S – 111111 2012-04-23 15:54:55

+0

您可以請我轉到一個文件,它說這個文件在破壞時會自動關閉,當這樣打開時?我只是找不到它... – bob 2012-04-24 07:37:53

2

完全等效是:

std::ifstream fs("./filename"); 
int i = 0; 
fs >> i >> std::ws; 
uint16_t j = i; 

是否硫s是你真正想要的是另一個問題:在格式字符串使用 "\n"fscanf建議(對我來說,至少)是 你真的想讀一個單一的'\n',而不是任意的空白; 然而,表示fscanf的含義是跳到下一個 非空格。 (在交互式輸入的情況下,這可能是一個真正的 問題,因爲直到你遇到一個非空白 字符或文件的最後,您將無法從scanf —或我 更換退貨上述—。對於從文件輸入時,它可能不是一個 問題。)

當讀線定向輸入時,經典的解決方案是使用 std::getline,然後一個std::istringstream解析它。