 Hey everybody, it's Brian and in this video we're going to cover the humble QString class. I'm actually joking when I say humble. This class is nuts. Okay, so what does this do? It's a string class that provides a Unicode character string, but unlike most string classes in other libraries and frameworks, this has pretty much everything plus the kitchen sink thrown right into it. QString is going to store a string of 16-bit QCares, which is their version, Qt's version of a character or a 16-bit Unicode character. If you don't know what Unicode is, think of like every language, every symbol, every character you've ever seen in your life that's pretty much baked into Unicode. You have all of that power right at your fingertips. So it doesn't matter if your application is in Russian or Chinese or Korean or some offset or you want some special characters, it's all baked in. On top of that, it has a whole ton of functionality baked in because it also works hand in hand with QBiteArray, which we'll cover in depth in another video, but QBiteArray is a class that provides an array of bytes. So now we're talking about byte manipulation. Oh my goodness, and we're not even done. So I'm just going to scroll up. As fast as my little mouse will go, you see all these functions? You see them all? We're still scrolling. Yes, literally. We're still going. There we go. There we go. Come on, virtual machine. You can do it. And we're at the top. Oh my gosh. So basically, if you haven't guessed, this class is huge and there's a lot of functionality baked in here. We're not going to cover everything, but we're going to hit the highlights from creating to comparing and searching, modifying and parsing and how to do very simple things. Let's dive in and take a look. We have to start somewhere. So let's start at the beginning. How do we actually create a queue string? Well, there's a couple of different ways, very similar, but different. So I'm going to say queue string, we're going to just work with the constructor here. I'm going to say the line, hello world. And you notice there is 11 different ways to construct this. So there's a lot going on here. You have a multitude of options at your fingertips for every use case you can possibly think of. And I'm going to say queue info. And then we can just pump that out directly onto the queue info, which actually pushes out to the standard output. So let's just say run and demonstrate that ridiculously simple. Don't let the simplicity fool you. This thing is crazy powerful. So I'm going to say queue string, and we're just going to demonstrate another way. Name I'm not going to use the constructor instead, going to assign it. And I'm going to just give it my name, afraid to type in whatever your name is. And then again, we're just going to queue info this out works exactly the same way. Same manner. So it doesn't matter which way you want to work with it, it just works. Now, special note, when you're using queue info or queue debug or anything else, it's going to have the quotes around it, those double quotes that signifies this is a queue string in memory. More modern languages and frameworks have what are called arguments where you can actually use arguments in the construction of the stringing. Well, queue has that too. So I'm going to go ahead and demonstrate that. So I'm going to say int POS, and I'm just going to choose like a random number 504. And then int max, I'm going to choose another random number. And let's go ahead and demonstrate how to use the args. So I'm going to say queue string status equal. Now I want to actually construct a queue string. Now let's go ahead and enter in our character some say processing file. I'm just kind of making this up on the fly percent one. Notice the special encoding here we're using the percent sign and one of and then percent sign and then two. Yes, you may have guessed this is just simply incrementing so we can go one, two, three, four, five, six all the way up to however long we want. But now what we're going to do is tell cute to switch that out or replace that text. I'm going to say arg, I always like that word arg sounds like a pirate, but what we're going to do is say we want to use the POS variable short for position and it's in the first spot here. So it's going to replace this one of and now we want to replace this guy. So we're just going to chain this and say arg again, max. And you can take that out and do pretty much whatever you wanted to with it. You can make it super ridiculous. I'm going to say queue info, say run and let's go ahead and demonstrate that makes it just ridiculously simple to work with. One question I'm often asked, especially by newbies, is how do you get each and every individual character in a string? Now, what are we talking about here? So a string is actually a bunch of characters. So like the letter H, E, L, L, O, each one of those are individual queue characters. So if you just pop open the documentation, if you have no idea how I did that, I just highlight a queue string and press F1 on the keyboard takes you right to the built in help system. You can see, as we go to more, queue string stores a string of 16-bit queue cares. So each one of these under the hood is a queue care. If you click on queue cares documentation, you see this is an entire class in itself and you can do a whole lot of manipulation. Vastly out of scope of what we're going to do in this video, but I wanted you to be aware of what we're working with, which is simply a queue care. So how do we get each and every one of those? It's actually pretty simple. So I'm going to use the humble for loop, I'm going to say four and I equals zero because this is a zero based index. If you've done any programming, you should be very, very familiar with zero based. Now I'm going to reuse this guy right here or pretty much the rest of this video just because we've got this nice little hello world. So I'm going to grab him line and then it's just, this is something I really love about queue. It's very, very intuitive. We want to know the length of this. So I'm going to type LEN and there you go. It's going to give us the length. There's something to be said about being super intuitive. It just really cuts down on trying to figure things out. So now that we can get each position, we want to get each character. So I'm going to say queue care and we want to know the position at which returns a queue care. Again, very intuitive, very easy to understand. We don't have to have a four hour conversation about memory offsets and all that other fun stuff. And let's just go ahead and print that out. So what this allows you to do is get every single character as a queue care, which is a 16 bit Unicode character under the hood. Let's go ahead and run and demonstrate this. And here we go. You notice that the character has a single quote. So if you're ever in console land and you see double quote, it's a queue string single quote is a character. One of the more challenging aspects of working with strings is well comparing and searching. Cue makes it very simple. We're going to cover the basics here. So I'm going to say queue info. So we're going to compare and let's go ahead and let's figure out what we want to compare. So far, all this thing says is hello world. So I want to say line dot compare. And let's compare this to hello world. But notice the case sensitivity here. This is actually pretty important, not just in C plus plus land, but also in string manipulation land. This is all lowercase. If we go up here, this is upper and then lower, upper and then lower. So these simply won't match. They're not bit for bit compatible. All right. So hello world in lowercase. So all we have to do is say cute. And we want the case sensitivity again, very intuitive. You can see right here what we need. But in case you want to see all of that, you can choose insensitive or sensitive. So insensitive in Norse completely ignores case sensitivity. And that's what we want for this specific example. So I just want to say, hey, does it contain hello world? We're just comparing two strings together. Go ahead and save run. See what that looks like. And compare zero. Now, if you're curious what the zero was, if you mouse over this, you notice it's returning an int, not a bool. So you can dive into the documentation if you really want to. But basically compares S one or string one with S two or string two and returns an integer less than equal to or greater than zero. If S one, the first string is less than equal to or greater than S two or string two. Sounds super confusing. But basically we're talking about sorting. That's right. You use this in larger operations, more complex things to determine the position in an order. So that's how sorting works. Now notice if I change this from case insensitive to case sensitive, let's save run. Let's see if it changes from zero. Sure enough, it's now negative 32, meaning it is not even remotely close to what the original is. Very simple, but very complex to understand that compare is not giving you a bool. It's giving you an int when you're comparing two strings in their position relative to each other. All right, now, if that seems super confusing, don't worry, the rest of this is well fairly straightforward. So we're going to just copy this. And I want to see if it starts with a specific word. So I'm going to say line and then starts with. Very simple. Now you notice right off the bat, case sensitive is the default. So if you ever want case insensitive, you specifically have to request it. So I want to see if it starts with hello. Notice the case sensitivity doesn't match. So of course, we have to go into the case sensitivity and choose case insensitive. We can abbreviate all that just by getting rid of that case sensitivity. Now let's see if it starts with the word hello or case insensitive. And sure enough, true. If I flip that to case sensitive, then it will be false because this is a lower case age, not an uppercase. Let's go ahead and grab this. We're going to do virtually the same thing. I'm going to say ins. And let's go ahead and say world. And we want the ends with. Notice as we're typing in this little dialogue, it's suggesting things. So we can have like an end where you can get the end iterator. You can append, you can see and you can constant all these things. Again, this is a huge class. So some of that stuff may not be what you want. Let's see if this ends with world. Sure enough, it does because we have that case insensitivity set. Let's just grab this. I love copy and paste. It's like the best thing in the whole world. And we're going to say contains. And we want to know if this just simply contains something. And that will actually return a bowl. So a lot of people choose compare thinking it's going to tell them. And it's actually not compare is used for sorting, contains is used for validation that it's actually there. So we want to see if world is in there. And I'm going to switch this to the default. And let's see what happens here. Notice how it says false, but we know that it does end with world. Again, that's that case sensitivity. I can't drive that home enough. Case sensitivity is usually the cause of why things magically stop working in your code. So when in doubt, always look at the sensitivity level and what you're actually asking Qt to do. From there, let's just find the actual position here. So I'm going to grab this. And I want to say index. So remember, a string is just, well, a list of Q characters. So we want to know the position or the index of something. So I'm going to say line dot index of. And you can also get the last index of if you're looking for the last occurrence of something. But we're going to do index of. And then, of course, you've got five options to choose from. So this gets a little confusing. But let's say we want to know where the word world is. Save run. And it is at position six. Remember, this is a zero-based index. So zero, one, two, three, four, five, six. That space does count. So world starts at position six or index six. That's how you find the position of something inside of a larger string. Now we're going to talk about modifying and parsing. And this can get, well, a little bit involved. So I'm going to go kind of slow it first and then really speed this up through the power of copy and paste. So let's look at what's called an escape sequence. So I'm going to say line dot append. And we're going to just add to this. And we want to add a slash r slash n. Notice what we're doing there. Slash r slash n. What is this right here? Well, it's an escape sequence. It's built right into C++. If you want a special character of some kind, you have to use a slash in front of it. So why would you want to do this? Well, r and n is carriage return line feed. So this is a new line. And again, this gets really in-depth. But most of the world uses a slash n. However, Windows uses a slash r and a slash n. So you've got to be a little bit careful there. But you can do some other things as well. So for example, I'm going to just get rid of this. I'm going to say today Bob said hello, wife. Notice what's happening. If you look at the screen, it stopped turning green. And it is now black. Because C++ doesn't know what's going on. I forget my horrible spelling. But you see what's going on here is now it's very confused as to what we're trying to do. And this is exactly why escape sequences are there. We're going to put a double quote in there. So to do that, we just simply put a slash in front of it. And a slash in front of that one. And then it magically starts fixing itself once we end the string correctly. See? Now, if we go ahead and run this, actually, let's queue info first. I'm going to just put escape and then line. Let's run this and see what this looks like here. This is the other fundamental point I want to drive home. Hello, world. Today, Bob said slash, quote, hello, wife, slash, quote. How are you? You notice it prints the escape sequence. So if you are expecting just the double quote, it's not going to work that way. There's a way to make that work around. But we're not going to cover it in this video. We'll cover it later on in the series. I just want you to be aware. You will see the escape sequences. So now that you understand that fundamental problem, let's do this. I'll say line, slash, slash, and how are you? One thing you need to really understand here is what we're doing. We are modifying this string directly using a pen. So we're just adding to it. Save, run, and let's see what that looks like. Exactly what you think it would. Hello, world. New line. How are you? And you see that escape sequence in there. Now, escape sequences exist. Well, solely for your benefit, to make it easier to do things like add in a backslash, a backspace, character, turn line, feed, tabs, or any special character sequence that you want, including Unicode characters. And it can get kind of nuts, as you can see on the screen, how you have to start working with the hex codes of the numbers. Fortunately, a lot of that's already baked into Qt, so you don't really have to worry about that too much. So for example, if I say line.append, and we are going to, again, carriage return line feed, but we want to add in some HTML. If you don't know what HTML is, it is hypertext markup language, or it's what they used to build web pages with, and it has a special syntax. So for example, I'm going to italicize some tests, and say this, and then unitalicize that text is HTML, and then let's add in the HTML version of a hard return. But look at the characters on the screen. We're using less than, greater than, you guessed it, this could actually cause problems if you try to read this as a string and accidentally interpret it as computer code. You're actually doing things. That is actually the basic groundwork. It gets way more complex, but it's the basic premise of some cyber attacks. So to circumvent that, you never want to put HTML encoding in, say, a database. Instead, you'll want to escape it, just like we did up here, but it's already built in. So I'm going to say line.to HTML escaped. So we don't have to go out and look up the code for each one of these special symbols. We can just say line to HTML escaped. Let's say run and see what that looks like. Ta-da, hello world, new line. How are you, new line? And then we have all the HTML encoding done for us, so we don't have to worry about it. That is extremely cool. The main takeaway here is that there's a lot of functionality baked right into this. And because it's so functional and it's so versatile, this is where I'm going to speed things up just a little bit through the magic of copy and paste. So let's say we wanted to replace something. It's just line.replace and then you can use a character or a string doesn't matter and just simply replace it and it will print out the replaced character. Let's save and run just for demonstration on that. And then you see how we have replaced our question mark with this exclamation mark. And that, again, it's just the tip of the iceberg. You can do things like this, where you have the uppercase, the lowercase or the mid. Now mid takes a little bit of explanation. Mid is shorthand for middle. So you want to get some text middle between the starting and ending points. So I just have three to five. Remember a string is a sequence of characters. So if we start at three and end at five, let's see what that looks like. Mid is going to be LO world. So starting at three, zero, one, two, three, LO, space, W, O and we're stopping there. So that is how you would get something in between like that. It's extremely simple and extremely powerful, especially if you combine that with index of. So let's say you wanted to get to the index of world, then you would just put that index right here. Again, that is just really, really fundamental to both computer programming languages. And I'm assuming you've worked with some C++ if you're watching this video series. Now let's look at how you would get each individual line here. So I'm gonna say Q string list. And we're gonna cover Q string list in depth later on. And this is one of the problems with teaching people programming languages, especially C++ is everything kinda uses everything. So you gotta touch on a little bit everything. So we're going to take our Q string and split it. Now split will create a Q string list, which is just a list of Q strings. We need to tell it what to split on. When you think of the word split, think of like splitting wood. You're gonna take an ax and literally chop it. So I want to chop it at that new line character. And then I wanna say for each Q string item in our list. But we have a fundamental problem here. You notice what we've been using is slash r slash n because we've been trying to accommodate windows on top of Linux and everything else in the world. So we're still gonna have that trailing slash r. Let's go ahead and demonstrate some secure info item. And let's go ahead and say, they run and let's see what that looks like here. Okay, so now you see how we have that trailing slash r here. That's not good because it's still gonna put in a hard return. So what we can do is simply trim that out. And what trim does is remove white space characters. So what is a white space character? Well, spaces and returns and tabs and things of that nature. Things that don't print out on the screen is what it's gonna get rid of. See, returns a string that has white space removed from the start and the end. I've just got it doing everything, save and run. And let's see what that looks like. Now the slash r's are out of there. One of the more challenging things of working with computer programming is, well, conversion. And let's just do a simple demonstration. So I'm gonna say SDD and we want C out. Okay, I'm sure you've probably tried to do this before. I'm gonna say SDD and let's go ahead and print our Q string out. Notice what happens in valid operands to binary expression. Meaning the standard library C out has not a clue what the Q string actually is or how to display it. That's unfortunate, but your buddy here is you just say dot to and that gives you pretty much everything possible that you can convert it to. Now, we want to go to the standard library. So I'm gonna say to STD. And before I even finish it, we have some options, string, UTF 16, 32 or W. So I'm gonna do just a standard string. And yes, because somebody out there is gonna ask, you can, even though I don't like doing it, use the standard library and L. Now, if you're wondering why I don't like standard library and L is because it has betrayed me in the past specifically for that Windows versus Unix debacle that we talked about, but you can do it. The other major takeaway here is we have to add that space because Q info and Q debug and all the things we've been working with have done that automatically for us. Let's say run and see what that looks like. So sure enough, STD and then there's the space that we put in. It also breaks it into the individual lines, means it's now processing all of these escape sequences. So those are some fundamental differences here, but just shows you very simply how you can convert a Q string to a standard string. Now, the other major caveat here is that you can work directly with Q byte array, which is more advanced. We're gonna talk about it in another video. You may be wondering, why does he keep saying we're gonna talk about something in another video? I'm trying to keep these videos kind of self-contained. Otherwise, you're gonna watch a 30 hour video on string processing and it just would be maddening for you and me. So we're gonna say line dot to UTF-8 if you need something specifically in UTF-8 format. But you notice what UTF-8 returns is a Q byte array. Ooh, okay, so let's look at Q byte array. Just kinda highlight that F1. So Q byte array class provides an array of bytes. That is used for, you guessed it, byte manipulation. So you can actually at the byte level start manipulating data. This is extremely cool, but also why we're going to break that off into its own video because it does get a little complex. Little copy paste action here and we're just gonna show you how you can do, like for example, base 64 encoding. You don't need some special library. You can just say dot to UTF-8.2 And now we're actually working with Q byte array, not Q string, base 64. And then you can do the options. And in the video where I covered Q byte array, we're gonna talk about how to convert back and forth between plain text and base 64 and things of that nature. And then you could do something like, let's say you wanted not hacks, hacks, there we go. And then you can add in your care separators and all that fun stuff. So the reason why I added this in this video is people will often tell me, well, I converted a Q string to base 64. And I'm like, no, you didn't, you converted a Q string to a Q byte array, format in UTF-8 to a base 64. Just understand what's going on there. You're jumping data types. All right, let's save, run and see what that looks like here. And sure enough, here is our UTF-8. Here is our base 64 encoded and here is our hex encoded. All right, to wrap this video up, I think it's important to mention that Q string is not a Q object. I see all the time people will treat Q string like a Q object and then wonder why their code simply doesn't work. To demonstrate that, remember, Q objects cannot be copied, but we're just going to do this. What are we doing there? We're making a copy that is a big no-no for Q objects. We're gonna say Q-info and we're just gonna pump that data out to Q-info. So yes, we are making a copy and a lot of your old school C++ programmers are yelling at your screen because copies are extremely slow and the same rules apply for Q string. If you're making a copy and you have a massive Q string, you are now going to gobble up a bunch of memory. So there are simple ways around that, passing the address of our pointer, but I'm just simply demonstrating that this is not a Q object and we can copy it to our heart's contents. And it just magically works the way you would expect it to. Ta-da, there is our copy in all of its glory. I hope you enjoyed this video. You can find the source code out on github.com. If you need additional help, myself and thousands of other developers are hanging out in the Voidromes Facebook group. This is a large group with lots of developers and we talk about everything technology related, not just the technology that you just watched. And if you want official training, I do develop courses out on udemy.com. This is official classroom style training. If you go out there and the course you're looking for is just simply not there, drop me a note, I'm either working on it or I will actually develop it. I will put a link down below for all three of those. And as always, help me help you. Smash that like and subscribe button. The more popular these videos become, the more I'll create and publish out on YouTube. Thank you for watching.