2009-01-26 58 views
4

我讀的文本文件格式:字符串流回路發生故障

哎呀,一些文字,45.4321,54.22134

我只是我的雙看重的存儲在一個字符串變量。

爲什麼它只給了我字符串的第一個數字?

如果我重新開始只有一個while循環和這種新格式的文本文件:

21.34564

它的作品,因爲它應該。

事情是,sLine具有與我重新開始時的價值相同的價值。最有可能導致問題的三個嵌套for循環不同。

這裏是讓我的代碼是什麼我想:

#include <iostream> 
#include <fstream> 
#include <string> 
#include <vector> 
#include <iomanip> 
#include <cstdlib> 
#include <sstream> 

using namespace std; 

int main() 
{ 
    string usrFileStr, 
    fileStr = "test.txt", // declaring an obj string literal 
    sBuffer, 
    sLine, 
    str; 

    double dValue ; 

    int lineCount = 1; 
    int nStart; 
    istringstream issm; 

    fstream inFile;     // declaring a fstream obj 
    // cout is the name of the output stream 
    cout << "Enter a file: "; 
    cin >> usrFileStr; 

    inFile.open(usrFileStr.c_str(), ios::in); 
    // at this point the file is open and we may parse the contents of it 


    while (getline (inFile, sBuffer) && inFile.eof()) 
    { 
      cout << "Original String From File: " << sBuffer << endl; 

      cout << "Modified Str from File: " << fixed << setprecision(2) 
      << dValue << endl; 
    } 

    fgetc(stdin); 
    return 0; 
}  

所以有它的工作原理就像它應該。但我不能讓它的內部工作for循環,或當我在我的文本文件中的多個精密組件...

With this code, why is it taken off the decimal? 

#include <iostream> 
#include <fstream> 
#include <string> 
#include <vector> 
#include <iomanip> 
#include <cstdlib> 
#include <sstream> 
#include <errno.h> 

using namespace std; 

int main() 
{ 
    string usrFileStr, 
    myFileStr = "myFile.txt", // declaring an obj string literal 
    sBuffer, 
    sLine = ""; 


    istringstream inStream; 

    int lineCount = 1; 
    int nStart; 
    double dValue = 0, 
    dValue2 = 0; 
    float fvalue; 

    fstream inFile;     // declaring a fstream obj 
    // cout is the name of the output stream 
    cout << "Enter a file: "; 
    cin >> usrFileStr; 


    inFile.open(usrFileStr.c_str(), ios::in); 
    // at this point the file is open and we may parse the contents of it 

    if (!inFile) 
    { 
     cout << "Not Correct " << endl; 
    } 


    while (getline (inFile, sBuffer)) 
    { 
      nStart = -1 ; 

      for (int x = nStart + 1; x < sBuffer.length(); x++) 
      { 
       if (sBuffer[ x ] == ',') 
       { 
        nStart = x; 
        break; 
       } 

       cout << sBuffer[ x ]; 
      } 

      for (int x = nStart + 1; x < sBuffer.length(); x++) 
      { 

       if (sBuffer[ x ] == ',') 
       {  
        nStart = x; 
        break; 
       } 

       cout << sBuffer[ x ]; 
      } 


      for (int x = nStart + 1; x < sBuffer.length(); x++) 
      { 

       if (sBuffer[ x ] == ',') 
       { 
        nStart = x; 
        break; 
       } 

       sLine = sBuffer[ x ]; 
       inStream.clear(); 
       inStream.str(sLine); 

       if (inStream >> dValue) 
       cout << setprecision(1) << dValue; 

      } 


      for (int x = nStart + 1; x < sBuffer.length(); x++) 
      { 
       if (sBuffer[ x ] == ',') 
       { 
        nStart = x; 
        break; 
       } 

       sLine = sBuffer[ x ];  
       inStream.clear(); 
       inStream.str(sLine); 

       if (inStream >> dValue2) 
        cout << setprecision(1) << dValue2;  
      } 

      cout << ") \n"; 
      lineCount++; 
    } 


    cout << "There are a Total of: " << lineCount -1 << " line(s) in the file." 
    << endl; 

    inFile.clear();   // clear the file of any errors 
    inFile.close(); // at this point we are done with the file and may close it 

    fgetc(stdin); 
    return 0; 
} 

我沒有任何其他的字符在第一代碼迴路過去,因爲我只是閱讀一個不錯的小雙重價值。

在我的第二個代碼中,我有很多字符可以在我想要的之前到達。但不管怎樣,它仍然與其他角色隔絕,並且仍然處於可變狀態。即時通訊生病了解問題所在:/雖然我認爲它是for循環。

我也試過atof,但我得到'0'小數點應該是。 和strtod很難,因爲我需要即時通訊沒有讀取數據到一個常量字符* cPtr

回答

1

使用河道內>> dvalue肯定是正確的方式做事。但有時候,正確並不總是最簡單或最好的。

我們可以做這樣的事情:

int 
main() 
{ 
    string s = "grrr,some text,45.4321,54.22134"; 
    double a,b; 

    ASSERT_IS(2, sscanf(s.c_str(), "%*[^,],%*[^,],%lf,%lf", & a, & b)); 

    cout << setprecision(8); 
    SHOW(a); 
    SHOW(b); 
} 

或者,也許這樣的事情,雖然效率較低,可能會更容易理解......

int 
main() 
{ 
    string s = "grrr,some text,45.4321,54.22134"; 
    vector<string> v; 

    StringSplit(& v, s, ","); 

    cout << setprecision(8); 
    SHOW(v); 
    SHOW(atof( v[2].c_str())); 
    SHOW(strtod(v[3].c_str(), (char**)NULL)); 
} 

假設:

#define SHOW(X) cout << # X " = " << (X) f << endl 


    /* A quick & easy way to print out vectors... */ 
template<class TYPE> 
inline ostream & operator<< (ostream & theOstream, 
           const vector<TYPE> & theVector) 
{ 
    theOstream << "Vector [" << theVector.size() << "] {" 
      << (void*)(& theVector) << "}:" << endl; 

    for (size_t i = 0; i < theVector.size(); i ++) 
    theOstream << " [" << i << "]: \"" << theVector[i] << "\"" << endl; 

    return theOstream; 
} 


inline void 
StringSplit(vector<string> * theStringVector, /* Altered/returned value */ 
      const string & theString, 
      const string & theDelimiter) 
{ 
    UASSERT(theStringVector, !=, (vector<string> *) NULL); 
    UASSERT(theDelimiter.size(), >, 0); 

    size_t start = 0, end = 0; 

    while (end != string::npos) 
    { 
    end = theString.find(theDelimiter, start); 

     // If at end, use length=maxLength. Else use length=end-start. 
    theStringVector -> push_back(theString.substr(start, 
        (end == string::npos) ? string::npos : end - start)); 

     // If at end, use start=maxSize. Else use start=end+delimiter. 
    start = ( (end > (string::npos - theDelimiter.size())) 
       ? string::npos : end + theDelimiter.size() ); 
    } 
} 
2

你的代碼有點難讀。你可能想要考慮封裝並將其分解爲函數。

此外,我會盡量避免在讀取單個字符和使用各種功能和方法領域中讀取數據 - 你可以閱讀整個浮點或使用>>流提取整數。

最後,一個有用的技能是學習如何使用調試器。您可以逐步完成代碼,並隨時檢查變量的值。

這就是說,它看起來像你的問題是在這裏:

  if (sBuffer[ x ] == ',') 
      { 
       nStart = x; 
       break; 
       } 

      **** sLine = sBuffer[ x ];  
      inStream.clear(); 
      inStream.str(sLine); 

      if (inStream >> dValue2) 
      cout << setprecision(1) << dValue2; 

在標有行「****」,你把一個字符爲稱爲「SLINE的」變量。完成後,您將該一個字符轉換爲雙精度變量dValue2,然後輸出。這應該是顯而易見的,爲什麼這一個字符被轉換成你想要的數字的第一個數字。

0

兩點:

  • 你可能想sBuffer.find(',')
  • 您設置sLine之前的最後一個字符用「」是這樣打算如此?您只能以這種方式正確解析單個數字。