|
George L. Jackson wrote: Is that why you seem to go bananas after reading some of the posts on Code Project?
Hey! I resemble that remark.
|
|
|
|
|
Hi All,
I'm having trouble getting a file into a list. What I don't want to do is read a line (string), and then push_back() for each character.
Is anyone aware of the ctor I'm interested in which takes an ifstream ?
I can't believe how rusty I am with STL...
Thanks,
Jeff
std::list< char > certificate;
std::ifstream file;
<br>
file.open( "..//smime.p7b", std::ios::binary );
<br><br>
if( false == file.is_open() ) { return 1; }
<br><br>
char c;
while( file.get( c ) )
{
certificate.push_back( c );
}
<br><br>
std::cout << "Certificate Size: ";
std::cout << certificate.size() << std::endl;
<br><br>
file.close();
|
|
|
|
|
Why do you need this file loaded in a list<char> object instead of a vector<char> ? I mean, wouldn't something like this suffice (error checks omitted)?
vector<char> buffer;
ifstream file;
size_t fileSize;
file.open( "..\\smime.p7b", ios::binary );
file.seekg( 0, ios_base::end );
fileSize = file.tellg();
buffer.resize( fileSize );
file.seekg( 0, ios_base::beg );
file.read( &buffer.front(), buffer.size() );
|
|
|
|
|
Hi gleat,
gleat wrote: Why do you need this file loaded in a list<char> object instead of a vector<char>?
I'm using it to help me parse the input. With a list (or stack) once a top/pop occurs, I don't have to worry about adjusting a pointer (or index) into the array. Also, I can push back values without concern for book keeping.
Jeff
|
|
|
|
|
Using std::list like this is very inefficient; it's essentially a doubly liked list with -- in your case each -- each node containing a single char . You'd be better off using a std::vector .
Steve
|
|
|
|
|
Hi Steve,
Thanks for the reply.
Stephen Hewitt wrote: Using std::list like this is very inefficient;
I should have stated the files are small - less than 5KB. I desired to simplify insertion and extraction. With the list, both operations are O(1) (constant time), with a memory footprint ~= 3 times original files size. I do not need random access (vector). Also, I do not need to search.
Stephen Hewitt wrote: You'd be better off using a std::vector.
With vector, I loose O(1) extraction (extraction is linear from front or middle). Insertion is O(1) if at the end. But I have to manage an index or pointer. However, size ~= 1x.
Taking from SGI's site on vectors:
Vector is the simplest of the STL container classes, and in many cases the most efficient. As the docs state, "in most cases". In my case, I am working on a parser/scanner (no need for the tokenizer). I believe if I wanted to lessen memory needs, I could use an slist. But out of habit, I grabbed a list.
In the end, I am willing to trade memory for time (and simplicity).
Thanks for the input,
Jeff
|
|
|
|
|
Why are you inserting anything into the input file? It sounds like you're going to be mutating the input structure to form the output? When parsing, I prefer to use a pure functional approach, so that the input is immutable, and I form a separate output structure. Having said that, I know nothing about the format you're parsing
|
|
|
|
|
Eeep - I wouldn't use a list for that - as the others have said, use a vector.
Once you get past that, the easiest way to populate the vector is like this (or a list, actually, as shown):
<code>std::ifstream file (filename);
std::vector<char> vectorStore(std::istream_iterator<char>(file), std::istream_iterator<char>());
{or}
</code><code>std::list<char> listStore(std::istream_iterator<char>(file), std::istream_iterator<char>());</code> This may discard line-endings in text (as opposed to binary) mode - I'm not sure.
An alternative (and more efficient for big files) approach would be to reserve enough space in the vector before reading the file:
std::vector<char> fileContents;
struct _stat stat;
if (_stat(filename, &stat) == -1) throw std::runtime_error("Can\'t open " + file);
fileContents.resize(stat.st_size);
std::ifstream file(filename);
std::copy(std::istream_iterator<char>(file), std::istream_iterator<char>(),
fileContents.begin()); Once you have the contents in a vector, parse them from there. Use iterators to keep track of input location.
|
|
|
|
|
Hi Stuart,
I went into detail on my choosing of a list over vector with Steve above (and concluded I could use a slist to lessen memory requirements). But I believe I could use your code on the stream. Thanks.
Jeff
|
|
|
|
|
One other thing - one detail I didn't notice was that your file is a binary format - strictly, you should be using unsigned char s, I guess, so that signs don't get in the way. Probably doesn't make any pragmatic difference, though.
|
|
|
|
|
Hi Stuart,
Stuart Dootson wrote: strictly, you should be using unsigned chars,
Got it... I was being lazy before I did the #define byte unsigned char
Thanks,
Jeff
|
|
|
|
|
Jeffrey Walton wrote: file.open( "..//smime.p7b", std::ios::binary );
A P7B file is a Cryptographic Message Sytnax Standard (PKCS #7). As such, it is specified in ASN.1 notation.
ASN.1 is an interesting beast. To parse, it requires more of a 'Message Cracker' (similar to Windows Messaging), rather than a full fledged parser/tokenizer (HTML, XML, etc).
Jeff
|
|
|
|
|
Dear all,
Could you help me giving a sample of a function which return bitset (Standar Template Library). Please reply as soon as possible. I am waiting...
Thanks.
Regards,
Ian
|
|
|
|
|
#include <bitset>
std::bitset<12> BitsetWithNthBitSet(int n)
{
return std::bitset<12>().set(n, true);
}
|
|
|
|
|
Stuart Dootson wrote: std::bitset<12> BitsetWithNthBitSet(int n) { ...
In the example above you mention the N of bitset<n> is 12. How about if you don't know the 'N'?
-- modified at 22:54 Thursday 8th November, 2007
|
|
|
|
|
|
You can only use std::bitset if N is fixed at compile-time. If you don't know N until runtime, you can use std::vector<bool> or (as Rob said) boost::dynamic_bitset .
|
|
|
|
|
Ontanggabe Parulian wrote: In the example above you mention the N of bitset is 12. How about if you don't know the 'N'?
i feel, you need to N , otherwise how you determine which bit you have to set.
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow Never mind - my own stupidity is the source of every "problem" - Mixture
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
Support CRY- Child Relief and You
|
|
|
|
|
Hello all.
So I was working with no problem in some DLLs using WTL's CString. No problemo here. However, now that I'm building my UI with WTL, the compiler is throwing me a naughty error: "CString: ambiguos symbol".
I have the following headers in my stdafx.h file:
#include <atlwin.h>
#include <atlcrack.h>
#include <atlframe.h>
#include <atlctrls.h>
#include <atldlgs.h>
#include <atlctrlw.h>
#include <atlctrlx.h>
#include <atlddx.h>
#include <atltime.h>
#include <atlmisc.h>
The bolded include is the one causing the problem. The reason is that such file uses ATL's CString version. Is there any way I can avoid ATL::CString messing up my code (I mean, without having to prefix my code with WTL::CString)?
Thanks in advance.
Hope is the negation of reality - Raistlin Majere
|
|
|
|
|
I think you can avoid the ambigous symbol problem by placing:
using WTL::CString;
in your stdafx.h file.
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
No, by doing so it throws me the "CString ambiguos symbol"...
Hope is the negation of reality - Raistlin Majere
|
|
|
|
|
Have you tried to "typedef" WTL::CString to something like WString?
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
Yep, already. Even tried things like
#undef CString
#define WTL::CString CString
but didn't work.
Hope is the negation of reality - Raistlin Majere
|
|
|
|
|
CString is actually a "typedef" at global scope! Why did they do that?
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
I think I found it! You have to define: _ATL_NO_AUTOMATIC_NAMESPACE because the atlbase.h header file has a using namespace ATL; .
Thus, you can do: using WTL::CString;
However, that opens up another problem with the ATL namespace contents!
-- modified at 21:27 Wednesday 7th November, 2007
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|