簡體   English   中英

extract >>運算符在C ++中的確切運作方式

[英]How exactly does the extract>> operator works in C++

我是一名計算機科學專業的學生,​​因此對C ++語言沒有太多經驗(考慮到這是我使用這種語言的第一個學期)或編碼。

我被賦予了一個從文本文件中讀取整數的賦值,其形式為:

19 3 -2 9 14 4
5 -9 -10 3
.
.
.

這讓我更好地了解了I / O操作符,因為我需要使用此流做某些事情(呃)。

我到處尋找,無法找到關於extract >>運算符如何在內部工作的簡單解釋。 讓我澄清一下我的問題:

我知道提取器>>運算符會提取一個連續元素,直到它到達空格,制表符或換行符。 我試圖弄清楚的是,指針(?)或讀取位置(?)在提取元素之后會在哪里。 它會被刪除的元素的最后一個字符,還是被刪除,因此消失了? 它會出現在空格/制表符/'\\ n'字符本身嗎? 也許是下一個要素提取的開始?

我希望我很清楚。 我缺乏所有適當的術語來更清楚地描述我的問題。


這就是為什么我需要知道這個:(如果有人想知道......)其中一個要求是分別對每行中的所有整數求和。 我創建了一個循環來逐個提取所有整數,直到它到達文件的末尾。 但是,我很快就了解到extract >>運算符忽略了空格/制表符/換行符。 我想要嘗試的是提取>>一個元素,然后使用inputFile.get()來獲取空格/制表符/換行符。 然后,如果它是換行符,那就做我要做的事情。 這僅在流指針處於良好位置以便在最后一次提取>>之后提取空格/制表符/換行符時才有效。


在我之前的問題中 ,我嘗試使用getline()和sstring來解決它。


解:

為了回答我的具體問題 ,關於運算符>>如何工作,我不得不接受Ben Voigt作為最佳答案的答案。 我已經使用了這里建議的其他解決方案(每行使用一個sstring),它們確實有效! (你可以在我之前的問題鏈接中看到它)但是,我使用Ben的答案實現了另一個解決方案,它也有效:

        .
        .
        .

if(readFile.is_open()) {
        while (readFile >> newInput) {
                char isNewLine = readFile.get();    //get() the next char after extraction

                if(isNewLine == '\n')               //This is just a test!
                        cout << isNewLine;          //If it's a newline, feed a newline.
                else
                        cout << "X" << isNewLine;   //Else, show X & feed a space or tab

                lineSum += newInput;
                allSum += newInput;
                intCounter++;
                minInt = min(minInt, newInput);
                maxInt = max(maxInt, newInput);

                if(isNewLine == '\n') {
                        lineCounter++;
                        statFile << "The sum of line " << lineCounter
                        << " is: " << lineSum << endl;
                            lineSum = 0;
                }
        }
        .
        .
        .

不考慮我的數值,表格是正確的! 兩個空格和'\\ n'都被捕獲了: 測試

謝謝Ben Voigt :)

盡管如此,這種解決方案依賴於格式,非常脆弱。 如果任何行在'\\ n'之前還有其他內容(如空格或制表符),則代碼將錯過換行符。 因此,使用getline()和sstrings的另一種解決方案更加可靠。

提取后,流指針將被放置在導致提取終止的空白處(或其他非法字符,在這種情況下,還將設置failbit)。

這並不重要,因為你不負責跳過那個空格。 下一次提取將忽略空格,直到找到有效數據。

綜上所述:

  • 前導空格被忽略
  • 尾隨空格留在流中

還有noskipws修飾符,可用於更改默認行為。

operator>>將文件中的當前位置保留為提取的最后一個字符之外的一個字符(可能位於文件末尾)。 這不一定有助於你的問題; 一行中的最后一個值后面可以有空格或制表符。 您可以跳過向前閱讀每個字符並檢查它是否是'\\n'以外的空白區域,但更習慣的方法是讀取面向行的輸入是使用std::getline讀取該行,然后初始化std::istringstream從行中提取整數:

std::string line;
while ( std::getline( source, line ) ) {
    std::istringstream values( line );
    //  ...
}

這還可以確保在行中出現格式錯誤時,主輸入的錯誤狀態不受影響,您可以繼續下一行。

根據cppreference.com ,標准operator>>將工作委托給std::num_get::get 這需要一個輸入迭代器。 輸入迭代器的一個屬性是,您可以多次取消引用它而不會推進它。 因此,當檢測到非數字字符時,迭代器將指向該字符。

一般來說, istream的行為不是istream 有多個標志可以改變任何istream行為方式,你可以在這里閱讀。 一般來說,你不應該關心內部指針的位置; 這就是你首先使用流的原因。 否則,您只需將整個文件轉儲為字符串或等效文件,然后手動檢查它。

無論如何,回到你的問題,一種可能的方法是使用istream提供的getline方法來提取字符串。 從字符串,您可以手動讀取它,或將其轉換成stringstream ,並從那里提取令牌。

例:

std::ifstream ifs("myFile");
std::string str;

while ( std::getline(ifs, str) ) {
    std::stringstream ss( str );
    double sum = 0.0, value;
    while ( ss >> value ) sum += value;
    // Process sum
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM