2012-04-24 91 views
3

所以我有一個.cpp文件,其中包含一個接收文件名的函數,並且應該返回一個包含文件內容的字符串(實際上修改過的內容,我修改了代碼以使其更易於理解,但沒有任何對我的問題有影響)。問題是f.good()正在返回false和循環,它讀取文件不起作用。 CODE:我的fstream不好還是不好()?

#include "StdAfx.h" 
#include "Form21.h" 
#include <string> 
#include <fstream> 
#include <iostream> 



    string ReadAndWrite(char* a){ 
    char filename[8]; 
    strcpy_s(filename,a); 
    string output; 
    char c; 
    ifstream f(filename,ios::in); 
    output+= "Example text"; // <-- this writes and returns just fine! 
    c = f.get(); 

    while (f.good()) 
     { 

    output+= c; 
    c= f.get();   
      } 

    return output; 
} 

有沒有人對爲什麼會這樣的想法? 它有什麼關係,這是一個單獨的.cpp文件(當我刪除#include <fstream>時它甚至不會拋出錯誤)。 也許有一種不同的方法來使循環? 我很樂意聽到關於如何解決這個問題的任何建議也許是如何實現我的目標的不同方法。

回答

4

首先,真的沒有理由複製你收到的文件名 - 你可以直接使用它。二,形式while (stream.good())while (!stream.bad())while (stream)等,幾乎所有的迴路一定是馬車。你通常想要做的是檢查是否讀取一些數據的工作。

或者,您可以跳過使用循環。有幾種方法可以做到這一點。一個很好地工作在較短的文件看起來是這樣的:

string readfile(std::string const &filename) { 
    std::ifstream f(filename.c_str()); 
    std::string retval; 

    retval << f.rdbuf(); 
    return retval; 
} 

這很好地工作長達幾十數據的千字節(左右),但開始變慢上的文件。在這種情況下,你通常要使用ifstream::read來獲取數據,沿着這條總路線的東西:

std::string readfile(std::string const &filename) { 
    std::ifstream f(filename.c_str()); 

    f.seekg(0, std::ios_base::end); 
    size_t size = f.tellg(); 

    std::string retval(size, ' '); 
    f.seekg(0); 
    f.read(&retval[0], size); 
    return retval; 
} 

編輯:如果你需要處理的單個字符(不只是看他們),你有幾個選擇。一種是將它分成幾個階段,在這個階段你可以讀取一個階段的所有數據,然後在一個單獨的階段進行處理。另一種可能性(如果你只需要處理時看單個字符)是使用類似std::transform讀取數據,做加工,並且把輸出轉換成字符串:

struct character_processor { 
    char operator()(char input) { 
     // do some sort of processing on each character: 
     return ~input; 
    } 
}; 

std::transform(std::istream_iterator<char>(f), 
       std::istream_iterator<char>(), 
       std::back_inserter(result), 
       character_processor()); 
+0

請注意,在循環中,actualy需要分析每個字符,並將一些字符更改爲不同的字符,我也將添加行。 Maby我的思想堅持我的方法,但我不確定我是否會用你的建議方法實現我想要的。 – krishkule 2012-04-24 16:18:04

+0

@krishkule:參見已編輯的答案。 – 2012-04-24 16:35:41

0

我會檢查strlen(a)是不是大於7 ... 你可能會溢出filename並得到一個不存在的文件名。

不涉及這個問題,我會重新寫功能:

string ReadAndWrite(string a) { // string here, if you are into C++ already 
    string filename; // also here 
    filename = a; // simpler 
    string output; 
    char c; 
    ifstream f(filename.c_str()); // no need for ios::in (but needs a char *, not a string 
    output+= "Example text"; // <-- this writes and returns just fine! 
    f >> c; // instead c = f.get(); 

    while (f) // no need for f.good()) 
     { 

     output+= c; 
     f >> c; // again, instead c= f.get();   
     } 

    return output; 
} 
+0

即使我改變「文件名'具有所需文件名稱的靜態「001.txt」,它仍然不起作用:/ – krishkule 2012-04-24 15:55:43

+0

操作符>>與get()不同。默認情況下,運算符>>將在執行讀入變量之前刪除所有正在進行的空白。 – 2012-04-24 16:03:04

+0

這個'while(f)'和'while(f.good())'一樣糟糕。在正常情況下,你不會使用。 – 2012-04-24 16:09:47

-3

我可以建議使用的fopen? http://www.cplusplus.com/reference/clibrary/cstdio/fopen/它需要一個文件名並返回一個文件指針。有了這個,你可以使用fgets逐行讀取文件http://www.cplusplus.com/reference/clibrary/cstdio/fgets/

+2

請不要! :-) C++流是更方便,更安全,自動關閉等等......這是應該做的方式,而是需要知道如何使用它們 – 2012-04-24 15:48:08

+0

好嗎然後用FSEEK – 2012-04-24 15:53:01

+1

替換與fgets請刪除這個答案之前,我倒投票它。 – 2012-04-24 16:11:09

相關問題