我正在读取一个具有这种格式的文本文件:
grrr,一些文本,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循环中工作,或者当我的文本文件中有多个feilds时.
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中。
发布于 2009-01-26 08:44:57
使用instream>>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() );
}
}发布于 2009-01-26 04:40:04
你的代码读起来有点难。您可能会想一些关于封装的观点,并将其分解为函数。
此外,我将尽量避免使用单个字符进行读取,并使用各种函数和方法读取字段中的数据--您可以使用>>流提取器读取整个浮点数或整数。
最后,学习的一项有用技能是如何使用调试器。您可以在执行过程中逐步遍历代码并检查变量的值。
尽管如此,看起来你的问题就在这里:
if ( sBuffer[ x ] == ',' )
{
nStart = x;
break;
}
**** sLine = sBuffer[ x ];
inStream.clear();
inStream.str( sLine );
if ( inStream >> dValue2 )
cout << setprecision(1) << dValue2;在标记为“*”的行中,将一个字符准确地放入名为"sLine“的变量中。这样做之后,您将该字符转换为一个双精度变量dValue2,然后输出它。这显然是为什么这个字符被转换成你想要的数字的第一个数字。
发布于 2009-01-26 04:40:06
两点:
您可能希望使用sBuffer.find(',')
sLine对",“之前的最后一个字符使用https://stackoverflow.com/questions/478806
复制相似问题