Thread: Txt file and data storage

  1. #16
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I just don't understand how do you suggest me to store complete paths in the class you suggested.
    Each Path object represents one complete path (just as each std::vector<Point> represents one complete path). The difference here is that you will provide an interface from which one can create and access this complete path. The actual implementation (i.e., whether you store the Point objects in a vector or a linked list) can vary since it is private.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  2. #17
    Registered User
    Join Date
    Jun 2008
    Posts
    33
    I figured out that one object represents on complete path, but i don't understand how should i implement collection of object (full collection of complete paths) since i don't know the number of complete paths. How should i store points of one path in list of points? I know that i'm bugging you, but this is just one part of my project which i must do in c++, the rest of project is done in specialised language for robotics (and as you can see i'm not to familiar with c++ unfortunately). Do you know what could be the problem with printing that i mentioned in the post before?

  3. #18
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    but i don't understand how should i implement collection of object (full collection of complete paths) since i don't know the number of complete paths.
    That would still be a vector<Path>, or you could create a full blown PathCollection class instead of a typedef (but in this case a vector<Path> will probably suffice).

    How should i store points of one path in list of points?
    In a sequential container such as a vector or linked list, since a path is a sequence of points.

    Do you know what could be the problem with printing that i mentioned in the post before?
    It looks correct to me, so you may need to post a little more code.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #19
    Registered User
    Join Date
    Jun 2008
    Posts
    33
    The code is almost the same as the one before:
    Code:
    #include <iostream>
    #include <cstdlib>
    #include <fstream>
    #include <vector>
    using namespace std;
    
    class Koord {		//varijabla vrijednosti koordinatnih tocaka x i y
    
    	public:
    		int x,y;
    	};
    	typedef vector<Koord>Tocke;		//skup tocaka jednog puta
    	typedef vector<Tocke>Putovi;		//svi putovi mape
    
    int main(int argc, char* argv[])
    {
    	Putovi trajektorije;
    	Tocke t;
    	int i,j;
    	
    	if (argc == 2) {		//ako je pri pozivu naveden samo jedan parametar stvara se ulazni tok dat i pridruzuje datoteci zadanoj kao parametar
    	
    	ifstream dat (argv[1]);
    	if (!dat) {
    		cerr << "Nije moguce otvoriti zadanu datoteku"<<argv[1]<<endl;
    	}
    	
    	while (!dat.eof()) {
    		int br, p=0;
    		dat >> br;
    		
    		if (br == '\n') {
    		trajektorije.push_back(t);
    		p++;
    	}		
    		
    		else if ((p%2) == 0) {	
    		t[p].x=br;
    		p++;
    	}
    		
    		else {
    		t[p].y=br;
    		p++;
    	}
    	}
    	
    	for(i=0; i < trajektorije.size(); i++) 
    		for (j=0; j < t.size(); j++)
    	cout << "Put #" << j+1 << " se sastoji od slijedecih tocaka:" << '\t' << trajektorije[i][j] << endl;
    
    }		
    		
    	return 0;
    }

  5. #20
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Oh, of course. trajektorije[i][j] is a Point object, and you have not overloaded operator<< for ostream for Point objects.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #21
    Registered User
    Join Date
    Jun 2008
    Posts
    33
    Ok you lost me completely there. I don't know anything about operator overloading. How can i do that? (this c++ is complicated as hell). I've started something on the class approach so i will post my code for class and constructor. I used constructor for file opening (as you can see). Can i do that and is this ok so far? And as you can see i declared public function unos_tocaka. With it i would like to read numbers and store collection of paths in class. Is this possible and if it is how? I've done something for storing points for one path (if that is even correct) but i don't know how to go on. I'm a real pain in the ass ain't i??

    Code:
    #include <iostream>
    #include <cstdlib>
    #include <fstream>
    #include <vector>
    using namespace std;
    
    struct Koord {
    	
    	int x;
    	int y;
    }
    
    class Putovi {
    	
    	public:
    	int i;
    	Putovi (int argc, char* argv[]);
    	void unos_tocaka();
    	
    	private:
    	vector<Koord>put;
    	
    };
    	
    Putovi::Putovi(int argc, char* argv[]) {
    		
    		if (argc == 2) {
    			ifstream dat(argv[1]);
    			if (!dat) {
    				cerr << "Zadanu datoteku nije moguce otvorit" << argv[1] << endl;
    				exit (1);
    			}
    		}
    		else if (argc < 2) {
    			cout << "Greska pri pozivanju programa" <<endl;
    			cout << "Koristenje: eg_decomposition <ime_datoteke>" <<endl;
    		}
    		else {
    			cerr << "Zadano je previse parametara u pozivu programa" << endl;
    			exit (1);
    		}
    	}
    
    void Putovi::unos_tocaka() {
    	
    	while (!dat.eof()) {
    		int br, p=0;
    		dat >> br;
    		
    		if (br == '\n') 
    	    break;
    		
    		else if ((p&#37;2) == 0) {	
    		put[p].x=br;
    		p++;
    	}
    		
    		else {
    		put[p].y=br;
    		p++;
    	}
    		
    	}
    
    
    int main(int argc, char* argv[])
    {
    	return 0;
    }
    Last edited by radnik; 06-16-2008 at 03:38 PM.

  7. #22
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I don't know anything about operator overloading. How can i do that?
    If you have not learnt how to do operator overloading, then at this point just write:
    Code:
    cout << trajektorije[i][j].x << ' ' << trajektorije[i][j].y << endl;
    However, overloading the operator is easy:
    Code:
    std::ostream& operator<<(std::ostream& out, const Point& point)
    {
        return out << point.x << ' ' << point.y;
    }
    Basically, operator<< is just a function with an unusual name and some other limitations.

    I used constructor for file opening (as you can see). Can i do that and is this ok so far?
    Yes, you can do that, but of course you should test if it works. However, although you can do that, it may be better to open the file in main() (or some other function), and then either pass the data read to the constructor, or pass the std::istream reference to the constructor. Passing the command line arguments to the constructor of an object that should have no knowledge of whether the command line or a graphical user interface is used certainly is not very good practice.

    And as you can see i declared public function unos_tocaka. With it i would like to read numbers and store collection of paths in class. Is this possible and if it is how?
    Of course it is possible. You can overload operator>> to read into a Point. Then you can overload operator>> to read Point objects into a Path. Then you can write the code to read Path objects from a file into a vector<Path> or PathCollection. To start with, use what you know of reading integers provided by a user at the command line (i.e., cin >> num).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #23
    Registered User
    Join Date
    Jun 2008
    Posts
    33
    WHre in the code should i put the operator overloading main() or...? Because i got this error on compiling:
    eg_decomposition.cpp:34: error: 'std:stream& Koord:perator<<(std:stream&, Koord)' must take exactly one argument

    Code:
    eg_decomposition.cpp:34: error: 'std::ostream& Koord::operator<<(std::ostream&, Koord)' must take exactly one argument
    How can i pass the std::istream reference to the constructor as an argument?

  9. #24
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by radnik View Post
    WHre in the code should i put the operator overloading main() or...? Because i got this error on compiling:
    eg_decomposition.cpp:34: error: 'std:stream& Koord:perator<<(std:stream&, Koord)' must take exactly one argument

    Code:
    eg_decomposition.cpp:34: error: 'std::ostream& Koord::operator<<(std::ostream&, Koord)' must take exactly one argument
    How can i pass the std::istream reference to the constructor as an argument?
    If you make the stream << or >> operator a member function (rather than a friend function), all you pass is the stream - the extra argument is the "Koord" one, since that should be implied with the member function. It is generally considered better to make it a friend function, and make it take a const reference.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #25
    Registered User
    Join Date
    Jun 2008
    Posts
    33
    Thanks matsp. In the first solution i didn't use the class approach but typedefs. The compiling went well but when i run the program with correct file path to open i get a segmentation fault. Can you please check whats the problem. I first need one working solution to continue my project and i will then try to finish the class approach. Anyway here is my code:
    Code:
    #include <iostream>
    #include <cstdlib>
    #include <fstream>
    #include <vector>
    using namespace std;
    
    class Koord {		//varijabla vrijednosti koordinatnih tocaka x i y
    
    	public:
    		int x;
    		int y;
    		
    	};
    	typedef vector<Koord>Tocke;		//skup tocaka jednog puta
    	typedef vector<Tocke>Putovi;		//svi putovi mape
    
    int main(int argc, char* argv[])
    {
    	
    	Putovi trajektorije;
    	Tocke t;
    	int i,j;
    	
    	if (argc == 2) {		//ako je pri pozivu naveden samo jedan parametar stvara se ulazni tok dat i pridruzuje datoteci zadanoj kao parametar
    	
    	ifstream dat (argv[1]);
    	if (!dat) {
    		cerr << "Nije moguce otvoriti zadanu datoteku "<< argv[1]<<endl;
    	}
    	
    	while (!dat.eof()) {
    		int br, p=0;
    		dat >> br;
    		
    		if (br == '\n') {
    		trajektorije.push_back(t);
    		p++;
    	}		
    		
    		else if ((p%2) == 0) {	
    		t[p].x=br;
    		p++;
    	}
    		
    		else {
    		t[p].y=br;
    		p++;
    	}
    	}
    	
    	for(i=0; i < trajektorije.size(); i++) 
    		for (j=0; j < t.size(); j++)
    	cout << "Put #" << j+1 << " se sastoji od slijedecih tocaka:" << '\t' << trajektorije[i][j].x <<' '<<trajektorije[i][j].y << endl;
    
    }	
    else if (argc < 2) {
    			cout << "Greska pri pozivanju programa" <<endl;
    			cout << "Koristenje: eg_decomposition <ime_datoteke>" <<endl;
    		}
    		else {
    			cerr << "Zadano je previse parametara u pozivu programa" << endl;
    			exit (1);
    		}	
    		
    	return 0;
    }

  11. #26
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Can you post the input file. I'm suspecting that you are trying to access the vector before you have given it any size (before you do "put_back()").

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #27
    Registered User
    Join Date
    Jun 2008
    Posts
    33
    Here's the file. This is just one example. The file can have unknown number of lines (paths) and unknown number of point per path (where first number is x, second y, third x and so on):
    Code:
    12 14 15 17 987 234 23 45
    1 2 65 34 56 34 12 78 23 987

  13. #28
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    As I suspected, the problem is that you are accessing the t[p] before it has been assigned to anything. You will either have to collect a coordinate pair and add that to the vector when it's complete, or give the vector a size before you access elements in the vector.

    Also this:
    Code:
    		if (br == '\n') {
    		trajektorije.push_back(t);
    		p++;
    	}
    is completely broken - br == '\n' will be true when you see the value 10 in the input stream, not when you hit a newline, since br is an integer, and not a char, the input filtering will ignore newlines.

    If you need to know about newlines, I would suggest you read the input into a string using getline, then use stringstream to parse out the integer values.
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #29
    Registered User
    Join Date
    Jun 2008
    Posts
    33
    Ok, thank you. Where can i read about usage of getline and stringstream because i don't have any books on c++?

  15. #30
    Registered User
    Join Date
    Jun 2008
    Posts
    33
    Can someone please help me with this stringstream. Just give me a good link if you know it or explain it to me how to parse integers from string with it please.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. File transfer- the file sometimes not full transferred
    By shu_fei86 in forum C# Programming
    Replies: 13
    Last Post: 03-13-2009, 12:44 PM
  2. Data Structure Eror
    By prominababy in forum C Programming
    Replies: 3
    Last Post: 01-06-2009, 09:35 AM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  5. gcc problem
    By bjdea1 in forum Linux Programming
    Replies: 13
    Last Post: 04-29-2002, 06:51 PM