Is it a good practice to avoid modifying the fmtflags of a stream permanently?
For instance, the function I wrote does
std::ios_base::fmtflags flags = std::cout.setf(std::ios_base::boolalpha);
at the beginning and
std::cout.setf(flags);
right before the end.
Should I do this? Suppose multiple unrelated functions use the same stream and require different formatting options.
Yes, it seems self-evident that leaving the stream in the state you found it (as pertains to formatting flags) is a decent thing to do in the general case.
Whether you should actually do it in your specific case entirely depends on what other components use the same stream and what their expectations are of it.
Related
I have a game engine and a shader parser. The engine has an API for reading from a virtual file system. I would like to be able to load shaders through this API. I was thinking about implementing my own std::ifstream but I don't like it, my api is very simple and I don't want to do a lot of unnecessary work. I just need to be able to read N bytes from the VFS. I used a C++ mod for more convenience, but in the end I can not find a solution to this problem, since there is very little official information about this. Everything is there for the C API, at least I can call the scan_string function, I did not find such a function in the yyFlexParser interface.
To be honest, I wanted to abandon the std::ifstream in the parser, and return only the C api . The only thing I used the Flex C++ mode for is to interact with the Bison C++ API and so that the parser can be used in a multi-threaded environment, but this can also be achieved with the C API.
I just couldn't compile the C parser with the C++ compiler.
I would be happy if there is a way to add such functionality through some kind of macro.
I wouldn't mind if there was a way to return the yy_scan_string function, I could read the whole file myself and provide just a string.
The simple solution, if you just want to provide a string input, is to make the string into a std::istringstream, which is a valid std::istream. The simplicity of this solution reduces the need for an equivalent to yy_scan_string.
On the other hand, if you have a data source you want to read from which is not derived from std::istream, you can easily create a lexical scanner which does whatever is necessary. Just subclass yyFlexLexer, add whatever private data members you will need and a constructor which initialises them, and override int LexerInput(char* buffer, size_t maxsize); to read at least one and no more than maxsize bytes into buffer, returning the number of characters read. (YY_INPUT also works in the C++ interface, but subclassing is more convenient precisely because it lets you maintain your own reader state.)
Notes:
If you decide to subclass and override LexerInput, you need to be aware that "interactive" mode is actually implemented in LexerInput. So if you want your lexer to have an interactive mode, you'll have to implement it in your override, too. In interactive mode, LexerInput always reads exactly one character (unless, of course, it's at the end of the file).
As you can see in the Flex code repository, a future version of Flex will use refactored versions of these functions, so you might need to be prepared to modify your code in the future, although Flex generally maintains backwards compatibility for a long time.
I need to develop a C++ routine performing this apparently trivial task: create a file only if it does not exist, else do nothing/raise error.
As I need to avoid race conditions, I want to use the "ask forgiveness not permission" principle (i.e. attempting the intended operation and checking if it succeeded, as opposed to checking preconditions in advance), which, to my knowledge, is the only robust and portable method for this purpose [Wikipedia article][an example with getline].
Still, I could not find a way to implement it in my case. The best I could come up with is opening a fstream in app mode (or fopening with "a"), checking the output position with tellp (C++) or ftell (C) and aborting if such position is not zero. This has however two disadvantages, namely that if the file exists it gets locked (although for a short time) and its modification date is altered.
I checked other possible combinations of ios_base::openmode for fstream, as well as the mode strings of fopen but found no option that suited my needs. Further search in the C and C++ standard libraries, as well as Boost Filesystem, proved unfruitful.
Can someone point out a method to perform my task in a robust way (no collateral effects, no race conditions) without relying on OS-specific functions?
My specific problem is in Windows, but portable solutions would be preferred.
EDIT: The answer by BitWhistler completely solves the problem for C programs. Still, I am amazed that no C++ idiomatic solution seems to exist. Either one uses open with the O_EXCL attribute as proposed by Andrew Henle, which is however OS-specific (in Windows the attribute seems to be called _O_EXCL with an additional underscore [MSDN]) or one separately compiles a C11 file and links it from the C++ code. Moreover, the file descriptor obtained cannot be converted to a stream except with nonstandard extensions (e.g. GCC's __gnu_cxx::stdio_filebuf). I hope a future version of C++ will implement the "x" subattribute and possibly also a corresponding ios:: modificator for file streams.
The new C standard (C2011, which is not part of C++) adds a new standard subspecifier ("x"), that can be appended to any "w" specifier (to form "wx", "wbx", "w+x" or "w+bx"/"wb+x"). This subspecifier forces the function to fail if the file exists, instead of overwriting it.
source: http://www.cplusplus.com/reference/cstdio/fopen/
Is it possible to get the pointer to the string stored in string stream object . Basically i want to copy the string from that location into another buffer ..
I found that i can get the length from below code
myStringStreamObj.seekg(0, ios::end);
lengthForStringInmyStringStreamObj = myStringStreamObj.tellg();
I know i can always domyStringStreamObj.str().c_str(). However my profiler tells me this code is taking time and i want to avoid it . hence i need some good alternative to get pointer to that string.
My profiler also tells me that another part of code where is do myStringStreamObj.str(std::string()) is slow too . Can some one guide me on this too .
Please , I cant avoid stringstream as its part of a big code which i cant change / dont have permission to change .
The answer is "no". The only documented API to obtain the formatted string contents is the str() method.
Of course, there's always a small possibility that whatever the compiler or platform you're using might have its own specific non-standard and/or non-documented methods for accessing the internals of a stringstream object; which might be faster. Because your question did not specify any particular compiler or implementation, I must conclude that you are looking for a portable, standards-compliant answer; so the answer in that case is a pretty much a "no".
I would actually be surprised if any particular compiler or platform, even some who might have a "reputation" for poisonings language standards <cough>, would offer any alternatives. I would expect that all implementations would prefer to keep the internal stringstream moving gears private, so that they can be tweaked and fiddled with, in future releases, without breaking binary ABI compatibility.
The only other possibility you might want to investigate is to obtain the contents of the stringstream using its iterators. This is, of course, an entirely different mechanism for pulling out what's in a stringstream; and is not as straightforward as just calling one method that hands you the string, on a silver platter; so it's likely to involve a fairly significant rewrite of your code that works with the returned string. But it is possible that iterating over what's in the stringstream might turn out to be faster since, presumably, there will not be any need for the implementation to allocate a new std::string instance just for str()'s benefit, and jamming everything inside it.
Whether or not iterating will be faster in your case depends on how your implementation's stringstream works, and how efficient the compiler is. The only way to find out is to go ahead and do it, then profile the results.
I can not provide a portable, standards compliant method.
Although you can't get the internal buffer you can provide your own.
According to the standard setting the internal buffer of a std::stringbuf object has implementation defined behaviour.
cplusplus.com: std::stringbuf::setbuf()
As it happens in my implementation of GCC 4.8.2 the behaviour is to use the external buffer you provide instead if its internal std::string.
So you can do this:
int main()
{
std::ostringstream oss;
char buf[1024]; // this is where the data ends up when you write to oss
oss.rdbuf()->pubsetbuf(buf, sizeof(buf));
oss << "Testing" << 1 << 2 << 3.2 << '\0';
std::cout << buf; // see the data
}
But I strongly advise that you only do stuff like this as a (very) temporary measure while you sort out something more efficient that is portable according to the standard.
Having said all that I looked at how my implementation implements std::stringstream::str() and it basically returns its internal std::string so you get direct access and with optimization turned on the function calls should be completely optimized away. So this should be the preferred method.
Is there a way I can check if an istream of ostream is seekable?
I suspect doing a test seek and checking for failbit is not correct
since the seek can fail for unrelated reasons.
I need this to work on Linux and mac, if that makes a difference.
Iostreams doesn't give you much. Stream objects are just wrappers around a buffer object derived from class std::streambuf. (Assuming "narrow" characters.) The standard derived buffer classes are std::stringbuf for strings and std::filebuf for files. Supposing you're only interested in files, std::filebuf is just a simple wrapper around the C library functionality. The C library does not define a way to determine if a FILE object supports seeking or not, besides attempting to do so, so neither does C++.
For what it's worth, the semantics of seek vary a bit. Some platforms might allow you to "seek" a pipe but only to the current position, to determine how many characters have been read or written. Seeking past the end might resize the file, or might cause the next write operation to resize the file, or something in between.
You might also try checking errno if badbit is set (or, as I prefer, use exceptions instead of flags).
I am getting warning when using the std copy function.
I have a byte array that I declare.
byte *tstArray = new byte[length];
Then I have a couple other byte arrays that are declared and initialized with some hex values that i would like to use depending on some initial user input.
I have a series of if statements that I use to basically parse out the original input, and based on some string, I choose which byte array to use and in doing so copy the results to the original tstArray.
For example:
if(substr1 == "15")
{
std::cout<<"Using byte array rated 15"<<std::endl;
std::copy(ratedArray15,ratedArray15+length,tstArray);
}
The warning i get is
warning C4996: 'std::copy': Function call with parameters
that may be unsafe
- this call relies on the caller to check that the passed
values are correct.
A possible solution is to to disable this warning is by useing -D_SCL_SECURE_NO_WARNINGS, I think. Well, that is what I am researching.
But, I am not sure if this means that my code is really unsafe and I actually needed to do some checking?
C4996 means you're using a function that was marked as __declspec(deprecated). Probably using D_SCL_SECURE_NO_WARNINGS will just #ifdef out the deprecation. You could go read the header file to know for sure.
But the question is why is it deprecated? MSDN doesn't seem to say anything about it on the std::copy() page, but I may be looking at the wrong one. Typically this was done for all "unsafe string manipulation functions" during the great security push of XPSP2. Since you aren't passing the length of your destination buffer to std::copy, if you try to write too much data to it it will happily write past the end of the buffer.
To say whether or not your usage is unsafe would require us to review your entire code. Usually there is a safer version they recommend when they deprecate a function in this manner. You could just copy the strings in some other way. This article seems to go in depth. They seem to imply you should be using a std::checked_array_iterator instead of a regular OutputIterator.
Something like:
stdext::checked_array_iterator<char *> chkd_test_array(tstArray, length);
std::copy(ratedArray15, ratedArray15+length, chkd_test_array);
(If I understand your code right.)
Basically, what this warning tells you is that you have to be absolutely sure that tstArray points to an array that is large enough to hold "length" elements, as std::copy does not check that.
Well, I assume Microsoft's unilateral deprecation of the stdlib also includes passing char* to std::copy. (They've messed with a whole range of functions actually.)
I suppose parts of it has some merit (fopen() touches global ERRNO, so it's not thread-safe) but other decisions do not seem very rational. (I'd say they took a too big swathe at the whole thing. There should be levels, such as non-threadsafe, non-checkable, etc)
I'd recommend reading the MS-doc on each function if you want to know the issues about each case though, it's pretty well documented why each function has that warning, and the cause is usually different in each case.
At least it seems that VC++ 2010 RC does not emit that warning at the default warning level.