C++ equivalent to Fortran Namelist - c++

My question is nearly-identical to C equivalent to Fortran namelist
The key difference is that I'm using C++/17 and wanted to know if there is a more C++ idiomatic manner of solving the issue.

There is no equivalent to Fortran's Namelist in C++. And there is no portable way of achieving this.
If you want to achieve a similar construct, you'd need some general parsing function working with lines on an istream:
It would read lines and ignore anything following a "!";
It would read the name that follows the first "&" to see if it matches the expected name;
It would stop reading when encountering a sole "/" on a line;
It would parse every line in-between, finding the a string with the name of the variable, the "=", and a string with the value on the right of the equal operator, and store the two strings in a std::map<std::string,std::string>.
For ad hoc reading, you'd call the parsing function to transform istream lines into the map. You would then access the map to initialise the variables. An easy and powerful way would be to use a stringstream sst(my_map["variable name"]); sst>>my_variable;
If the Namelist would correspond more or less to a class or a struct X, the idiom would then be to overload a friend istream& operator>> (istream&, X&);. This overloaded extractor would then work as in the ad-hoc case to initialise the member variables.
Of course, I simplify somewhat the algorithm, since you'd also need to cope with errors in the input file: what do you do if an expected variable is missing ? what do you do if the value read is incompatible with the target variable ?
If you are migrating Fortran code to C++ and you must to use Namelist to avoid disruptions, this could be a portable way to go forward.
But if it's just an habit of yours, and the file format is not mandatory, then you may consider using json, with one of the many libraries existing to read and write this format (22 libraries are listed on the linked page). The advantage is that you don't have to reinvent the wheel, you'd be more interopearble with a lot of other languages, and json seems more future-proof.

Related

How can I replicate compile time hex string interpretation at run time!? c++

In my code the following line gives me data that performs the task its meant for:
const char *key = "\xf1`\xf8\a\\\x9cT\x82z\x18\x5\xb9\xbc\x80\xca\x15";
The problem is that it gets converted at compile time according to rules that I don't fully understand. How does "\x" work in a String?
What I'd like to do is to get the same result but from a string exactly like that fed in at run time. I have tried a lot of things and looked for answers but none that match closely enough for me to be able to apply.
I understand that \x denotes a hex number. But I don't know in which form that gets 'baked out' by the compiler (gcc).
What does that ` translate into?
Does the "\a" do something similar to "\x"?
This is indeed provided by the compiler, but this part is not member of the standard library. That means that you are left with 3 ways:
dynamically write a C++ source file containing the string, and writing it on its standard output. Compile it and (providing popen is available) execute it from your main program and read its input. Pretty ugly isn't it...
use the source of an existing compiler, or directly its internal libraries. Clang is probably a good starting point because it has been designed to be modular. But it could require a good amount of work to find where that damned specific point is coded and how to use that...
just mimic what the compiler does, and write your own parser by hand. It is not that hard, and will learn you why tests are useful...
If it was not clear until here, I strongly urge you to use the third way ;-)
If you want to translate "escape" codes in strings that you get as input at run-time then you need to do it yourself, explicitly.
One way is to read the input into one string. Then copy the characters from that source string into a new destination string, one by one. If you see a backslash then you discard it, fetch the next character, and if it's an x you can use e.g. std::stoi to convert the next few characters into its corresponding integer value, and append that number to the destination string (either adding it with std::to_string, or using output string streams and the normal "output" operator <<).

Clean and Efficient String concatenation in C++

I want to join thousands of strings in C++. There is no way that I know from before the size of the possible output string. Currently I join the strings using the '+' operator.
Unfortunately, this process takes a lot of time in my program.
In Java I would use StringJoiner which is much faster. Is there anything similar in C++?
I have read similar things online, and I have also read this question, but it is quite old (9 years old) and I imagine things have changed since.
Consider using std::ostringstream defined in header file sstream.
You add data by using operator <<.
The final string you get by calling str().
You could use a sstringstream (std::sstringstream)
. See the documentation about it on cppref
You could also use boost to concat strings or transform list into strings using boost::algorithm::join but that would be overkill depending on your projet

scanf on an istream object

NOTE: I've seen the post What is the cin analougus of scanf formatted input? before asking the question and the post doesn't solve my problem here. The post seeks for C++-way to do it, but as I mentioned already, it is inconvenient to just use C++-way to do it sometimes and I have clear examples for that.
I am trying to read data from an istream object, and sometimes it is inconvenient to just use C++-style ways such as operator>>, e.g. the data are in special form 123:456 so you have to imbue to make ':' as space (which is very hacky, as opposed to %d:%d in scanf), or 00123 where you want to read as string and convert decimal instead of octal (as opposed to %d in scanf), and possibly many other cases.
The reason I chose istream as interface is because it can be derived and therefore more flexible. For example, we can create in-memory streams, or some customized streams that generated on the fly, etc. C-style FILE*, on the other hand, is very limited, at least in a standard-compliant way, on creating customized streams.
So my questions is, is there a way to do scanf-like data extraction on istream object? I think fscanf internally read character by character from FILE* using fgetc, while istream also provides such interface. So it is possible by just copying and pasting the code of fscanf and replace the FILE* with the istream object, but that's very hacky. Is there a smarter and cleaner way, or is there some existing work on this?
Thanks.
You should never, under any circumstances, use scanf or its relatives for anything, for three reasons:
Many format strings, including for instance all the simple uses of %s, are just as dangerous as gets.
It is almost impossible to recover from malformed input, because scanf does not tell you how far in characters into the input it got when it hit something unexpected.
Numeric overflow triggers undefined behavior: yes, that means scanf is allowed to crash the entire program if a numeric field in the input has too many digits.
Prior to C++11, the C++ specification defined istream formatted input of numbers in terms of scanf, which means that last objection is very likely to apply to them as well! (In C++11 the specification is changed to use strto* instead and to do something predictable if that detects overflow.)
What you should do instead is: read entire lines of input into std::string objects with getline, hand-code logic to split them up into fields (I don't remember off the top of my head what the C++-string equivalent of strsep is, but I'm sure it exists) and then convert numeric strings to machine numbers with the strtol/strtod family of functions.
I cannot emphasize this enough: THE ONLY 100% RELIABLE WAY TO CONVERT STRINGS TO NUMBERS IN C OR C++, unless you are lucky enough to have a C++ runtime that is already C++11-conformant in this regard, IS WITH THE strto* FUNCTIONS, and you must use them correctly:
errno = 0;
result = strtoX(s, &ends, 10); // omit 10 for floats
if (s == ends || *ends || errno)
parse_error();
(The OpenBSD manpages, linked above, explain why you have to do this fairly convoluted thing.)
(If you're clever, you can use ends and some manual logic to skip that colon, instead of strsep.)
I do not recommend you to mix C++ input output and C input output. No that they are really incompatible but they could just plain interoperate wrong.
For example Oracle docs recommend not to mix it http://www.oracle.com/technetwork/articles/servers-storage-dev/mixingcandcpluspluscode-305840.html
But no one stops you from reading data into the buffer and parsing it with standard c functions like sscanf.
...
string curString;
int a, b;
...
std::getline(inputStream, curString);
int sscanfResult == sscanf(curString.cstr(), "%d:%d", &a, &b);
if (2 != sscanfResult)
throw "error";
...
But it won't help in some situations when your stream is just one long contiguous sequence of symbols(like some string turned into memory stream).
Making your own fscanf from scratch or porting(?) the original CRT function actually isn't the worst possible idea. Just make sure you have tested it thoroughly(low level custom char manipulation was always a source of pain in C).
I've never really tried the boost\spirit and such parsing infrastructure could really be an overkill for your project. But boost libraries are usually well tested and designed. You could at least try to use it.
Based on #tmyklebu's comment, I implemented streamScanf which wraps istream as FILE* via fopencookie: https://github.com/likan999/codejam/blob/master/Common/StreamScanf.cpp

Recognize a specific string from a string array without iteration

I'm writing a derivative calculator in C++, and in order to properly perform the derivation operations, I need to parse the input equation at various character indexes along the equation's string.
I'm using isdigit() to parse out the numerical values from the equation and then store them into a separate string array, however now I need to parse out the mathematical symbols from the equation to identify which operation I need to perform.
Is there any way I can modify (overwrite?) isdigit() to recognize custom values from a string array? I'd like to avoid iteration to make my code a little less cluttered, since I'm already going to be using plenty of loops for the rest of this program and I want my code to be easy to follow. Does overwriting and inheritance in C++ work similarly to inheritance in Java (with the exception of multiple inheritance/interfaces)?
Please refrain from posting solutions that are irrelevant to the scope of this question, IE; different approaches to deriving equations in C++, as I've used this approach for some fairly specific reasons.
Thanks
You can use the new powerful C++11 regular expressions library that does almost what ever parsing you want. This way, you'll avoid iterations and code cluttering.
You can just use strchr. (Not everyone will like the macros here, but they do make combining character classes easy.)
#define OPERATOR "+-*/"
#define DIGIT "0123456789"
// Is c an operator
if (strchr(OPERATOR, c)) {
// Yes it is
}
or:
// Is c an operator or a digit?
if (strchr(OPERATOR DIGIT, c)) {
// Yup
}
Overriding and Inheritance works more or less the same as in Java.
You need to define a function as virtual and redefine it in derived class.
I know the "Please refrain from posting...", but I've written a library that does function parsing and derivation.
It is available at https://github.com/B3rn475/MathParseKit
I hope you can find some tips there.

Parse URLs using C-Strings in C++

I'm learning C++ for one of my CS classes, and for our first project I need to parse some URLs using c-strings (i.e. I can't use the C++ String class).
The only way I can think of approaching this is just iterating through (since it's a char[]) and using some switch statements. From someone who is more experienced in C++ - is there a better approach? Could you maybe point me to a good online resource? I haven't found one yet.
Weird that you're not allowed to use C++ language features i.e. C++ strings!
There are some C string functions available in the standard C library.
e.g.
strdup - duplicate a string
strtok - breaking a string into tokens. Beware - this modifies the original string.
strcpy - copying string
strstr - find string in string
strncpy - copy up to n bytes of string
etc
There is a good online reference here with a full list of available c string functions
for searching and finding things.
http://www.cplusplus.com/reference/clibrary/cstring/
You can walk through strings by accessing them like an array if you need to.
e.g.
char* url="http://stackoverflow.com/questions/1370870/c-strings-in-c"
int len = strlen(url);
for (int i = 0; i < len; ++i){
std::cout << url[i];
}
std::cout << endl;
As for actually how to do the parsing, you'll have to work that out on your own. It is an assignment after all.
There are a number of C standard library functions that can help you.
First, look at the C standard library function strtok. This allows you to retrieve parts of a C string separated by certain delimiters. For example, you could tokenize with the delimiter / to get the protocol, domain, and then the file path. You could tokenize the domain with delimiter . to get the subdomain(s), second level domain, and top level domain. Etc.
It's not nearly as powerful as a regular expression parser, which is what you would really want for parsing URLs, but it works on C strings, is part of the C standard library and is probably OK to use in your assignment.
Other C standard library functions that may help:
strstr() Extracts substrings just like std::string::substr()
strspn(), strchr() and strpbrk() Find a character or characters in a string, similar to std::string::find_first_of(), etc.
Edit: A reminder that the proper way to use these functions in C++ is to include <cstring> and use them in the std:: namespace, e.g. std::strtok().
You might want to refer to an open source library that can parse URLs (as a reference for how others have done it -- obviously don't copy and paste it!), such as curl or wget (links are directly to their url parsing files).
I don't know what the requirements are for parsing the URLs,
but if this is CS level it would be appropriate to use (very
simple) BNF and a (very simple) recursive descent parser.
This would make for a more robust solution than direct
iteration, e.g. for malformed URLs.
Very few string functions from the standard C library would
be needed.
You can use C functions like strtok, strchr, strstr etc.
Many of the runtime library functions that have been mentioned work quite well, either in conjunction with or apart from the approach of iterating through the string that you mentioned (which I think is time honored).