I have a text file included as resource to my EXE.
i declared a LPSTR variable which consists of the full contents of my
text file (included asresource)
this LPSTR consists of several lines of my initial text file.
i know that each line is a semi-colon formated line ending by a CRLF (0D
0A in hexa).
how can i extract each line of my resource in order to place them into
an string array ?
thx,
Maileen
The old, tried and true <g> way would have you use strtok().
Regards,
Will
std::vector<tstring> v;
v = Split(s, L' \n'); // L'\n' is the newline character
// the vector can be indexed like an array.
for (k = 0; k < v.size(); k++)
err_file << v[k] << " ";
err_file << std::endl;
Good luck,
Ed
//
// Splits a tstring into a vector of tstrings
//
//
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <comutil.h>
#include <string>
#include <vector>
#include <tchar.h>
#ifndef tstring
typedef std::basic_string<TCHAR> tstring;
#endif
const std::vector<tstring> Split(const tstring& s, wchar_t sep )
{
std::vector<tstring> v;
std::ofstream err_file;
err_file.open("error.log", std::ios::out|std::ios::app);
if(!err_file){
exit (1);
}
int state=0; // 0 means looking for non whitespace
// 1 means looking for whitespace
int count=0, i=0;
tstring tok;
while( s[i] != L'\0'){
if(state == 0){ // looking for a word to begin
if(s[i] != sep ){
tok += s[i];
state =1;
}
else{
}
}
else {// looking for word to end
if(s[i] == sep ){
count++;
state = 0;
v.push_back(tok); // save completed token in the vector
tok.erase();
}
else{
tok += s[i];
}
}
i++;
}
if(state == 1){
state = 0;
v.push_back(tok); // save last completed token in the vector
tok.erase();
count++; // count the last word if it was delimited with the
NULL
}
// err_file << "count = " << count << std::endl;
err_file.close();
return v;
One way would be to use an istringstream to do most of the work:
std::istringstream<std::string> input(your_lpstr);
std::string buffer;
std::vector<std::string> lines;
while (std::getline(input, buffer))
std::push_back(lines, buffer);
I tend to like another a bit better, even though it takes a bit more
code. We start by defining a string proxy that knows that it's a
line -- I.e. that when being read from a file, a whole line should be
read, not just a space delimited word:
class line {
std::string data;
public:
friend std::istream &operator>>(std::istream &is, line &l) {
std::getline(is, l.data);
return is;
}
operator std::string() { return data; }
};
having done that, we can basically just use std::copy to copy lines
to a vector:
std::vector<line> lines;
std::istringstream input(your_lpstr);
std::copy(
std::istream_iterator<line>(input),
std::istream_iterator<line>(),
std::back_inserter(lines));
Depending on what sorts of things you're doing, there's yet another
possibility: create a locale that only treats \r and \n as white
space:
class line_reader : std::ctype<char> {
line_reader() : std::ctype<char>(get_table()) {}
static std::ctype_base::mask const *get_table() {
static std::ctype_base::mask *rc;
if ( rc == 0) {
rc = new std::ctype_base::mask
[std::ctype<char>::table_size];
std::fill_n(rc, std::ctype,char>::table_size,
std::ctype_base::mask());
rc['\r'] = rc['\n'] = std::ctype_base::space;
]
return rc;
}
};
Using this is somewhat similar:
std::istringstream input(your_lpstr);
input.imbue(std::locale(std::locale(), new line_reader));
std::vector<std::string> lines;
std::copy(std::istream_iterator<std::string>(input),
std::istream_iterator<std::string>(),
std::back_inserter(lines));
Which of these is best will depend on the situation. If you're doing
this in one place, and that's it, then it's probably easiest to use
the first.
If you're reading line-at-a-time in quite a few places, the second is
probably easier to use, but it treats the line-at-a-time behavior as
part of the type of thing you're reading. The third uses locales,
which few people ever even look at, not to mention understanding, but
in some ways it's probably the cleanest of the solutions -- it plugs
into the standard library and extends it in exactly one of the
intended ways.
There are a number of other possibilities -- Boost has a tokenizer
class, and the standard library has strtok. I hesitate at even
mentioning strtok though -- IMO, it's only one (rather small) step
above gets, in being a function you should virtually never use.
Nearly the only use of strtok I condone is one that's completely
different from its intent or normal use -- if (for example) you're
reading lines of text in C (using fgets), it works well for stripping
off the trailing newline you normally get:
fgets(input_file, buffer, sizeof(buffer));
strtok(buffer, "\n");
Whether this is good or bad is open to question: it's about the
cleanest way I know of to do this job and it's nearly the only really
safe use for strtok, but people find it puzzling, since it's totally
different from the usual purpose to which strtok is put.
--
Later,
Jerry.
The universe is a figment of its own imagination.