我想使用下面的代码将下面的数据推送到一个向量中。但是我的代码只适用于整数。如何对下面的数据执行此操作?谢谢。
我的数据:
M,0.455,0.365,0.095,0.514,0.2245,0.101,0.15,15
M,0.35,0.265,0.09,0.2255,0.0995,0.0485,0.07,7
F,0.53,0.42,0.135,0.677,0.2565,0.1415,0.21,9
M,0.44,0.365,0.125,0.516,0.2155,0.114,0.155,10
I,0.33,0.255,0.08,0.205,0.0895,0.0395,0.055,7
I,0.425,0.3,0.095,0.3515,0.141,0.0775,0.12,8
F,0.53,0.415,0.15,0.7775,0.237,0.1415,0.33,20
F,0.545,0.425,0.125,0.768,0.294,0.1495,0.26,16
M,0.475,0.37,0.125,0.5095,0.2165,0.1125,0.165,9
F,0.55,0.44,0.15,0.8945,0.3145,0.151,0.32,19
我的代码:
fp = fopen(argv[1], "r"); //Opening the input file in read mode.
if(!fp)
{
printf("open data source file failed!\n");
goto MAINEXIT;
}
int ivalue;
//extract data from files
while(fscanf(fp,"%d,",&ivalue)!=EOF)
{
printf("Counter-%d\n",counter++);
srcdata.push_back(ivalue); //Pushing value by value into the vector with "," delimiter.
}
if(fp)
fclose(fp);
答案 0 :(得分:2)
%d
用于整数。将其更改为%lf
double
,并相应更改其他部分,例如,将ivalue
更改为double
。
根据你在问题中的评论,我认为你可能需要像
这样的东西while(fscanf(fp,"%s", str)!=EOF) { char* pch = strtok(str, ","); pch = strtok(NULL, ","); // skip first while (pch != NULL) { double d = atof(pch); printf("Counter-%d\n",counter++); srcdata.push_back(d); pch = strtok (NULL, ","); } }
答案 1 :(得分:0)
由于您使用的是C ++ STL容器(vector
),因此您应该使用C ++ I / O(iostream
)而不是C I / O(stdio
)。它更安全,更灵活,最终可以为您节省一些胃灼热。
这是一个快速的脏样本,展示了如何将数据读入矢量:
#include <iostream>
#include <iomanip>
#include <vector>
#include <iterator>
#include <sstream>
#include <string>
/**
* Create a struct type to represent each record,
* with one char member (which I'm calling "gender"
* based on the 'M' and 'F', but that's just a guess),
* 7 doubles (which I've gathered into a fixed-size
* array), and one integer.
*
* I've also overloaded the stream << and >> operators
* to read and write the struct as a single entity.
*/
struct record {
char gender;
double dvar[7];
int ivar;
record() { }
virtual ~record() { }
std::ostream& operator<<(std::ostream& s)
{
s << gender << " ";
for (int i = 0; i < 7; i++)
s << std::fixed << std::setw(8) << std::setprecision(4) << dvar[i] << " ";
s << std::setw(3) << ivar;
return s;
}
std::istream& operator>>(std::istream& s)
{
char delim;
s >> gender >> delim;
for (int i = 0; i < 7; i++)
s >> dvar[i] >> delim;
s >> ivar;
return s;
}
};
/**
* Overload the << and >> operators outside of the struct
* definition; this is necessary for the istream and ostream
* iterators to function properly. Each operator simply
* calls the overloaded operator in the struct definition
*/
std::ostream& operator<<(std::ostream& s, const record& r)
{
const_cast<record&>(r).operator<<(s);
return s;
}
std::istream& operator>>(std::istream& s, record& r)
{
r.operator>>(s);
return s;
}
/**
* For the purpose of this example I'm reading from a string
* stream local to main; however, you can swap out the string
* stream with a C++ file stream (ifstream) and use it in the
* copy method *exactly* as you use the string stream:
*
* std::ifstream infile(filename);
* ...
* std::copy(std::istream_iterator<record>(infile),
* std::istream_iterator<record>(),
* std::back_inserter(myRec));
*/
int main(void)
{
std::vector<record> myRec;
/**
* We're using a local string and string stream for the purpose of
* this example, but the handling of a string stream and a file
* stream would be exactly the same.
*/
std::string data = "M,0.455,0.365,0.095,0.514,0.2245,0.101,0.15,15"
"M,0.35,0.265,0.09,0.2255,0.0995,0.0485,0.07,7"
"F,0.53,0.42,0.135,0.677,0.2565,0.1415,0.21,9"
"M,0.44,0.365,0.125,0.516,0.2155,0.114,0.155,10"
"I,0.33,0.255,0.08,0.205,0.0895,0.0395,0.055,7"
"I,0.425,0.3,0.095,0.3515,0.141,0.0775,0.12,8"
"F,0.53,0.415,0.15,0.7775,0.237,0.1415,0.33,20"
"F,0.545,0.425,0.125,0.768,0.294,0.1495,0.26,16"
"M,0.475,0.37,0.125,0.5095,0.2165,0.1125,0.165,9"
"F,0.55,0.44,0.15,0.8945,0.3145,0.151,0.32,19";
std::stringstream dataStream;
/**
* Write the contents of the string to the string stream
*/
dataStream << data;
/**
* Read the contents of the string stream into the vector
*/
std::copy(std::istream_iterator<record>(dataStream),
std::istream_iterator<record>(),
std::back_inserter(myRec));
std::cout << "Read " << myRec.size() << " records" << std::endl;
/**
* Write the contents of the vector to standard output.
*/
std::copy(myRec.begin(),
myRec.end(),
std::ostream_iterator<record>(std::cout, "\n"));
return 0;
}
这非常简单;没有任何错误处理或处理格式错误的输入的方法。但是,我认为它很好地说明了C ++ I / O例程的强大功能。
但是,如果您坚持使用C I / O,则可以执行以下操作:
struct record {
char gender;
double dvar[7];
int ivar;
};
int getRecord(FILE *stream, struct record *r)
{
char line[80]; // assuming each line is less than 80 characters long
if (fgets(line, sizeof line, stream))
{
int count = sscanf(line, "%c,%f,%f,%f,%f,%f,%f,%f,%d",
&r->gender,
&r->dvar[0],
&r->dvar[1],
&r->dvar[2],
&r->dvar[3],
&r->dvar[4],
&r->dvar[5],
&r->dvar[6],
&r->ivar);
if (count < 8)
{
fprintf(stderr, "Input line \"%s\" is malformed\n", line);
return 0;
}
}
else
{
if (feof(stream))
{
fprintf(stderr, "Reached end of file\n");
}
else
{
perror("Error on read");
}
return 0;
}
return 1;
}
int main(void)
{
std::vector<record> myRec;
FILE *input = fopen("myfile.dat", "r");
record r;
while(getRecord(input, &r))
myRec.push_back(r);
...
}
我强烈建议使用C ++ I / O例程;将C I / O与C ++混合是胃灼热的一种方法。