Sign in to follow this  
Oxyd

File position at 8th byte after extracting 1 character?

Recommended Posts

Oxyd    1162
I'm reading a file that's opened in text-mode. When I open the file, the file.tellg () returns 0, but after I call file.get () (and file.gcount is equal to 1), file.tellg () returns 8. From now on, it works as I think, it should, that is it tellg returns 9 after calling get, but I don't know, why I get warped to 8th character after extracting one character... Oxyd

Share this post


Link to post
Share on other sites
snk_kid    1312
std::iostream::gcount : Get number of characters extracted by last unformatted input operation.

std::iostream::tellg : Get position of the get pointer.
std::iostrema::tellp : Get position of the put pointer.

Share this post


Link to post
Share on other sites
snk_kid    1312
did you mean searching for a string in a binary file? if not i think you may be going about it the wrong way.

Quote:
Original post by Oxyd
Ah so... So if I want to seek through the file to search for a string and return it's position in the file I should do the counting myself?


you can still use gcount if you wont to but it gives you relative amount of bytes read not absolute so you just need to have a variable that keeps count and adds to it by calling gcount after each unformatted op i mean:


//declared & defined some where
std::streamsize num_of_bytes_read(0);

//....

//first unformatted read op
num_of_bytes_read = ifs.gcount();

//....

//another read op.
num_of_bytes_read += ifs.gcount();


perhaps if you described abit more about what your trying to do we might be able to suggest better alternative.

[Edited by - snk_kid on November 11, 2004 11:27:08 AM]

Share this post


Link to post
Share on other sites
Oxyd    1162
Quote:
perhaps if you described abit more about what your trying to do & we can suggest maybe a better alternative


I'm trying to do a simple config-file parser. The syntax should be as simple as "<identifier> <value>".

I've done it by loading whole file into memory and parsing it there. But I'm still wondering, wheter there's a method to find and load just the line I need...

Oxyd

Share this post


Link to post
Share on other sites
snk_kid    1312
Quote:
Original post by Oxyd
I'm trying to do a simple config-file parser. The syntax should be as simple as "<identifier> <value>".


Is it a text file? what types can value be? is the identifier a string type or some other type?

Quote:
Original post by Oxyd
But I'm still wondering, wheter there's a method to find and load just the line I need...


yes there is, i can shed some light if you wont [wink]

Share this post


Link to post
Share on other sites
Oxyd    1162
Quote:
Original post by snk_kid
Quote:
Original post by Oxyd
I'm trying to do a simple config-file parser. The syntax should be as simple as "<identifier> <value>".


Is it a text file? what types can value be? is the identifier a string type or some other type?


It's a text file. Value is string and so are the identifiers.

Quote:
i can shed some light if you wont [wink]


If you could give me some advice, I'd be happy [smile]

Oxyd

Share this post


Link to post
Share on other sites
snk_kid    1312
okay to read in the whole thing you can use std::map of strings to strings which will keep the keys unique for you (and sorted which don't really need so std::hash_map would be more efficient but its an STL extension so its not currently part of the standard. e.g.:

input file jack.txt:

foo bar
scooby snacks
snk neo-geo
jimboob dan


code:


#include <iterator>
#include <map>
#include <string>
#include <fstream>
#include <iostream>

typedef std::map<std::string, std::string> prop_map;

int main(int argc, char* argv[]) {

if(argc == 1) {
std::cerr << argv[0] << " error usage: " << argv[0] << " <file-name>\n";
return EXIT_FAILURE;
}

std::ifstream in(argv[1]);

if(!in) {
std::cerr << argv[0] << " error could not open file\n";
return EXIT_FAILURE;
}

prop_map p;

std::istream_iterator<std::string> in_itr(in), in_end;

while(in_itr != in_end) {
p[*in_itr] = *(++in_itr);
++in_itr;
}

for(prop_map::const_iterator itr = p.begin(), end = p.end();
itr != end;
++itr)
std::cout << "key: " << itr->first << "\tvalue: " << itr->second << std::endl;

}



To search for value with given a search key with-out reading in the file you can use stream iterators & STL algorithms:


#include <algorithm>
#include <iterator>
#include <string>
#include <fstream>
#include <iostream>

int main(int argc, char* argv[]) {

typedef std::istream_iterator<std::string> iss_itr;

if(argc == 1) {
std::cerr << argv[0] << " error usage: " << argv[0] << " <file-name>\n";
return EXIT_FAILURE;
}

std::ifstream in(argv[1]);

if(!in) {
std::cerr << argv[0] << " error could not open file\n";
return EXIT_FAILURE;
}


iss_itr in_itr(in), end;

iss_itr result = std::find(in_itr, end, "snk");

if(result != end)
std::cout << "found key " << *result++ << ", value = " << *result << std::endl;
else
std::cout << "no key found\n";

return EXIT_SUCCESS;

}


if your string values have whitespace then both sources need to be changed a little otherwise it will ka-bork on you, if you need hand just give a shout.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this