Reading a text file using VC++ - visual-studio-2010

I need to read a text file which is for example like bottom :
8.563E+002 2.051E+004 4.180E-004 7.596E-001 5.260E-005 6.898E-002 1.710E-001 8.053E-011 2.686E-013 8.650E-012
each of this 10 scientific digits are the specific value of one line it means each line contains 10 value like above, There is one such line for every grid point in each file. The X indices value most rapidly, then Y, then Z; the first line in the file refers to element (0,0,0); it means the first 10 values presents the first line which refers to element (0,0,0) and the second line (second 10 values) to second element (1,0,0); the last to element (599,247,247).
I don't know how can I write the code for this file using visual C++ ,what I know is I have to read this file line by line which can be determined by eliminating 10 values and tokenize it , then I have to create the x y z for each line il end of the line. I know the concept but I don't know How can I code it in visual C++ .. I need to submit it as my homework .. I really welcome every help .. Thanks

core part can look like:
std::ifstream is("test.txt");
std::vector<double> numbers;
for(;;) {
double number;
is >> number;
if (!is)
break;
numbers.push_back(number);
}

I do not have here MSVC but GCC 4.3. I hope this code helps:
#include <iostream>
#include <fstream>
#include <list>
#include <string>
#include <iterator>
using namespace std;
class customdata
{
friend istream& operator>>(istream& in, customdata& o);
friend ostream& operator<<(ostream& out, const customdata& i);
public:
customdata()
: x(0), y(0), z(0)
{}
customdata(const customdata& o)
: x(o.x), y(o.y), z(o.z)
{}
customdata& operator=(const customdata& o)
{
if (this != &o)
{
x = o.x;
y = o.y;
z = o.z;
}
return *this;
}
private:
long double x, y, z;
};
istream& operator>>(istream& in, customdata& o)
{
in >> o.x >> o.y >> o.z;
return in;
}
ostream& operator<<(ostream& out, const customdata& i)
{
out << "x=" << i.x << " y=" << i.y << " z=" << i.z;
return out;
}
// Usage: yourexec <infile>
int main(int argc, char** argv)
{
int exitcode=0;
if(argc > 1)
{
ifstream from(argv[1]);
if (!from)
{
cerr << "cannot open input file " << argv[1] << endl;
exitcode=1;
}
else
{
list<customdata> mydata;
copy(istream_iterator<customdata>(from), istream_iterator<customdata>(), back_inserter(mydata));
if(mydata.empty())
{
cerr << "corrupt input data" << endl;
exitcode=3;
}
else
copy(mydata.begin(), mydata.end(), ostream_iterator<customdata>(cout, "\n"));
}
}
else
{
cerr << "insufficient calling parameters" << endl;
exitcode=2;
}
return exitcode;
}

Related

The problem is i need the input of the string to accept a blank line

The program is supposed to receive a string, that can have blank lines, blank spaces, and break lines. So the problem is i can't use get line, because i don't know how many break lines the user will use.
I tried making a do while but it didn't work, the program stops working.
It was a do while, that would receive an char and using pushback insert in the string while the char was different to EOF. I don't know how else to do it, or why this do while doesn't work.
This code is using get line witch doesn't accept a break line.
'''''
#ifndef INDICE_H
#define INDICE_H
#include <cstddef>
struct Indice{
std::size_t f;
double p;
};
#endif
#include <iostream>
#include <sstream>
#include <string>
#include <iomanip>
#include <map>
#include "Indice.hpp"
int main()
{
std::string str;
std::getline(std::cin, str);
// Count the number of occurrences for each word
std::string word;
std::istringstream iss(str);
std::map<std::string,Indice> occurrences;
while (iss >> word) ++occurrences[word].f;
//Calculate the percentual each word
int total = 0.0;
for (std::map<std::string,Indice>::iterator it = occurrences.begin();
it != occurrences.end(); ++it)
{
total += it->second.f;
}
for (std::map<std::string,Indice>::iterator it = occurrences.begin();
it != occurrences.end(); ++it)
{
it->second.p = (static_cast<double>(it->second.f))/total;
}
// Print the results
for (std::map<std::string,Indice>::iterator it = occurrences.begin();
it != occurrences.end(); ++it)
{
if(it->first.size()>2)
std::cout << it->first << " " << it->second.f << " "<< std::fixed << std::setprecision(2) << it->second.p << std::endl;
}
return 0;
}
''''
Two possible solutions:
#include <iostream>
#include <string>
int main(){
std::string line;
while(std::cin >> line){
//Variable line contains your input.
}
//Rest of your code
return 0;
}
Or:
#include <iostream>
#include <string>
int main(){
std::string line;
while(std::getline(std::cin, line)){
if (line.empty()){
break;
}
//Variable line contains your input.
}
//Rest of your code
return 0;
}

Line-based parser with empty lines and attributes, how to ignore attribute

I'm using boost spirit to parse a line-based format, where empty lines are allowed. For this, i'm using something similar to the following grammar:
struct parser_type : public qi::grammar<std::string::iterator, qi::ascii::blank_type, std::vector<int>()>
{
typedef std::string::iterator Iterator;
parser_type() : parser_type::base_type(main)
{
element = qi::int_;
line %= element | qi::eps;
main %= +(line >> qi::eol);
}
qi::rule<Iterator, int()> element;
qi::rule<Iterator, qi::ascii::blank_type, int()> line;
qi::rule<Iterator, qi::ascii::blank_type, std::vector<int>()> main;
} parser;
This works fine, since the qi::eps together with the qi::eol matches empty lines. Nice (though i am open to other, perhaps better approaches to parse line-based formats with empty lines). However, the attribute of the line parser is an int, which is obviously not present on empty lines. Therefore, for an input of
1
4
the parser creates a vector with the content { 1, 0, 0, 4 }.
I want the line totally ignored, that is, i don't want any dummy object to be constructed to match the attribute of the line. Can this be done? Is there a better way to parse lines?
Here is a complete minimum example (the program needs a input file called "input", you can use my example above):
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
struct parser_type : public qi::grammar<std::string::iterator, qi::ascii::blank_type, std::vector<int>()>
{
typedef std::string::iterator Iterator;
parser_type() : parser_type::base_type(main)
{
element = qi::int_;
line = element | qi::eps;
main %= +(line >> qi::eol);
}
qi::rule<Iterator, int()> element;
qi::rule<Iterator, qi::ascii::blank_type, int()> line;
qi::rule<Iterator, qi::ascii::blank_type, std::vector<int>()> main;
} parser;
int main()
{
std::ifstream file("input");
std::stringstream buffer;
buffer << file.rdbuf();
std::string str = buffer.str();
auto iter = str.begin();
std::vector<int> lines;
bool r = qi::phrase_parse(iter, str.end(), parser, qi::ascii::blank, lines);
if (r && iter == str.end())
{
std::cout << "parse succeeded\n";
for(auto e : lines)
{
std::cout << e << '\n';
}
}
else
{
std::cout << "parse failed. Remaining unparsed: " << std::string(iter, str.end()) << '\n';
}
}
This rule:
line = element | eps;
causes you to loose the information you need. By accepting no-match (eps), you force it to just return the value-initialized attribute you declared (int in the rul signature).
So, drop that, and then I usually write this kind of a repeat using the list-operator (%):
line = element;
main = -line % qi::eol;
This works:
Live On Coliru
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
struct parser_type : public qi::grammar<std::string::iterator, qi::ascii::blank_type, std::vector<int>()>
{
typedef std::string::iterator Iterator;
parser_type() : parser_type::base_type(main)
{
element = qi::int_;
line = element;
main = -line % qi::eol;
}
qi::rule<Iterator, int()> element;
qi::rule<Iterator, qi::ascii::blank_type, int()> line;
qi::rule<Iterator, qi::ascii::blank_type, std::vector<int>()> main;
} parser;
int main()
{
std::ifstream file("input");
std::stringstream buffer;
buffer << file.rdbuf();
std::string str = buffer.str();
auto iter = str.begin();
std::vector<int> lines;
bool r = qi::phrase_parse(iter, str.end(), parser, qi::ascii::blank, lines);
if (r && iter == str.end())
{
std::cout << "parse succeeded\n";
for(auto e : lines)
{
std::cout << e << '\n';
}
}
else
{
std::cout << "parse failed. Remaining unparsed: " << std::string(iter, str.end()) << '\n';
}
}
Prints
parse succeeded
1
4

Odd numbers recursively? code currently finds even nums

Just wondering if there is a line change I can make in order to find odds instead of evens? Here's what I got:
#include <iostream>
#include <conio.h>
#include "stdafx.h"
void numOdd(int x, int y)
{
std::cout << x << " ";
if (x < y)
{
numOdd(x + 2, y);
}
}
int main()
{
int x = 0;
int y = 0;
std::cout << "Up to what num to find odd nums? " << std::endl;
std::cin >> y;
numOdd(x, y);
_getch();
}
Initialize x to 1 instead of 0.
Aso, be advised that recursion is not a great fit for this problem; a simple loop would be more appropriate.

Boost Mem_fn and accessing member function of derived class

I made a simple example to test boost bind's interaction with derived classes.
I created two subclasses with different getarea functions. I expected
g1 = boost::bind(boost::mem_fn(&Shape::getarea), Rec)
to print the area of Rectangle(10,20) but instead it printed '1'. I get the same when I instead write Rectangle::getarea. It prints the same even when I input other functions eg. member of Rectangle
double sum(double h,double w){return h+w; }
and use
g1 = boost::bind(boost::mem_fn(&Rectangle::sum), Rec,2,3)
Question 1: Why does it return '1'?Is that a default response for error?
My second problem is to do the same of printing g2 but now Rec is replaced by **iter, i.e. an object of some derived class type from a list of objects. Since getarea is a virtual fcn, once I get the above working it should be fine to just write:
g2= boost::bind(boost::mem_fn(& Shape::getarea , &(**iter));
Question 2: However, I was wondering if there is a way to return the classtype of **iter eg. classof(**iter) and then put it in g2 i.e.
g2= boost::bind(boost::mem_fn(& classof(**iter)::getarea , &(**iter));
When I ran g2 by writing Shape::getarea, I got '1' again for all iter.
#include <memory>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <boost/bind.hpp>
using namespace std;
class Shape {
public:
Shape(double h, double w) :height(h), width(w) {};
virtual double getarea() = 0;
double height;
double width; };
class Rectangle: public Shape {
public:
Rectangle(double h, double w): Shape(h,w) {};
double getarea() override { return height*width; } };
class Triangle : public Shape {
public:
Triangle(double h, double w) :Shape(h,w) {};
double getarea() { return height*width*0.5; }};
int main() {
//create objects
Rectangle Rec(10, 20);
Triangle Tri(2, 3);
//create boost bind function
boost::function<double(double, double)> g1;
g1 = boost::bind(boost::mem_fn(&Shape::getarea), Rec);
//print area and g
cout << Rec.getarea()<<" should be equal to " << g1<< '\n';
//create list
vector<shared_ptr<Shape>> Plist;
Plist.push_back(make_shared<Rectangle>(Rec));
Plist.push_back(make_shared<Triangle>(Tri));
//print each element from the vector list
for (auto iter = Plist.begin(); iter != Plist.end(); iter ++ ) {
boost::function<double(double, double)> g2;
g2= boost::bind(boost::mem_fn(& .... , &(**iter));
//where in dots we need Classtype_of_**iter::getarea
cout << (**iter).getarea()<<"should be equal to " << g2<< '\n';
}
}
You... forget to invoke the functions...
for (auto iter = Plist.begin(); iter != Plist.end(); iter++) {
boost::function<double()> g2;
g2 = boost::bind(&Shape::getarea, iter->get());
cout << (*iter)->getarea() << " should be equal to " << g2() << '\n';
}
What you saw what the implicit conversion to bool (http://www.boost.org/doc/libs/1_60_0/doc/html/boost/function.html#idm45507164686720-bb)
Note also I fixed the signature of g1 and g2: Live On Coliru.
Some further improvements (remove the need for the g2 in the loop?):
auto getarea = boost::mem_fn(&Shape::getarea);
for (auto iter = Plist.begin(); iter != Plist.end(); iter++) {
cout << (*iter)->getarea() << " should be equal to " << getarea(**iter) << '\n';
}
Or, indeed in c++11:
for (auto& s : Plist)
cout << s->getarea() << " should be equal to " << getarea(*s) << '\n';
By this time, you'd wonder why you have this accessor when you can just use the member.

C++ why does getline() only work on the first instance of my function?

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <cstdlib>
//These two functions work fine
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
if(!item.empty())
elems.push_back(item);
}
return elems;
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
//I think this function is where the problem is
std::string& singleSplit(const std::string* s, char delim='\0'){
static std::string input=*s;
static std::stringstream ss(*s);
if(input!=*s){ss.str(*s);input=*s;}
std::string item;
if (std::getline(ss, item, delim)&&!item.empty())
{std::cout<<item<<std::endl;return item;}
}
void setIntFrames(std::vector<std::string>& frames, std::vector<uint16_t>* Start, std::vector<uint16_t>* End)
{
for(int i=0; i<frames.size(); i++)
{
Start->push_back(std::atoi((singleSplit(&frames[i],'-').c_str())));
End->push_back(std::atoi((singleSplit(&frames[i],'\0').c_str())));
}//this loop works fine the first time it passes, but the second time it just pushes back 0's into my Start and End vectors
}
int main()
{
std::string x="0000-1200,1201-2359";//sample string of what alloted time frames in a day would look like
std::vector<std::string>timeFrames(split(x,','));
std::vector<uint16_t>startTimes; std::vector<uint16_t>endTimes;
setIntFrames(timeFrames, &startTimes, &endTimes);
std::cout<<startTimes[1]<<std::endl<<endTimes[1];
//setIntFrames() didn't set these correctly, I don't know why
return 0;
}
I'm trying to make a simple scheduling program. I'm dealing with converting string x inside of main() into to arrays(vectors in this case) of start and end times. The way I'm trying to do it is first to split the original string into multiple strings(delimited by ',') then placed into the vector timeFrames. The next step would be to split those smaller strings, turn them to ints, and place them into either the startTimes vector or endTimes vector. I use setIntFrames for this step but I don't understand why it only works to set the first timeFrame.
I'm pretty sure the problems lies in my singleSplit() function, but I don't understand getline and stringstream enough to fix this. Any help is appreciated.
This works for me. I changed pass arguments in as references and then pushing them back after use.
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <cstdlib>
//These two functions work fine
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
if(!item.empty())
elems.push_back(item);
}
return elems;
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
//I think this function is where the problem is
void singleSplit(const std::string& s, char delim, std::string& first, std::string& second){
std::stringstream ss(s);
if (std::getline(ss, first, delim)){
std::cout << "Found:" << first << '\n';
}
if (std::getline(ss, second)){
std::cout << "Found:" << second << '\n';
}
}
void setIntFrames(std::vector<std::string>& frames, std::vector<uint16_t>& Start, std::vector<uint16_t>& End)
{
std::string first, second;
for(int i=0; i<frames.size(); i++)
{
std::cout << frames[i] << '\n';
singleSplit(frames[i], '-', first, second);
Start.push_back(std::atoi(first.c_str()));
End.push_back(std::atoi(second.c_str()));
}//this loop works fine the first time it passes, but the second time it just pushes back 0's into my Start and End vectors
}
int main()
{
std::string x="0000-1200,1201-2359";//sample string of what alloted time frames in a day would look like
std::vector<std::string>timeFrames(split(x,','));
std::vector<uint16_t>startTimes; std::vector<uint16_t>endTimes;
setIntFrames(timeFrames, startTimes, endTimes);
// std::cout<<startTimes[1]<<std::endl<<endTimes[1];
for (int i = 0; i < startTimes.size(); ++i){
std::cout << i << ':' << startTimes[i] << '\t' << endTimes[i] << '\n';
}
//setIntFrames() didn't set these correctly, I don't know why
return 0;
}
The output looks like this:
$ a.out
0000-1200
Found:0000
Found:1200
1201-2359
Found:1201
Found:2359
0:0 1200
1:1201 2359

Resources