如何通过读取文件将不同数据类型的数据推送到向量中
How to push data of different data types into a vector by reading from a file?
我想使用以下代码将以下数据推送到向量中。但我的代码仅适用于整数。如何对以下数据执行此操作?谢谢。
我的数据:
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-%dn",counter++);
srcdata.push_back(ivalue); //Pushing value by value into the vector with "," delimiter.
}
if(fp)
fclose(fp);
>%d
用于整数。将其更改为double
的%lf
,并相应地更改其他部分,例如,将ivalue
更改为double
。
根据您在问题中的评论,我认为您可能需要类似的东西
while(fscanf(fp,"%s", str)!=EOF){ char* pch = strtok(str, ","); pch = strtok(NULL, ",");先跳过 而 (pch != 空) { 双 d = atof(pch); printf("Counter-%d",counter++); srcdata.push_back(d); pch = strtok (NULL, ","); }}
既然你使用的是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 malformedn", line);
return 0;
}
}
else
{
if (feof(stream))
{
fprintf(stderr, "Reached end of filen");
}
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/O 与 C++ 混合是胃灼热的秘诀。
相关文章:
- 很好的语法来获取对向量/数组数据的大小引用?
- 在类 A 中创建类型为 B 类的向量 - 访问数据 [C++] [成员在两个类中都是私有的]
- C++:在多个线程中访问同一数组/向量的不同单元格是否会产生数据竞赛?
- 如何以"union-like"方式更改C++向量的数据类型
- 在线程函数中处理数据向量时进行线程竞速
- 大家好,当一个类有一个向量作为它的数据成员时,为什么它的大小总是24?
- 初始化可变数据结构中的共享指针向量
- 如何使用模板获取向量中的数据类型?
- 从自定义数据类型向量中删除重复元素
- C++:自定义数据类型向量错误的队列
- 如何将csv中的数据放入c++中的字符串向量中,而绝对没有任何作用
- 如何有效地实现将向量的数据分配给多个变量?
- 如何从多维向量中提取数据
- 将一种数据类型的向量复制到同一数据类型的结构向量中的有效方法是什么
- 向量中的数据何时释放
- 生成一个类Name_class并将两种数据类型存储在一个向量中
- 如何高效更改向量中所有对象的成员数据?
- 使用算法查找自定义数据向量中的最大值和最小值
- 从逗号分隔的文本文件中创建有意义的数据向量的最佳方法是什么?
- 为什么清除后我仍然可以访问数据向量