I work in C++Builder 6. I have a file.txt with 5 words, I would like to be able to save all these words in an AnsiString, then change something in them and save it again in file.txt. Anyone have any idea?
C++Builder 6 did not offer much in the way of structured file I/O. Modern versions of C++Builder provide more options.
In BCB6, the simplest solution would be to use the TStringList class in <Classes.hpp>, with its LoadFromFile() and SaveToFile() methods, and its Text or Strings[] properties.
Alternatively, you can use the standard C++ std::(i|o)fstream classes in <fstream>. An AnsiString can be used with the << and >> operators of the standard C++ streams by defining VCL_IOSTREAM in your project's Conditionals list.
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 am writing a C++ program and I want to have some created files deleted if meeting with some conditions. These file have various file names that are assigned using type "string" in each iteration. Now I'm trying to delete some of the files with their file names, but it seems that neither Deletefile function nor remove can deal with C++ strings. I have also tried to convert the strings to c type char* but it doesn't work.
I'm using visual studio community 2015 on windows 10.
Is their any convenient way for this problem?
As said in the comment - the function .c_str() returns C-compatible string that can be use with DeleteFile and remove.
If that doesn't work, I'd guess that you app is compiled as Unicode , meaning you will have to use std::wstring instead of std::string.
try to combine the two ways:
std::string fileName = "C://file.txt";
std::wstring wFileName(fileName.begin(),fileName.end());
auto res = DeleteFile(wFileName.c_str());
remove however, uses "regular" const char*.
Is it possible to delete N bytes from the end of a binary file in C++ using fstream (or something similar)? I don´t want to read the whole file, cut it and write it again, but since it´s from the end of a file it seems like it shouldn't be such a problem.
I'm not aware of a generic C++ (platform independent) way to do this without writing a new file. However, on POSIX systems (Linux, etc.) you can use the ftruncate() function. On Windows, you can use SetEndOfFile().
This also means you'll need to open the file using the native functions instead of fstream since you need the native descriptor/handle for those functions.
EDIT: If you are able to use the Boost library, it has a resize_file() function in its Filesystem library which would do what you want.
Update:
Now in C++17 you can use resize_file from filesystem
Live on Coliru
In case you want to use Qt, QFile also provides two resize() methods that allow to truncate a file.
I need to do a prototype that involves some serialization in C++. It is a quick'n'dirty prototype, so I don't need to solve the problem generally, provide good error checking, or anything like that. But at the same time, I do need to be able to serialize strings of arbitrary length and with arbitrary charcters.
Are there some best practices for how to whip up a quick data serialization in C++? Normally I'd just have output records into a text file with one record per line, but my strings may have new lines in them.
You could consider using JSON, notably thru JsonCpp. You could also use libs11n, a full fledged, template friendly, C++ serialization framework.
(If you want a C library for Json, consider jansson).
You might also consider using old XDR or ASN1 technology.
For a quick & dirty prototype, I do recommend the JsonCpp library mentioned above. And using JSON in that case is useful, since it is a textual, nearly-human-friendly, format.
Later you could even perhaps consider going to MongoDb which has a Json-like model.
Checkout serialization with boost:
http://www.boost.org/doc/libs/1_51_0/libs/serialization/doc/index.html
Not dirty at all but definitely quick.
If you do not mind binary data, for each string dump a length (cast to a char*) and then the value of the string to file. It is very easy to read back. POD structs can also be dumped directly by casting to a char*
I have code that currently passes around a lot of (sometimes nested) C (or C++ Plain Old Data) structs and arrays.
I would like to convert these to/from google protobufs. I could manually write code that converts between these two formats, but it would be less error prone to auto-generate such code. What is the best way to do this? (This would be easy in a language with enough introspection to iterate over the names of member variables, but this is C++ code we're talking about)
One thing I'm considering is writing python code that parses the C structs and then spits out a .proto file, along with C code that copies from member to member (in either direction) for all of the types, but maybe there is a better way... or maybe there is another IDL that already can generate:
.h file containing all of nested types
.proto file containing equivalents
.c file with functions that copy either direction between the C++ structs that the .proto file generates and the structs defined in the .h file
I could not find a ready solution for this problem, if there is one, please let me know!
If you decide to roll your own in python, the python bindings for gdb might be useful. You could then read the symbol table, find all structs defined in specified file, and iterate all struct members.
Then use <gdbtype>.strip_typedefs() to get the primitive type of each member and translate it to appropriate protobuf type.
This is probably safer then a text parsers as it will handle types that depends on architecture, compiler flags, preprocessor macros, etc.
I guess the code to convert to and from protobuf also could be generated from the struct member to message field relation, but does not sound easy.
Protocol buffers can be built by parsing an ASCII representation using TextFormat. So one option would be to add a method dumpAsciiProtoBuf to each of your structs. The method would dump any simple fields (like strings, bools, etc) and call dumpAsciiProtoBuf recursively on nested structs fields. You would then have to make sure that the concatenated result is a valid ASCII protocol buffer which can be parsed using TextFormat.
Note though that this might have some performance implications (since parsing the ASCII representation could be expensive). However, this would save you the trouble of writing a converter in a different language, so it seems to be a convenient solution.
I would not parse the C source code myself, instead I would use the LibClang to parse C files into an AST and my own AST walker to generate the Protobuf and the transcoders as necessary. Googling for "libclang walk AST" should give something to start with, like ast-walker.cc and ast-dumper.cc from this github repository, for example.
The question brought up is the age old challenge with "C" (and C++) code - No easy (or standard) way to reflect on c "struct" (or classes). Just search stack overflow on C reflection, and you will see lot of unsuccessful attempts. My first advice will be NOT to try to build another solution (in python, etc.).
One simple approach: Consider using gdb ptype to get structured output for you structures, which you can use to create the .proto file. The advantage is that there is no need to handle the full syntax of the C language (#define, line breaks, ...). See How do I show what fields a struct has in GDB?
From the gdb ptype, it's a short trip to protobuf '.proto' file.
You can get similar result from libCLang (and I believe there is comparable gcc plugin, but I can not locate it). However, you will have to write some non-trivial "C" code.
Another approach - will be to use 'swig' (https://www.swig.org), and process the swig xml output (or the -xmlout option) to dump the parse tree into XML. While this approach will require a little bit of digging to locate the structure that are needed, the information in XML format is complete, easy to parse (using whatever XML parser you want - python, perl). If you are brave enough, you can use xslt to generate the output.