Results 1 to 26 of 26

Thread: File Manipulation

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 2002
    Location
    Tulsa,Ok
    Posts
    262

    File Manipulation

    Guys,

    I am needing a little help finding some information.

    I am a VB programmer by day but I am also taking some C++ classes so I can maybe change languages, but C++ and I are not getting along.

    What I need to do is to be able to read a comma delimited file from a C++ program. the format would be like so

    "phone","last name","first Name","address"
    "phone","last name","first Name","address"
    "phone","last name","first Name","address"

    and so on. I have searched the forum and found nothing that I can tell relates to reading files like this. I have used the fstream header before for reading numbers and doing stuff with them but an address will have spaces, and fstream stops on a space.

    I also need to be able to append the file when a new record needs added.

    Any help would be appreciated.

    Jerel

  2. #2
    Hyperactive Member made_of_asp's Avatar
    Join Date
    Jul 2001
    Location
    123 Fake Street
    Posts
    394

    Smile

    My own implementation

    Code:
    #include <stdio.h>
    #include <malloc.h>
    #include <windows.h>
    
    //Frees a buffer
    void VirtualFreeHuge(char** pString, int uBound)
    {
    	//free each of the items
    	for(int i = 0; i <= uBound; i++)
    		free(pString[i]);
    
    	//free the item itself
    	free(pString);
    };
    
    TCHAR** VirtualSplitString(TCHAR* pString, TCHAR sep, int& uBound)
    {
        unsigned long s = 0; unsigned long i = 0;
        TCHAR** pArray = (TCHAR**)calloc(strlen(pString), sizeof(TCHAR*));
    	
        //allocate empty storage
        
        //the first array
        pArray[0] = (TCHAR*)calloc(1024, sizeof(TCHAR));
    
        //separate an array...
        while(*pString)
        {
            //go through the string, find position
            if(*pString == sep)
            {    
                i++;
                s = 0; //current position
                //allocate space for new input
                pArray[i] = (TCHAR*)calloc(1024, sizeof(TCHAR));
            }
            else
            {
                //get the current character and set it
                pArray[i][s] = *pString;
    
                //increase character position
                s++;
            }
    
            //increase string position
            pString++;
    
        }
        
        uBound = ++i;
    
        //return the pArray data type
        return pArray;
    };
    
    int main(int argc, char* argv[])
    {
    CHAR sz[1024];
    FILE* f = fopen("C:\\file.txt", "r");
    
    	while(fgets(sz, 1024, f))
    	{
    		int u;
    		char** s = VirtualSplitString(sz, ',', u);
    		
    		for(int i = 0; i < u; i++)
    			printf("%s\n", s[i]);
    
    		VirtualFreeHuge(s, u);
    	}
    
    	fclose(f);
    
    return 0;
    }
    
    
    fclose(f);
    VS.NET 2003

    Need to email me?

  3. #3
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    I'll write something that is (hopefully) easier to use tomorrow.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  4. #4

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 2002
    Location
    Tulsa,Ok
    Posts
    262
    *bump*

    made_of_asp: I appreciate you posting your code, but I have no idea what it is doing.

    Does anyone else have an example or can you point me in the right direction cause I really lost on how to do this.

    Jerel

  5. #5
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Is it supposed to read in this exact file or should it be more generic?
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  6. #6

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 2002
    Location
    Tulsa,Ok
    Posts
    262
    The program is a pizza order program so the file would be like so.

    "5551212","Doe","John","1212 Mockingbird Ln"

    I need to be able to extract the info from within the quotes.

    I have started by reading one char at a time and kina of parse it til I get to a '\n' char.

    Is that the best way to do it. made_of_asp was using the malloc.h header which if I remember what that is, its for grabbing chucks of memory from the heap and such, but his code lost me.

    I guess the answer is it could generic so it could read any comma-delimited file.

  7. #7
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Well, specialized is easier to write and to use...
    And especially to understand. You wouldn't want me to come up with nested vectors or vectors of maps.

    Here's specialized code for you.
    Code:
    #include <algorithm>	// container manipulation
    #include <string>		// easy strings
    #include <vector>		// growable array
    using namespace std;
    
    // struct representing one line of data in the file
    struct file_entry
    {
    	string sPhone;
    	string sLast;
    	string sFirst;
    	string sAddress;
    };
    
    // prototypes
    void read_your_file(const string &strFilename, vector<file_entry> &out);
    void split_string(const string &s, vector<string> & out, char split_at);
    ostream & operator <<(ostream &os, const file_entry &fe);
    istream & operator >>(istream &is, file_entry &fe);
    
    int main(int argc, char *argv[])
    {
    	// storage location for the data
    	vector<file_entry> vc;
    	// read in data
    	// call app like
    	// app data.txt
    	// where data.txt is the file you want to read
    	read_your_file(argv[1], vc);
    	// output the array
    	for(vector<file_entry>::iterator it = vc.begin(); it != vc.end(); ++it)
    		cout << *it << '\n';
    	// ensure data is displayed
    	cout.flush();
    	return 0;
    }
    
    // this takes a string and splits it into an array of smaller strings
    // it's splitted every time split_at is encountered
    void split_string(const string &s, vector<string> & out, char split_at)
    {
    	// for searching the string
    	string::const_iterator stay, run;
    	// set stay to the start of the string
    	stay = s.begin();
    	// temporary
    	string t;
    	// loop run through the string, from front to back
    	for(run=stay; run != s.end(); ++run)
    	{
    		// if encountered split char...
    		if(*run == split_at)
    		{
    			// ...clear the temporary value...
    			t.clear();
    			// (speeds it up a little)
    			t.reserve(run-stay);
    			// ..., copy current substring to temporary...
    			copy(stay, run, back_inserter(t));
    			// ...and add it to the array.
    			out.push_back(t);
    			// Finally, let the next substring begin directly after the splitting char.
    			stay = run+1;
    		}
    	}
    	// same as above for the last piece (from last split char to end of string)
    	t.clear();
    	t.reserve(run-stay);
    	copy(stay, run, back_inserter(t));
    	out.push_back(t);
    }
    
    // reads in one file_entry from any stream
    istream & operator >>(istream &is, file_entry &fe)
    {
    	// temporary
    	string t;
    	// read one line from the stream
    	getline(is, t);
    	// receives substrings
    	vector<string> vs;
    	// split the line
    	split_string(t, vs, ',');
    	// fill the struct
    	// substr removes the "
    	fe.sPhone = vs[0].substr(1, vs[0].size()-2);
    	fe.sLast = vs[1].substr(1, vs[1].size()-2);
    	fe.sFirst = vs[2].substr(1, vs[2].size()-2);
    	fe.sAddress = vs[3].substr(1, vs[3].size()-2);
    	return is;
    }
    
    // output a file_entry to a stream
    ostream & operator <<(ostream &os, const file_entry &fe)
    {
    	return os << fe.sPhone.c_str() << ' ' << fe.sLast.c_str() << ' '
    		<< fe.sFirst.c_str() << ' ' << fe.sAddress.c_str();
    }
    
    // read in a file of your format
    void read_your_file(const string &strFilename, vector<file_entry> &out)
    {
    	// the stream
    	ifstream ifs;
    	// open the file
    	ifs.open(strFilename.c_str());
    	// temporary
    	file_entry t;
    	// while the end is not reached
    	while(!ifs.eof()) {
    		// read in one entry
    		ifs >> t;
    		// and add it to the array
    		out.push_back(t);
    	}
    }
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  8. #8

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 2002
    Location
    Tulsa,Ok
    Posts
    262
    I really appreciate it.

    I am going to take this and fire it into my program and see how it works. It will probably be tomorrow before I can get back to you on it.

    When and if I have questions, would you be willing to answer them for me when the time comes. I am wanting to understand what it does and I see your comments. Just want to be sure I understand what I am going to turn in.

    Jerel

  9. #9
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Sure. Just ask.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  10. #10

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 2002
    Location
    Tulsa,Ok
    Posts
    262
    CB,

    When I compile the program I get an error on the t.clear statements.

    I also added the fstream header in there. Did you have the fstream header included as well?

    I get an error 2039 on the t.clear() lines.

  11. #11
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    This is strange. Are you sure you included <string> and not <string.h>?

    If it won't work you can alternativly write
    t = "";
    but this is less efficient than the clear call.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  12. #12

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 2002
    Location
    Tulsa,Ok
    Posts
    262
    CB,

    I still have not been able to get this to compile and run. I changed the t.clear to t = "" then I got an error 4786

    I figured out what the error was and added:

    #pragma warning(disable:4786) to my code

    Now I have this

    c:\program files\microsoft visual studio\vc98\include\iterator(82) : error C2039: 'push_back' : is not a member of 'basic_string<char,struct std::char_traits<char>,class std::allocator<char> >'
    c:\program files\microsoft visual studio\vc98\include\iterator(82) : while compiling class-template member function 'class std::back_insert_iterator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > &_
    _thiscall std::back_insert_iterator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >:perator =(const char &)'
    Error executing cl.exe.

    Do you have any ideas here.

    I think I understand what the code is doing and if I code run it and step through it, I would be ok.

    Jerel

    ps

    just to be safe here is the code I am running. It is the same code you posted with the exceptions of the t.clear, two more header files, and the pragma statement

    Code:
    #pragma warning(disable:4786)
    
    #include <algorithm>	// container manipulation
    #include <string>		// easy strings
    #include <vector>		// growable array
    #include <fstream>
    #include <iostream>
    
    using namespace std;
    
    // struct representing one line of data in the file
    struct file_entry
    {
    	string sPhone;
    	string sLast;
    	string sFirst;
    	string sAddress;
    };
    
    // prototypes
    void read_your_file(const string &strFilename, vector<file_entry> &out);
    void split_string(const string &s, vector<string> & out, char split_at);
    ostream & operator <<(ostream &os, const file_entry &fe);
    istream & operator >>(istream &is, file_entry &fe);
    
    int main(int argc, char *argv[])
    {
    	// storage location for the data
    	vector<file_entry> vc;
    	// read in data
    	// call app like
    	// app data.txt
    	// where data.txt is the file you want to read
    	read_your_file(argv[1], vc);
    	// output the array
    	for(vector<file_entry>::iterator it = vc.begin(); it != vc.end(); ++it)
    		cout << *it << '\n';
    	// ensure data is displayed
    	cout.flush();
    	return 0;
    }
    
    // this takes a string and splits it into an array of smaller strings
    // it's splitted every time split_at is encountered
    void split_string(const string &s, vector<string> & out, char split_at)
    {
    	// for searching the string
    	string::const_iterator stay, run;
    	// set stay to the start of the string
    	stay = s.begin();
    	// temporary
    	string t;
    	// loop run through the string, from front to back
    	for(run=stay; run != s.end(); ++run)
    	{
    		// if encountered split char...
    		if(*run == split_at)
    		{
    			// ...clear the temporary value...
    			t = "";
    			// (speeds it up a little)
    			t.reserve(run-stay);
    			// ..., copy current substring to temporary...
    			copy(stay, run, back_inserter(t));
    			// ...and add it to the array.
    			out.push_back(t);
    			// Finally, let the next substring begin directly after the splitting char.
    			stay = run+1;
    		}
    	}
    	// same as above for the last piece (from last split char to end of string)
    	t = "";
    	t.reserve(run-stay);
    	copy(stay, run, back_inserter(t));
    	out.push_back(t);
    }
    
    // reads in one file_entry from any stream
    istream & operator >>(istream &is, file_entry &fe)
    {
    	// temporary
    	string t;
    	// read one line from the stream
    	getline(is, t);
    	// receives substrings
    	vector<string> vs;
    	// split the line
    	split_string(t, vs, ',');
    	// fill the struct
    	// substr removes the "
    	fe.sPhone = vs[0].substr(1, vs[0].size()-2);
    	fe.sLast = vs[1].substr(1, vs[1].size()-2);
    	fe.sFirst = vs[2].substr(1, vs[2].size()-2);
    	fe.sAddress = vs[3].substr(1, vs[3].size()-2);
    	return is;
    }
    
    // output a file_entry to a stream
    ostream & operator <<(ostream &os, const file_entry &fe)
    {
    	return os << fe.sPhone.c_str() << ' ' << fe.sLast.c_str() << ' '
    		<< fe.sFirst.c_str() << ' ' << fe.sAddress.c_str();
    }
    
    // read in a file of your format
    void read_your_file(const string &strFilename, vector<file_entry> &out)
    {
    	// the stream
    	ifstream ifs;
    	// open the file
    	ifs.open(strFilename.c_str());
    	// temporary
    	file_entry t;
    	// while the end is not reached
    	while(!ifs.eof()) {
    		// read in one entry
    		ifs >> t;
    		// and add it to the array
    		out.push_back(t);
    	}
    }

  13. #13
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    What compiler are you using? push_back is (just as clear btw) a part of standard C++.

    Could it be that some other header named <string> takes precedence over the one you want?
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  14. #14
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Oh, I see, VC++6 doesn't compile it...

    I'll see what can be done.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  15. #15
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Replace the split_string function by this:
    Code:
    // this takes a string and splits it into an array of smaller strings
    // it's splitted every time split_at is encountered
    void split_string(const string &s, vector<string> & out, char split_at)
    {
    	// for searching the string
    	string::const_iterator stay, run;
    	// set stay to the start of the string
    	stay = s.begin();
    	// temporary
    	string t;
    	// loop run through the string, from front to back
    	for(run=stay; run != s.end(); ++run)
    	{
    		// if encountered split char...
    		if(*run == split_at)
    		{
    			// ...clear the temporary value...
    			t.erase();
    			// (speeds it up a little)
    			t.reserve(run-stay);
    			// ..., copy current substring to temporary...
    			t.append(stay, run);
    			// ...and add it to the array.
    			out.push_back(t);
    			// Finally, let the next substring begin directly after the splitting char.
    			stay = run+1;
    		}
    	}
    	// same as above for the last piece (from last split char to end of string)
    	t.erase();
    	t.reserve(run-stay);
    	t.append(stay, run);
    	out.push_back(t);
    }
    Stupid VC++6 *mumble*...
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  16. #16

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 2002
    Location
    Tulsa,Ok
    Posts
    262
    that did it. and the wild thing is I understand what it is doing.

    and to think of all those curse words I have said about c++

    Thanks again,

    Jerel

  17. #17
    Hyperactive Member made_of_asp's Avatar
    Join Date
    Jul 2001
    Location
    123 Fake Street
    Posts
    394
    By The way, whats wrong with my method? It does exactly what you wanted.

    It splits "AAA","BBB","CCCCCCCC" separatly.
    VS.NET 2003

    Need to email me?

  18. #18
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    I only splits, and doesn't read a file or anything.

    And if it's only about splitting then strtoc is easier - and it doesn't ask the user to free any memory.

    And finally it is pure C while mine is C++ and takes advantage of various C++ features, namely string and vector.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  19. #19

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 2002
    Location
    Tulsa,Ok
    Posts
    262
    CB,

    I am having a bit of trouble with this code for some reason. I basically have your code but I have changed it just a bit to make it my own and to help me understand it better.

    anyway, the problem is, when I call the Parse function, the program crashes and if I debug it, I get a fatal exception. I dont have anything different than you. Its crashing when I pass the values to the function. I have look on here and read the books I have and I dont anything wrong.

    here is the prototype

    Code:
    void ParseString(const string &, vector<string> &);
    here is the function
    Code:
    void ParseString(const string &strParse, vector<string> &v)
    {
    	// This sub will parse the string and add it to the vector
    	// We are passing by reference the string to parse and
    	// the vector to store it in
    
    	string::const_iterator start,stop;		//This will help count through the string
    	string sTemp;													//Temp string for storing the parsed variable
    
    	stop = strParse.begin();							//Set this to the fron of the string
    
    	//This loop will parse strParse. It will look for the comma and grab
    	//everything between start and stop until wee reach the end of the line
    
    	for (start = stop; start != strParse.end(); start++ )
    		{
    			//See if we are ready to parse
    			//typcast the ',' so we cansave some memory
    			if ( *start == char(',') )				//If where we are looking is a comma, then time to parse
    			{
    				sTemp.erase();									//Make sure we are empty
    				sTemp.reserve(start-stop);			//Reserve the right memory.
    				sTemp.append(	stop, start );		//Copy out what we need
    				v.push_back( sTemp );						//Add the new sting to the vector
    				stop = start + 1;								//Move the pointer past the comma
    
    			}
    			//When we exit the loop, we will need to grab he last of the line
    			sTemp.erase();										//Make sure we are empty
    			sTemp.reserve(start-stop);				//Reserve the right memory.
    			sTemp.append(	stop, start );			//Copy out what we need
    			v.push_back( sTemp );							//Add the new sting to the vector
    		}
    
    }
    and here is how I call it, and how the variable are declared
    Code:
    string temp;
    vector<string> tempVector;
    
    ParseString( temp, tempVector );
    I just dont understand why its crashing

    Jerel

  20. #20
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    I don't either. Give me the whole code (or better, zip up the whole project) and post it, I'll take a look on it tomorrow or tuesday.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  21. #21

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 2002
    Location
    Tulsa,Ok
    Posts
    262
    There it is. I only added the .cpp and the text file I am using.

    I changed the file so it had no "" in the fields. Mainly just to give me a chance to play with the code and make it different so I could understand it better. Its far from finished but it is getting there.

    Thanks,

    Jerel
    Attached Files Attached Files

  22. #22

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 2002
    Location
    Tulsa,Ok
    Posts
    262
    CB,

    I deleted the byref variable and then readded them one at a time to see what was causing the problem and it started working. I eyeballed the code to death, maybe there was something not quite right.

    I dont know but it is working now.

    Thanks for the time you've given me,

    Jerel

  23. #23
    PowerPoster Chris's Avatar
    Join Date
    Jan 1999
    Location
    K-PAX
    Posts
    3,238
    Hi CornedBee, is the following library is belong to WTL? as you use in your sample code.

    PHP Code:
    #include <algorithm>    // container manipulation
    #include <string>        // easy strings
    #include <vector>        // growable array
    using namespace std

  24. #24
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    No, that's the Standard C++ Library. They used to be called the STL and people will recognise that, but technically they're not really that anymore.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  25. #25
    PowerPoster Chris's Avatar
    Join Date
    Jan 1999
    Location
    K-PAX
    Posts
    3,238
    Which mean i can call it from my C/C++ program? What is the binary dlls file for this STL library? As im new in WTL/STL/ATL

  26. #26
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Which DLLs it is in may not apply. You might not be on Windows, you might be statically linking, whatever.

    Note. STL is different from ATL and WTL, i.e. it's actually standardised, so you know it works on *all* systems......or should

    Mostly, the STL code is templates anyway, so it will be included directly into your program.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width