2012-02-11 70 views
0

我一直在搜索互聯網一段時間,但是我可以在C++中找到的文件輸入是當你知道文件名。C++中的文件輸入

我正試圖編寫一個程序來執行一個文件,但不使用scanf或cin的2大於0的數字的添加。我想將文件加載到內存中,但是我可以找到的關於這種情況的所有代碼都需要知道文件名。該文件在單行上用2個整數格式化,由空格分隔,並且有多行整數。該程序將輸出這兩個數字的總和。我可以很容易地用scanf做到這一點,但如果我得到一個大文件,我想將它加載到內存中(稍後保存映射)。

將文件加載到內存中給我帶來麻煩,因爲我不知道文件名,也不知道如何查找,除非用戶輸入文件名(不會發生)。我要像這樣執行的程序,但使用C++ IO的最原始和基本形式:

./myprog < boatloadofnumbers 

我將如何開始我的計劃取整「boatloadofnumbers」爲一檔,這樣我就可以使用更多的基本功能,如read()? (也,所謂上述方法?通過輸入?)

int main(){ 
    int a,b; 
    while (scanf("%i,%i",&a,&b)>-1){ 
     printf("%i\n",(a+b)); 
    } //endwhile 
    return 0; 
} //endmain 
+1

'我可以找到的所有文件輸入在C++是當你知道文件名.'大聲笑。如果您試圖從文件中讀取數據,而您不知道文件名稱是什麼,那麼您完全是SOL。明顯。 – 2012-02-11 21:48:46

+2

您正在從標準輸入讀取數據,而不是從任何文件讀取數據。 shell正在爲你重定向。 – 2012-02-11 21:54:52

+0

@KerrekSB我明白了..是否有另一種閱讀數據的方式?我想我可以做一些文件操作,如果一個文件被給出,但我看到情況不再是這樣了。我一直在嘗試使用比scanf更基本的輸入方法,或者能夠以更大的比例讀取數據,而不是按數字編號。你認爲你可以指出我正確的方向嗎? – 2012-02-11 22:05:06

回答

0

這並不完全清楚如何當你不知道文件名時會讀取一個文件。大概你不知道文件名編譯時間。沒關係,你可以在運行時命令行得到這個,像這樣:

./myprog boatloadofnumbers 

那麼你的文件名是在argv[1],您可以使用std::ifstream訪問它。

如果你正在通過redirection(如./myprog < boatloadofnumbers)你不需要的文件名都,你可以只使用std::cin直接給出對stdin輸入。

以下main()將處理這兩種情況下:

int main(int argc, char* argv[]) 
{ 
    if (argc == 2) 
    { 
     std::cerr << "Reading from file" << argv[1] << std::endl; 
     std::ifstream ifs(argv[1]); 
     if (ifs) 
     { 
      sum_lines(ifs); 
     } 
     else 
     { 
      std::cerr << "Could not read from " << argv[1] << std::endl; 
     } 
    } 
    else 
    { 
     std::cerr << "Reading from stdin" << std::endl; 
     sum_lines(std::cin); 
    } 
} 

樣本sum_lines()可能看起來有點像這樣:

void sum_lines(std::istream& is) 
{ 
    int first = 0, second = 0; 
    std::string line = ""; 
    while (std::getline(is, line)) 
    { 
     std::istringstream iss(line); 
     if (is >> first >> second) 
     { 
      std::cout << first << " + " << second << " = " << first + second << std::endl; 
     } 
     else 
     { 
      std::cerr << "Could not parse [" << line << "]" << std::endl; 
     } 
    } 
} 

這並不從輸入來自那裏的醫療,所以你可以很容易地注入一個std::istringstream進行單元測試。此外,這不會將整個文件讀入內存,每次只讀一行,所以它應該處理averybigboatloadofnumbers

1

當作爲你的狀態在程序調用,那麼boatloadofnumbers的內容可以從STD閱讀:: CIN。

該方法被稱爲輸入重定向由shell而不是您的程序完成。

如果輸入重定向,shell通常會緩衝文件的內容。這是通過計算一次性傳輸文件的非常快速的方式。

+0

那麼,輸入如何加載到內存中?從我一直在做的事情來看,內容是按數字來讀取的,計算被執行,然後被輸出。我想閱讀比「按數字編號」更大的內容,因爲我以文件的形式給出內容。我怎麼做? – 2012-02-11 21:58:06

+0

那取決於:請顯示您的代碼,這需要回答的猜測。 – 2012-02-11 22:00:31

+0

原始帖子中顯示的代碼。 (所有整數都是> 0 ...可能應該提到那個) – 2012-02-11 22:09:41

0

使用shell重定向,您的程序可以從標準輸入讀取,這可能是可取的。但是,從文件讀取也是可取的。這很容易支持:

cat data > ./prog 
./prog < data 

./prog -f data 

前兩個是相似的,而文件data的內容都可以從程序的標準輸入;第三行只是傳遞一個命令行參數。下面是我們如何支持這一點:

#include <cstdio> 
#include <cstring> 

void process_input(std::FILE * fp) 
{ 
    char buf[4]; 
    std::fread(buf, 4, 1, fp); 
    // ... 
} 

int main(int argc, char * argv[]) 
{ 
    std::FILE * fp = stdin; // already open! 

    if (argc >= 3 && 0 == std::strcmp(argv[1]. "-f")) 
    { 
     fp = std::fopen(argv[2], "rb"); 

     if (!fp) 
     { 
      std::fprintf(stderr, "Could not open file %s.\n", argv[2]); 
      return 1; 
     } 
    } 

    process_input(fp); 

    if (fp != stdin) { std::fclose(fp); } 
} 

等價,就可以實現與輸入輸出流類似的東西,但它更迂迴了一下,有一個很好的,通用的參考:

#include <fstream> 

int main() 
{ 
    std::ifstream ifp; 

    if (/* as before */) 
    { 
     ifp.open(argv[2], std::ios::binary); 
     if (!ifp) { /* error and die */ } 
    } 

    std::ifstream & infile = ifp ? ifp : std::cin; 

    process_input(infile); 
}