1 00:00:05,700 --> 00:00:08,400 In this video, we'll talk about stringstreams. 2 00:00:09,200 --> 00:00:14,080 Stringstreams allow us to use in-memory string objects as streams. 3 00:00:14,480 --> 00:00:18,480 That means that we can read and write data to strings in the same way that we can 4 00:00:18,480 --> 00:00:20,080 read and write data to any stream. 5 00:00:20,840 --> 00:00:24,840 This is a very powerful concept, and it's very useful for data validation. 6 00:00:25,500 --> 00:00:28,800 It's also very easy to use since we already know how to use streams. 7 00:00:32,800 --> 00:00:36,400 There are three classes that we can use when using stringstreams. 8 00:00:36,800 --> 00:00:40,460 The stringstream class allows us to read and write from stringstreams. 9 00:00:41,010 --> 00:00:45,210 The istringstream class allows us to read from stringstreams. 10 00:00:45,210 --> 00:00:49,410 And the ostreamstring class allows us to write to stringstreams. 11 00:00:49,910 --> 00:00:52,710 For all of these, we must include the sstream header file. 12 00:00:53,310 --> 00:00:55,910 The rest is very much like using any other stream. 13 00:00:55,910 --> 00:01:00,210 First, we declare a stringstream object of one of the three types that I mentioned, 14 00:01:00,210 --> 00:01:01,870 then we connect it to a string. 15 00:01:01,870 --> 00:01:06,230 That's it. Now we can read or write to that stringstream using formatted io and 16 00:01:06,230 --> 00:01:07,830 stream manipulators if we wish. 17 00:01:09,390 --> 00:01:12,670 Let's see an example of how we could read from a stringstream. 18 00:01:13,220 --> 00:01:17,470 Suppose we have three variables declared: an integer named num, a double name total 19 00:01:17,470 --> 00:01:18,970 and a string called name. 20 00:01:19,470 --> 00:01:23,370 Now suppose that we have string info with the string Moe 100, 21 00:01:23,370 --> 00:01:26,030 1234.5 as its contents. 22 00:01:27,030 --> 00:01:30,800 Remember, we did this example in this section and that same data was in a file. 23 00:01:30,800 --> 00:01:32,800 Well, now it's in memory in a string. 24 00:01:33,590 --> 00:01:37,790 We can create an istringstream object. We'll call it iss 25 00:01:38,090 --> 00:01:40,290 and connect it to the info string. 26 00:01:40,690 --> 00:01:43,350 So now we can read from the stringstream. 27 00:01:44,340 --> 00:01:48,840 Now we can use the stream extraction operator to extract those data from the string. 28 00:01:48,840 --> 00:01:52,500 That's pretty cool. I'm sure you can see lots of applications for this, 29 00:01:52,500 --> 00:01:54,500 especially in data validation. 30 00:01:56,800 --> 00:01:59,500 So now let's see how we can write data to a stringstream. 31 00:02:00,200 --> 00:02:03,850 In this case, we've initialized our variables: num total and name 32 00:02:03,850 --> 00:02:07,840 to 100, 1234.5 and Moe, respectively. 33 00:02:08,500 --> 00:02:12,000 We can create an ostringstream object named oss, 34 00:02:12,000 --> 00:02:14,000 and we can write to the stream object. 35 00:02:14,660 --> 00:02:18,260 In this case, I'm inserting the three values onto the stringstream. 36 00:02:18,920 --> 00:02:23,420 Remember, we can use any stream manipulators to format that data that we're putting on the stream. 37 00:02:24,220 --> 00:02:28,200 So now how do we display the string that we just formatted. 38 00:02:28,400 --> 00:02:33,390 Notice that notice in this case we didn't connect the ostringstream to any string object, 39 00:02:33,690 --> 00:02:37,840 we could have just like we did with the istringstream example in the previous slide. 40 00:02:38,390 --> 00:02:41,740 The stringstream has a string buffer that it uses internally, 41 00:02:41,740 --> 00:02:42,840 and we can use that. 42 00:02:43,740 --> 00:02:45,740 So if we want to display that string, all we have 43 00:02:45,740 --> 00:02:48,740 to do is call the stringstreams.str method. 44 00:02:50,400 --> 00:02:53,700 In this last example, we'll do some basic data validation. 45 00:02:54,690 --> 00:02:57,990 The idea is that I want to ask the user to enter an integer. 46 00:02:58,490 --> 00:03:01,590 The idea is that I want to ask the user to enter an integer. 47 00:03:01,590 --> 00:03:05,850 And I want to be sure that they do enter an integer, not some invalid data like a name. 48 00:03:06,550 --> 00:03:08,750 So we have a string named input, 49 00:03:08,750 --> 00:03:12,050 and we read the user's input into that string. 50 00:03:12,710 --> 00:03:16,210 We don't read it into an integer. Again, we read it into a string. 51 00:03:16,980 --> 00:03:21,580 Then what we want to do is to try to convert that string to an integer if possible. 52 00:03:22,460 --> 00:03:26,660 There are many ways to accomplish this in c++, some are better than others. 53 00:03:26,660 --> 00:03:29,020 Let's do it with a string stream it's pretty easy. 54 00:03:29,820 --> 00:03:33,920 What we can do is we can create a string stream object, we'll call it ss. 55 00:03:34,170 --> 00:03:38,370 And we can connect it to the input string that the user just entered. 56 00:03:39,170 --> 00:03:42,730 Then we can try to extract an integer from ss 57 00:03:42,730 --> 00:03:44,090 and store it in value. 58 00:03:44,450 --> 00:03:47,250 We can do that using the stream extraction operator. 59 00:03:47,250 --> 00:03:49,450 If the extraction was successful 60 00:03:49,450 --> 00:03:52,650 that means that we have a valid integer stored in value. 61 00:03:52,650 --> 00:03:55,010 If the extraction was not successful, 62 00:03:55,010 --> 00:03:57,160 we know that the user didn't enter an integer, 63 00:03:57,160 --> 00:03:59,360 and we can ask them to enter the number again 64 00:03:59,360 --> 00:04:01,760 or we can do whatever else makes sense in our program. 65 00:04:02,360 --> 00:04:05,860 So now let's head over to the IDE, and we'll see these examples, 66 00:04:05,860 --> 00:04:08,660 and we'll do a more complete data validation example as well. 67 00:04:09,660 --> 00:04:14,560 Okay. So I'm in the IDE. I'm in the section 19 workspace in the stringstream project. 68 00:04:15,060 --> 00:04:18,220 And what we'll do here is we'll do a few examples using stringstreams. 69 00:04:18,220 --> 00:04:19,779 We'll read from them, we'll write from them. 70 00:04:19,779 --> 00:04:22,660 And then I'll show you a little bit better data validation example 71 00:04:22,660 --> 00:04:24,660 than the one in this slide, a little more complete. 72 00:04:25,060 --> 00:04:28,360 So what we're doing here we've got some includes, and we're including limits. 73 00:04:28,360 --> 00:04:30,860 And I'll show you what that's about later. 74 00:04:30,860 --> 00:04:33,220 But right now we have iostream, iomanip, 75 00:04:33,220 --> 00:04:36,580 our sstream for our stringstreams and the string class. 76 00:04:36,580 --> 00:04:39,730 Okay. So here's what we've got. We've got these 77 00:04:39,730 --> 00:04:42,090 three variables, just like we saw on the slides: 78 00:04:42,090 --> 00:04:45,890 num is an int, total is a double and name is a string. 79 00:04:46,290 --> 00:04:50,690 And we've created this string right here called info that just has those three 80 00:04:51,190 --> 00:04:54,290 pieces of data in there. It's all a string right now. 81 00:04:54,290 --> 00:04:58,890 But what we want to do is we want to be able to read that or extract that information 82 00:04:58,890 --> 00:05:01,550 from the string as a string, 83 00:05:01,550 --> 00:05:05,350 an integer and a double and store them into these variables right up here. 84 00:05:05,600 --> 00:05:09,590 Yes. it's really easy to do. All we have to do is create 85 00:05:09,590 --> 00:05:12,590 an istringstream, we'll call it iss, 86 00:05:12,590 --> 00:05:15,790 and we're going to hook it up to that string info, this guy right here. 87 00:05:16,590 --> 00:05:20,290 And now what we can do is we can extract information from iss, 88 00:05:20,290 --> 00:05:24,490 which is a stream the same way that we extracted information from cin, 89 00:05:24,490 --> 00:05:27,850 the same way we extracted information from a file, same idea. 90 00:05:27,850 --> 00:05:30,050 Remember, we're using the stream abstraction, 91 00:05:30,050 --> 00:05:32,850 and we really don't care what the stream is connected to. 92 00:05:32,850 --> 00:05:35,510 In this case, it's connected to an in-memory string. 93 00:05:35,910 --> 00:05:40,410 And that's what we're doing here, we're reading name, num and total. 94 00:05:40,410 --> 00:05:44,310 The compiler knows the types for these guys because they're defined right up here. 95 00:05:44,310 --> 00:05:46,430 So it's going to try to read a string 96 00:05:46,430 --> 00:05:50,730 from the string iss, which is connected to this guy right here. 97 00:05:50,730 --> 00:05:53,430 And it's going to grab Moe and store it in name. 98 00:05:53,430 --> 00:05:58,230 Then it's going to get 100 stored in num, and it's going to get 1234.5 99 00:05:58,230 --> 00:06:02,430 and stored in total we'll display this information out to the 100 00:06:02,430 --> 00:06:04,030 console right here with cout. 101 00:06:04,390 --> 00:06:07,590 And we'll get a nice formatted output. So let's see what it looks like. 102 00:06:10,570 --> 00:06:14,230 And there you go. Moe 100 and 123.45. 103 00:06:14,230 --> 00:06:16,730 That's the data that was in this string. 104 00:06:16,730 --> 00:06:20,880 So you can see how easily we really what we were doing is actually parsing that string 105 00:06:20,880 --> 00:06:24,680 and parsing information out of there typed, which is kind of cool. 106 00:06:24,680 --> 00:06:27,180 And it was so easy to do we really had to do very little. 107 00:06:27,180 --> 00:06:31,480 All we had to do is this one line 17 right here. Once we hooked up the stringstream. 108 00:06:32,030 --> 00:06:35,630 Okay. So that's an example of input. Let me show you an example of output. 109 00:06:35,630 --> 00:06:39,230 I'll comment this piece of code out or uncomment that, I should say. 110 00:06:39,730 --> 00:06:43,230 Notice what we're doing here, we're going to use an output stringstream here 111 00:06:43,230 --> 00:06:46,590 and we'll call it oss. And we're not going to hook it up to anything 112 00:06:47,090 --> 00:06:50,890 behind the scenes the streamstream class has its own string buffer 113 00:06:50,890 --> 00:06:52,450 and that's what we're going to use. 114 00:06:52,450 --> 00:06:56,350 So in this case, what we're doing is we're instantiating oss right here. 115 00:06:56,850 --> 00:06:59,210 And then we're just going to write to the stream, 116 00:06:59,210 --> 00:07:03,010 and the stream is going to store that information in that string buffer that it has. 117 00:07:03,010 --> 00:07:05,670 So what we're going to do is we're going to display name, 118 00:07:05,670 --> 00:07:10,070 we're going to display num and we're going to display total. We still have those from this piece of code up here. 119 00:07:10,070 --> 00:07:13,070 And we're going to display them using these stream manipulators. 120 00:07:14,270 --> 00:07:17,260 And then when we're done we want to display the string, right. 121 00:07:17,260 --> 00:07:21,760 But all we have is that stream oss. I know string and stream sound alike, 122 00:07:21,760 --> 00:07:25,640 it's hard for me to say them because I confuse them myself. So 123 00:07:25,890 --> 00:07:29,990 all we have is a stream oss. It's connected to a string. 124 00:07:30,490 --> 00:07:32,590 So what we want to do is display the string. 125 00:07:32,590 --> 00:07:36,190 And the way we get to that string is we use the str method 126 00:07:36,190 --> 00:07:39,950 for the stream and that will return that internal 127 00:07:39,950 --> 00:07:43,950 string buffer that it's got it'll display it. So what we're doing here is 128 00:07:43,950 --> 00:07:47,150 we're we're outputting all of this information 129 00:07:47,150 --> 00:07:48,850 to that stream 130 00:07:48,850 --> 00:07:52,350 which is connected to its own string and then we're displaying the string. 131 00:07:52,350 --> 00:07:56,340 So when we display the string, you should see this display in a formatted manner. 132 00:07:56,640 --> 00:07:57,640 So let's try that. 133 00:07:59,940 --> 00:08:03,930 There it is, Moe 100 123.45. It's the same 134 00:08:03,930 --> 00:08:05,930 formatting that we used right up here. 135 00:08:06,230 --> 00:08:10,480 Makes sense. So what we're doing is we're displaying this. Remember, before it went to c out 136 00:08:10,480 --> 00:08:14,080 now it's not going to see out. Now it's going to that stringstream. 137 00:08:14,080 --> 00:08:17,280 They're both streams right, cout is an output stream. 138 00:08:17,280 --> 00:08:21,380 And oss is an output stream. It just happens to go to a string. 139 00:08:21,740 --> 00:08:24,040 And now let's do an example for data validation. 140 00:08:24,040 --> 00:08:27,640 You guys had a lot of questions about data validations on the on the forums. 141 00:08:27,640 --> 00:08:30,840 So I decided to do an example using the stringstream. 142 00:08:31,830 --> 00:08:35,130 All right. So let's go through this one really slowly here. 143 00:08:36,120 --> 00:08:39,620 This is the value. At the end of this, I want the 144 00:08:39,620 --> 00:08:43,289 user to enter an integer, and I want that integer to be in that 145 00:08:43,289 --> 00:08:45,950 value variable right here. Okay. 146 00:08:46,750 --> 00:08:50,100 But I can't -- you've seen how we can't just ask the user 147 00:08:50,100 --> 00:08:52,760 for an integer and then do something like cin, 148 00:08:52,760 --> 00:08:57,750 so we could read the console input into that value variable. 149 00:08:58,450 --> 00:09:01,810 That doesn't work real well, right. When they type strings and when they type 150 00:09:01,810 --> 00:09:05,060 just silly stuff on the keyboard, it's going to fail. 151 00:09:05,060 --> 00:09:08,500 So we've got to have a better way to do that.We have to be able to validate 152 00:09:08,500 --> 00:09:11,600 the type that they're entering. So that's what we're going to do here. 153 00:09:11,600 --> 00:09:17,500 Rather than read directly into an integer, we're going to read into a string, right here entry. 154 00:09:18,000 --> 00:09:22,660 Okay. And we're going to do this in a loop, and we're going to keep doing it until they enter something that's valid. 155 00:09:22,660 --> 00:09:24,860 So let's talk about the loop 156 00:09:24,860 --> 00:09:28,460 what we'll do what we'll do first is we're going to create a Boolean 157 00:09:28,460 --> 00:09:29,710 flag right here 158 00:09:29,710 --> 00:09:30,710 called done. 159 00:09:31,070 --> 00:09:33,970 And we're going to set done to false because we're not done. 160 00:09:33,970 --> 00:09:38,470 We're done when we're done, right. And we're starting out -- obviously,we're not done when we first start. 161 00:09:38,470 --> 00:09:41,770 So we've got a do loop or do while loop here. 162 00:09:41,770 --> 00:09:44,970 And what we're going to do first is we're going to say 163 00:09:44,970 --> 00:09:49,570 hey user please enter an integer and we're going to read the integer into entry. 164 00:09:49,570 --> 00:09:51,570 Remember, entry is that string. 165 00:09:52,570 --> 00:09:55,720 So now we're allowing them to enter anything they want, right. 166 00:09:55,720 --> 00:10:00,020 We're going to grab a string, so they can type in numbers letters decimals whatever they want. 167 00:10:00,020 --> 00:10:03,900 And what we'll do is we'll try to validate that to make sure that what they typed in 168 00:10:03,900 --> 00:10:07,890 is an integer. This is where the stringstream comes in, 169 00:10:07,890 --> 00:10:11,190 and we're going to use an istringstream. Here we could have just used a regular stringstream, 170 00:10:11,190 --> 00:10:15,390 it doesn't really matter because it goes both ways, but this is an input stringstream. 171 00:10:15,390 --> 00:10:18,890 And we're going to call it validator, could have called it anything you want. 172 00:10:18,890 --> 00:10:22,490 Typically, you see these things called ss out there in real code. 173 00:10:22,490 --> 00:10:28,050 I don't know why but it's very very common to see stringstreams named ss. 174 00:10:28,250 --> 00:10:31,610 So I'll call it validator, and I'm hooking it up to entry. 175 00:10:32,490 --> 00:10:34,790 So now remember entry is -- 176 00:10:34,790 --> 00:10:38,690 suppose entry has -- suppose the user entered one. 177 00:10:38,890 --> 00:10:41,890 Instead of the number one, they entered the string one. 178 00:10:42,690 --> 00:10:46,090 What we're doing is we're hooking up this string, right, input -- 179 00:10:46,090 --> 00:10:50,290 or sorry, entry right here to that validator stringstream. 180 00:10:50,540 --> 00:10:52,540 And then this is the key right here. 181 00:10:53,340 --> 00:10:57,340 I'm going to try to extract value what's value an integer, 182 00:10:57,840 --> 00:11:01,140 I'm going to try to extract a value from the stream. 183 00:11:01,390 --> 00:11:04,750 There's no way, right. We've got a string here that's o 184 00:11:04,750 --> 00:11:08,050 and e, that's not an integer. This will fail. 185 00:11:08,600 --> 00:11:12,100 If this fails, we're going to say sorry that's not an integer. 186 00:11:12,460 --> 00:11:17,160 Done is still false and we're going to loop again and I'll talk about this statement here in a second. 187 00:11:17,820 --> 00:11:21,820 But now suppose that they do enter a valid integer. Suppose they enter 188 00:11:21,820 --> 00:11:24,120 123 remember, it's a string. 189 00:11:24,120 --> 00:11:27,120 They're entering strings, but that's a valid integer in that string. 190 00:11:27,120 --> 00:11:32,110 When we get to here and we try to extract that integer from 191 00:11:32,410 --> 00:11:34,710 that entry that they put in through the stream, 192 00:11:34,710 --> 00:11:36,910 we're going to get back 123, 193 00:11:36,910 --> 00:11:40,270 and that's going to be stored right in value. So that's going to be perfect. 194 00:11:40,270 --> 00:11:43,570 This will pass. We'll set done to true, 195 00:11:44,070 --> 00:11:46,840 and we're looping while, we're not done, so we're done, 196 00:11:46,840 --> 00:11:51,540 right. Our loop will finish, and then I believe there's a statement down here at the bottom 197 00:11:51,540 --> 00:11:55,630 that says you enter the integer value, and I'll run this for you in a minute. 198 00:11:55,630 --> 00:11:58,130 Now let's talk about this statement right here. 199 00:12:01,120 --> 00:12:04,620 This is something I hadn't talked about yet. And this these are the more advanced 200 00:12:04,980 --> 00:12:07,480 edge cases and nuances of c++. 201 00:12:08,030 --> 00:12:10,530 Suppose that the user entered something like 202 00:12:10,730 --> 00:12:13,230 12.38. Okay. 203 00:12:15,430 --> 00:12:20,230 Well, this right here will extract the 12, 204 00:12:20,780 --> 00:12:22,780 and 12 will be put into value. 205 00:12:23,440 --> 00:12:26,140 But then we have all this stuff left over on the stream. 206 00:12:26,640 --> 00:12:30,300 So the next stream read doesn't really know that that's there. 207 00:12:30,300 --> 00:12:32,660 So what we're doing here is we're saying 208 00:12:32,660 --> 00:12:36,460 std cin, and we're using cin here because that's where we're reading data from. 209 00:12:37,010 --> 00:12:39,010 We're going to ignore 210 00:12:39,310 --> 00:12:41,670 everything in that stream up to the new line, 211 00:12:41,670 --> 00:12:46,030 and that's what we're doing here, and that's where that limits header file comes in. 212 00:12:46,030 --> 00:12:50,630 So we're using std numeric limits up to whatever the std stream size is, 213 00:12:50,630 --> 00:12:53,180 and that's dependent on your platform. 214 00:12:53,180 --> 00:12:57,440 So however big that stream is the maximum number 215 00:12:57,440 --> 00:13:01,940 I'm getting rid of all of this stuff, I'm just ignoring all that I'm, clearing out that stream. 216 00:13:01,940 --> 00:13:06,440 So that the next time i read from the stream, it's clean and there's nothing left over. 217 00:13:06,440 --> 00:13:09,440 Okay. Because remember, the user could have typed in 218 00:13:09,440 --> 00:13:13,040 12 hello there, 219 00:13:13,840 --> 00:13:14,340 right. 220 00:13:15,040 --> 00:13:17,040 And that space right there 221 00:13:17,540 --> 00:13:22,240 grabs that 12 and that 12 goes into value, this passes. This is true. 222 00:13:22,600 --> 00:13:25,400 So we've got an integer. They did type in an integer. 223 00:13:25,400 --> 00:13:27,700 They typed in a bunch of other stuff as well. 224 00:13:27,700 --> 00:13:32,360 But what we can do is we can grab the 12 and just delete that rest of that stuff. So the next time we read, 225 00:13:32,360 --> 00:13:35,660 we're clean. All right. So let's run this example 226 00:13:38,320 --> 00:13:40,520 and please enter an integer 12. 227 00:13:41,520 --> 00:13:45,120 You entered integer 12. Good, that was an integer that's what we expected. 228 00:13:45,120 --> 00:13:48,780 So let's run this again, please enter an integer let's say I typed in Frank. 229 00:13:49,440 --> 00:13:53,240 Sorry, that's not an integer. How about 0.01, 230 00:13:53,640 --> 00:13:57,240 sorry that's not an integer. But notice now that when I loop around, 231 00:13:57,240 --> 00:14:01,000 whatever was left in that that input stream is gone because I 232 00:14:01,000 --> 00:14:05,400 ignored it, I got rid of it all. So that really helps us with future input. 233 00:14:05,400 --> 00:14:09,000 So now if I did something like 10 Frank is 234 00:14:09,660 --> 00:14:11,160 a good teacher, 235 00:14:12,520 --> 00:14:13,820 something like that, 236 00:14:13,820 --> 00:14:17,810 you entered 10. Notice it grabbed the integer but then it just discarded everything else, 237 00:14:19,170 --> 00:14:22,370 right. So we're ready to read again. And our stream will be in a 238 00:14:22,370 --> 00:14:24,870 in a known state and not some unknown state. 239 00:14:25,670 --> 00:14:29,670 All right. So that's it. I hope you enjoyed this 240 00:14:29,670 --> 00:14:32,970 uh this section on stringstreams. They're very, very powerful. 241 00:14:33,330 --> 00:14:37,430 They're not used that often out there. But sometimes you'll see them used, and 242 00:14:37,430 --> 00:14:41,680 they're used a lot in gui work sometimes when you want to display strings to gui, 243 00:14:41,680 --> 00:14:46,670 graphical user interface elements, we tend to format them in memory and then display them out. 244 00:14:46,970 --> 00:14:50,970 That's it. So let me know if you have any questions about this.