|
Apologies for the shouting but this is important.
When answering a question please:
- Read the question carefully
- Understand that English isn't everyone's first language so be lenient of bad spelling and grammar
- If a question is poorly phrased then either ask for clarification, ignore it, or mark it down. Insults are not welcome
- If the question is inappropriate then click the 'vote to remove message' button
Insults, slap-downs and sarcasm aren't welcome. Let's work to help developers, not make them feel stupid.
cheers,
Chris Maunder
The Code Project Co-founder
Microsoft C++ MVP
|
|
|
|
|
For those new to message boards please try to follow a few simple rules when posting your question.- Choose the correct forum for your message. Posting a VB.NET question in the C++ forum will end in tears.
- Be specific! Don't ask "can someone send me the code to create an application that does 'X'. Pinpoint exactly what it is you need help with.
- Keep the subject line brief, but descriptive. eg "File Serialization problem"
- Keep the question as brief as possible. If you have to include code, include the smallest snippet of code you can.
- Be careful when including code that you haven't made a typo. Typing mistakes can become the focal point instead of the actual question you asked.
- Do not remove or empty a message if others have replied. Keep the thread intact and available for others to search and read. If your problem was answered then edit your message and add "[Solved]" to the subject line of the original post, and cast an approval vote to the one or several answers that really helped you.
- If you are posting source code with your question, place it inside <pre></pre> tags. We advise you also check the "Encode HTML tags when pasting" checkbox before pasting anything inside the PRE block, and make sure "Ignore HTML tags in this message" check box is unchecked.
- Be courteous and DON'T SHOUT. Everyone here helps because they enjoy helping others, not because it's their job.
- Please do not post links to your question in one forum from another, unrelated forum (such as the lounge). It will be deleted.
- Do not be abusive, offensive, inappropriate or harass anyone on the boards. Doing so will get you kicked off and banned. Play nice.
- If you have a school or university assignment, assume that your teacher or lecturer is also reading these forums.
- No advertising or soliciting.
- We reserve the right to move your posts to a more appropriate forum or to delete anything deemed inappropriate or illegal.
cheers,
Chris Maunder
The Code Project Co-founder
Microsoft C++ MVP
|
|
|
|
|
I am looking for ANY document actually tells HOW the build regular expression .
( Regular expression for dummies...)
Ideally something converting verbal description to regular expression, in any fashion.
There are few tools likes this
<a href="https://regexr.com/">RegExr: Learn, Build, & Test RegEx</a>[<a href="https://regexr.com/" target="_blank" title="New Window">^</a>]
BUT they usually take a SIMPLE example and do not tell WHY it works...
Here is my task description , in my best simple English:
Retrieve first word in line.
Here is a WORKING regular expression which does not return opinions , as humans do,
just fulfills the task.
"\\w+"
Again , AFTER RTFM this is my English interpretation / translation description of the expression
Retrieve, "they" call it "match" , first string of ASCII characters from (multiple)
data lines.
The "w" (lower case w ) "matches" ANY (count of consecutive +) ASCII characters - it does not match ASCII control characters, hence in this case FIRST "space" terminates the "+".
I can use my limited knowledge HOW to construct regular expression and change the task:
Retrieve, "they" call it "match" , first string of ASCII characters from (multiple)
data lines which has ":" as a last "character" .
and this expression fulfills the task
"\\w+:"
Now I won't even attempt to convert that to English....I know why "w+" finds (stops) matching , but how it "knows" that ":" is its terminating character now?
OK, I appreciate you have read so far, and in case you really expected the question (?) -
help me to construct NEW expression to fill this , modified , task
<pre>Retrieve, "they" call it "match" , first string of ASCII characters from (multiple)
data lines which has ":" as a last "character" .
The task extension is to retrieve / match the above from THE ENTIRE , ALL lines of text.
NOT just first match found, search all ALL
PS
I do understand that the actual syntax of the regular expression varies
with "engine used" , and yes I can deal with that.
Thanks appreciate your reply.
|
|
|
|
|
I'm trying to straighten out some pointer "arithmetic" in some existing code. The expressions themselves are overly ambiguous to say the least. In part of my readings, I've come across the "auto" keyword where the compiler deduces what type I need. At least that's what I got from all of the verbiage.
This seems a) dangerous and b) adds another level of mental indirection to what you are trying to accomplish. To me, software needs to be very clear and explicit in what data you are working with and what you intend to do with it. A lot of the "here is how auto will help you" descriptions justify it by saving typing when trying to make use of other classes, templates and the like. It feels like the C++ committee came up with a feature A then added feature B to make using A easier. I'm now doing battle with lambda expressions - another story.
So, in your code - do you make extensive use of auto, and how does it help you?
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
charlieg wrote: do you make extensive use of auto, Not "extensive" but I use it frequently. In some cases there is no way to go around it (when you have a lambda closure for instance), in other cases it is just convenient (like long container iterator types), and in a few cases it is surprisingly useful. One such case is in combination with IntelliSense when I have doubts about the final type of an expression. I do something like:
auto var = and, when I hoover over var , IntelliSense will obligingly tell me what the compiler thinks the variable type is. I know it's a bit silly (and maybe lazy) but hey, it helps me.
How I learned to stop worrying and start loving the auto
Mircea
modified 19-May-24 9:31am.
|
|
|
|
|
Mircea Neacsu wrote: IntelliSense will obligingly tell me that the compiler thinks it the variable type. I think this is the best use for auto in C++ or var in C#.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
I haven't touched C/C++ in a long time, but C# has the similar var. I used to use it until I recognized how unreadable it made code. It forces you to know more than you really need to know and is, frankly, a lazy way to write code.
I do still use it but only in the lazy way of using Intellisense to figure out what the actual type is supposed to be and give me the option of replacing var with the actual type. It has recently come in handy last week when using an API client library generated by Swagger code gen and the holy-sh*t-those-are-long-class-names it generated. The longest is 86 characters long, and average about 40-45. I'm not typing those. I have to get the code working this week, not next year.
|
|
|
|
|
I use it.
Suppose you have
unordered_map<string, int> um{ {"foo", 1}, {"goo", 2}, {"boo",42}};
I find
for (const auto & p : um)
{
cout << p.first << ", " << p.second << "\n";
}
'somewhat simpler' when compared to
for (const pair<string, int> & p : um)
{
cout << p.first << ", " << p.second << "\n";
}
Maybe I am used to it.
"In testa che avete, Signor di Ceprano?"
-- Rigoletto
|
|
|
|
|
The only time I don't use auto is to override the type that the compiler would deduce. That's very rare, usually with the size of a numeric. auto is almost always a type returned by a function, or maybe the type of a class member, so there's nothing "dangerous" about it in those situations. Someone reading the code needs to be familiar with the functions and classes being used, or they're fooling themselves as to their level of understanding.
|
|
|
|
|
I use auto as much as I can.
I will still use types for POD.
I also use variable names that makes sense so that I know what type the variable should be (obviously not hungarian reverse or not notation)
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
POD?
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
Plain Old Data.
usually simple types like int, char, float...
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
It appears to me that you may be doing much programming that doesn't really fit into a strong, static typing world. Maybe a dynamically typed language, with any variable having the type of its value (at any time) would suit your problems better.
I love the strictness of strong static typing. It makes it possible for the compiler to give me far more detailed and to-the-point error messages and warnings. When reading the code, it provides more information, making it simpler to comprehend the code.
There are situations where auto/var is required, e.g. in database operations; I am not objecting to using in in such cases. In most cases, you can extract the values to strongly typed variables. I do not leave them in untyped variables for long.
Corollary, I try to avoid deep subclass nesting. Choosing between having to inspect 4-6 superclass definitions to find the definition of a field (hopefully with a comment explaining its use) or extending a superclass with a field that for some instances are left unused, I definitely prefer the latter. (I have many times seen subclasses created for adding a single field - even with several sibling classes adding the same single field!)
Religious freedom is the freedom to say that two plus two make five.
|
|
|
|
|
I think you're confusing things up.
C++ is still strongly typed even when you use auto.
when I declare a variable with auto, it will be typed accordingly and I cannot change the type.
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
Maximilien wrote: when I declare a variable with auto, it will be typed accordingly and I cannot change the type.
Err...in C++?
Rather certain you can in fact change the type. Not generally a good idea but one can certainly do it.
char* s = ....;
int* p = (int*)s;
I have seen very limited situations where it provided value.
|
|
|
|
|
That's a C -like dirty hack. Useful at times.
There are also union s and variant s. Nonetheless C++ remains a strong typed programming language.
"In testa che avete, Signor di Ceprano?"
-- Rigoletto
|
|
|
|
|
That does not change anything, it's a cast. It merely tells the compiler "even though s is a char* , for this statement only, pretend it points to an int .
|
|
|
|
|
I believe that in terms of the semantic functionality that the type is now changed.
If you have a method that takes the second type, the compiler will complain if you pass the first but not the second.
I have in fact used a char array as a integer before. At least in that case there was no definable difference between the two.
So exactly, in terms of the language, how does the cast not make it into a different type?
|
|
|
|
|
Well, think of it this way: What is a type? What do we mean when we declare the type of a variable?
We're declaring how we want the compiler to treat the data value. It's not an existential property of the variable, it's the way that we interpret the value.
So:
char* b = "ABCD"; And:
int* a = (int*)b; We're declaring an action, not a property of the variable.
The difficult we do right away...
...the impossible takes slightly longer.
modified yesterday.
|
|
|
|
|
A char* is in reality just an index into a portion of memory. So at the machine level it has no type-ness, it can be used to address anything from a byte to a quadword. But as far as the language is concerned it only ever points to a character. When you use a cast the compiler does what can be done at machine level, but the object itself is still a char* , and any attempt to use it in any other way will raise a compiler error. If you have something like the following:
int somefunction(int* pi, int count)
{
int sum = 0;
for (int i = 0; i < count; ++i)
{
sum += *pi;
}
return sum;
}
char* ci = "Foobar";
int total = somefunction((int*)ci, strlen(ci));
The type of ci does not change at all, it is just that its value is passed to somefunction , as the cast allows you to break or ignore the rules of the language. And the result of calling that function may, or may not, make sense.
|
|
|
|
|
In your example, it should be noted that if the target CPU requires that an int have, for example, an even byte alignment, you may get an exception when trying to dereference the int pointer.
I also wondered if you meant to increment the int pointer inside the loop, in which case, at some point you would invoke undefined behavior. Unless, of course, sizeof(int) == sizeof(char) . Which isn't impossible, but I don't know of any system where that might be true. Maybe a 6502 or other 8bit system?
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
|
|
|
|
|
k5054 wrote: if the target CPU ... True, but hardly relevant to the point I was trying to make.
And yes, I should have incremented the integer pointer - writing (poor) code in a hurry.
|
|
|
|
|
In my world - close to hardware - it's important to know and understand the type. Sure, if I'm using a modern IDE with Intellisense (only one comes to mind) auto might help. But, because of the proximity to hardware, we really don't use complex C++ types. Shoot, the last time I tried to use a C++ map, it was 10x slower than a simple linear search loop. I did not believe it at first...
But getting back to using auto with it's intellisense interaction, intellisense does it's thing for plain and complex types as well. I'm not sure what the point it (other than reduced typing).
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
As already mentioned in several answers, auto keyword doesn't make C++ code less strong-typed or type-safe. So, using auto is individual preference. In some cases (such as templates, lambda) there is no other choice.
When auto is optional, I always use it for complicated types, like container iterators. I also like auto in container enumeration code:
for(const auto& x: my_container)
{
}
As for local variables, it depends. Sometimes we want the variable to have another type. If the variable must have the same type, as expression, auto can help, when the code is changed:
std::vector<short> v;
short n = v[0];
Consider the situation, when we change the container type to int:
std::vector<int> v;
short n1 = v[0]; auto n2 = v[0]; decltype(v)::value_type n3 = v[0];
I find myself using auto more and more. Sometimes, when I want to see exactly, what I am doing, I prefer to use an explicit type.
|
|
|
|
|
I clearly have a limited understanding of C++. I admittedly come from a C background, and I have embraced the general concepts of C++ (most of the 4 pillars). But I'm going to be honest here
It seems to me that auto is fixing or making easier to use some of the more spurious features of C++. Just a general thought, but it gets back to my original post/question. For example, your comment: "decltype(v)::value_type n3 = v[0];" means absolutely nothing to me. I'm at the level of wtf?
So, I went out to the internet and read: "Inspects the declared type of an entity or the type and value category of an expression." for decltype. I still don't know what that means. Are we off in the top 0.01% land of coding? It's okay, I found my niche long ago, but seriously, it feels like so many special features have been added that only apply to the religious fanatics of code land.
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|