首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >StringStream循环失败

StringStream循环失败
EN

Stack Overflow用户
提问于 2009-01-26 03:48:07
回答 3查看 2.1K关注 0票数 4

我正在读取一个具有这种格式的文本文件:

grrr,一些文本,45.4321,54.22134

我只是把双值存储在一个字符串变量中。

为什么它只给了我第一个数字的字符串?

如果我只从一个while循环和一个新格式的文本文件开始:

21.34564

它应该起作用的。

问题是,sLine的值与我重新开始时的值相同。不同的是最有可能导致问题的三个嵌套for循环。

下面是我想要的代码:

代码语言:javascript
复制
#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循环中工作,或者当我的文本文件中有多个feilds时.

代码语言:javascript
复制
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循环。

我也试过了,但是我得到了小数点应该是'0‘的位置。而strtod很难,因为我需要我不把数据读取到const char *cPtr中。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-01-26 08:44:57

使用instream>>dvalue当然是正确的方法。但有时,正确的东西并不总是最简单的,也不一定是最好的。

我们可以这样做:

代码语言:javascript
复制
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);
}

或者像这样的东西,虽然效率不高,但可能更容易理解.

代码语言:javascript
复制
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));
}

假设:

代码语言:javascript
复制
#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()     );
  }
}
票数 1
EN

Stack Overflow用户

发布于 2009-01-26 04:40:04

你的代码读起来有点难。您可能会想一些关于封装的观点,并将其分解为函数。

此外,我将尽量避免使用单个字符进行读取,并使用各种函数和方法读取字段中的数据--您可以使用>>流提取器读取整个浮点数或整数。

最后,学习的一项有用技能是如何使用调试器。您可以在执行过程中逐步遍历代码并检查变量的值。

尽管如此,看起来你的问题就在这里:

代码语言:javascript
复制
          if ( sBuffer[ x ] == ',' )
          {
               nStart = x;
               break;
               }

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

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

在标记为“*”的行中,将一个字符准确地放入名为"sLine“的变量中。这样做之后,您将该字符转换为一个双精度变量dValue2,然后输出它。这显然是为什么这个字符被转换成你想要的数字的第一个数字。

票数 2
EN

Stack Overflow用户

发布于 2009-01-26 04:40:06

两点:

您可能希望使用sBuffer.find(',')

  • You set sLine对",“之前的最后一个字符使用
  • ,这是否有意这样做?这样只能正确地解析单个数字。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/478806

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档