Monthly Archives: December 2020
Vue || How To Set, Add & Update Query Params With Vue Router Using Vue
The following is a module which demonstrates how to set, add and update query params with Vue using Vue Router.
Note: The examples below assumes your project is already set up and configured. For an overview on how to get started with Vue and Vue Router, visit the official documentation.
1. Add & Update Query
The example below is a simple page with a login link. The link has a redirect parameter to navigate back to the referring page after successful login.
Clicking on the link results in the following:
/login?[existing query + computed result]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<!-- // ============================================================================ // Author: Kenneth Perkins // Date: Dec 31, 2020 // Taken From: http://programmingnotes.org/ // File: Home.vue // Description: Page that has a login redirect link // ============================================================================ --> <template> <section> <router-link :to="{name: 'Login', query: redirectQuery}"> Log in </router-link> </section> </template> <script> export default { data() { return {} }, computed: { redirectQuery() { return Object.assign({}, this.$route.query, {redirect: this.$route.query.redirect || this.$route.path}); } }, }; </script> <style scoped> </style> <!-- http://programmingnotes.org/ --> |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
Vue || How To Set Up Fade In & Fade Out Router View Transitions With Vue Router Using Vue
The following is a module which demonstrates how to set up fade in and fade out router view transitions with Vue using Vue Router.
Note: The examples below assumes your project is already set up and configured. For an overview on how to get started with Vue and Vue Router, visit the official documentation.
1. Router Index File
The example below is a sample router index.js file. This file sets up the routes in the project.
There are 2 routes: a ‘Home‘ page, and a ‘About‘ page.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
// ============================================================================ // Author: Kenneth Perkins // Date: Dec 30, 2020 // Taken From: http://programmingnotes.org/ // File: index.js // Description: Router index.js file // ============================================================================ import { createRouter, createWebHistory } from 'vue-router'; const routes = [ { path: '/', name: 'Home', component: () => import(/* webpackChunkName: "Home" */ '../views/Home.vue') }, { path: '/about', name: 'About', component: () => import(/* webpackChunkName: "About" */ '../views/About.vue') } ]; const router = createRouter({ history: createWebHistory(), routes }); export default router; // http://programmingnotes.org/ |
The layout of the routes above are not important. They are declared here simply to demonstrate a project with multiple routes set up.
2. App.vue
The example below is the ‘App.vue‘ page. This is the root of the application. In this example, this is where the fade in and fade out router view transitions will take effect.
When a route is clicked, its contents is loaded inside the router-view. The example below demonstrates how to set up the fade in and fade out router view transition effect.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<!-- // ============================================================================ // Author: Kenneth Perkins // Date: Dec 30, 2020 // Taken From: http://programmingnotes.org/ // File: App.vue // Description: Home page that displays content via router-view // ============================================================================ --> <template> <div id="nav"> <router-link :to="{name: 'Home'}">Home</router-link> | <router-link :to="{name: 'About'}">About</router-link> </div> <router-view v-slot="slotProps"> <transition name="fade" mode="out-in"> <component :is="slotProps.Component"></component> </transition> </router-view> </template> <script> export default { data() { return {} }, methods: {} } </script> <style> .fade-enter-active, .fade-leave-active { transition: opacity 0.3s; } .fade-enter, .fade-leave-to { opacity: 0; } </style> <!-- http://programmingnotes.org/ --> |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
Vue || How To Set Up Vue Smooth Scroll Behavior With Vue Router Using Vue
The following is a module which demonstrates how to set up smooth anchor scroll behavior when navigating to a new route with Vue using Vue Router.
Note: The examples below assumes your project is already set up and configured. For an overview on how to get started with Vue and Vue Router, visit the official documentation.
1. Router Index File
The example below is a sample router index.js file. This file sets up the routes in the project. Its also where you set up the scrolling behavior when navigating to a new route.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
// ============================================================================ // Author: Kenneth Perkins // Date: Dec 26, 2020 // Taken From: http://programmingnotes.org/ // File: index.js // Description: Router index.js file // ============================================================================ import { createWebHistory, createRouter } from "vue-router"; const routes = []; const router = createRouter({ history: createWebHistory(), routes, scrollBehavior(to, from, savedPosition) { let defaultPos = {left: 0, top: 0}; if (savedPosition) { return savedPosition; } else if (to.hash) { let elem = document.querySelector(to.hash); return elem ? elem.scrollIntoView({ behavior: 'smooth' }) : defaultPos; } else { return defaultPos; } } }); export default router; // http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
Vue || How To Create A 404 Not Found Route With Dynamic Nested Routes With Vue Router Using Vue
The following is a module which demonstrates how to create a 404 not found route with dynamic nested routes via Vue Router using Vue.
Routes can be checked using Navigation Guards. This page will demonstrate verifying nested routes using the Per Route Guard.
This will demonstrate how to create a route that catches all non existing routes with Vue Router. It will also demonstrate how to use navigation guards to make sure nested dynamic routes exists.
Note: The examples below assumes your project is already set up and configured. For an overview on how to get started with Vue and Vue Router, visit the official documentation.
1. Router Index File
The example below is a sample router index.js file. This file sets up the routes in the project.
There are 4 routes: a ‘Home‘ page, a ‘DestinationDetails‘ page, a ‘ExperienceDetails‘ page, and a ‘NotFound‘ page.
The ‘ExperienceDetails‘ page is a nested child route.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
// ============================================================================ // Author: Kenneth Perkins // Date: Dec 25, 2020 // Taken From: http://programmingnotes.org/ // File: index.js // Description: Router index.js file // ============================================================================ import { createWebHistory, createRouter } from "vue-router"; const routes = [ { path: "/", name: "Home", component: () => import(/* webpackChunkName: "Home" */ "../views/Home.vue"), }, { path: "/destination/:slug", name: "DestinationDetails", props: true, component: () => import(/* webpackChunkName: "DestinationDetails" */ "../views/DestinationDetails.vue"), children: [{ path: ":experienceSlug", name: "ExperienceDetails", props: true, component: () => import(/* webpackChunkName: "ExperienceDetails" */ "../views/ExperienceDetails.vue") }], beforeEnter: (to, from, next) => { // Verify the route exists by checking the API let exists = false; // If this is a parent route, check if it exists if (to.params.slug) { // Do something to check if this is valid exists = true; } // If this is a child route, check if it exists if (to.params.experienceSlug) { // Do something to check if this is valid exists = true; } // If the route exists, navigate to it if (exists) { next(); } else { next({name: "NotFound"}); } } }, { path: "/404", name: "NotFound", component: () => import(/* webpackChunkName: "NotFound" */ "../views/NotFound.vue") }, { path: "/:catchAll(.*)", redirect: {name: "NotFound"} } ]; const router = createRouter({ history: createWebHistory(), routes }); export default router; // http://programmingnotes.org/ |
The DestinationDetails route is a dynamic route that accepts props. In this example, the route.params will be set as the component props. In this component, the ‘slug‘ prop is used as the dynamic route path identifier.
The ExperienceDetails nested child route is also a dynamic route. In this component, the ‘experienceSlug‘ prop is used as the dynamic route path identifier.
Using the beforeEnter navigation guard, we can check if the route is valid by checking the dynamic route path identifier. If the route is not valid, the ‘NotFound‘ route is navigated to.
The NotFound route catches all non existing routes.
2. Home Page
The example below is the ‘Home‘ route page. This demonstrates how to navigate to the DestinationDetails route using the dynamic props.
It uses router-link to navigate to the specific route.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
<!-- // ============================================================================ // Author: Kenneth Perkins // Date: Dec 25, 2020 // Taken From: http://programmingnotes.org/ // File: Home.vue // Description: Home page that shows all destinations // ============================================================================ --> <template> <section> <h1> All Destinations </h1> <div> <section v-for="destination in destinations" :key="destination.id"> <router-link :to="getNavigationPath(destination)" > <h2>{{destination.name}}</h2> </router-link> <figure> <router-link :to="getNavigationPath(destination)"> <img :src="destination.image" :alt="destination.name"> </router-link> </figure> </section> </div> </section> </template> <script> export default { data() { return { destinations: api.destinations } }, methods: { getNavigationPath(destination) { return { name: 'DestinationDetails', params: { id: destination.id, slug: destination.slug } }; } } }; </script> <style scoped> </style> <!-- http://programmingnotes.org/ --> |
3. Destination Details Page
The example below is the ‘DestinationDetails‘ route page. This demonstrates how to display information about the destination and navigate to the ExperienceDetails route using the dynamic props passed to it.
It uses router-link to navigate to the specific route, and uses router-view to display the nested content from the navigated child route.
When calling the child component, it will automatically receive the parent ‘slug‘ dynamic route path identifier as a parameter.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
<!-- // ============================================================================ // Author: Kenneth Perkins // Date: Dec 25, 2020 // Taken From: http://programmingnotes.org/ // File: DestinationDetails.vue // Description: Displays information about a destination // ============================================================================ --> <template> <section> <div> <h1>{{destination.name}}</h1> <div"> <img :src="destination.image" :alt="destination.name"> <p>{{ destination.description }}</p> </div> </div> <section> <h2> Top experiences in {{destination.name}} </h2> <div> <article v-for="experience in destination.experiences" :key="experience.slug"> <router-link :to="getNavigationPath(experience)"> <img :src="experience.image" :alt="experience.name"> <span> {{experience.name}} </span> </router-link> </article> </div> <router-view :key="$route.path" /> </section> </section> </template> <script> export default { data() { return { } }, props: { slug: { type: String, required: true } }, computed: { destination() { return api.destinations.find( destination => destination.slug == this.slug ); } }, methods: { getNavigationPath(experience) { return { name: 'ExperienceDetails', params: { experienceSlug: experience.slug }, hash: '#experience', }; } } } </script> <style scoped> </style> <!-- http://programmingnotes.org/ --> |
4. Experience Details Page
The example below is the ‘ExperienceDetails‘ route page. This demonstrates how to display information about the destination experience using the dynamic props passed to it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
<!-- // ============================================================================ // Author: Kenneth Perkins // Date: Dec 25, 2020 // Taken From: http://programmingnotes.org/ // File: ExperienceDetails.vue // Description: Displays information about an experience // ============================================================================ --> <template> <section> <h2>{{experience.name}}</h2> <div> <img :src="experience.image" :alt="experience.name"> <p id="experience"> {{experience.description}} </p> </div> </section> </template> <script> export default { props: { slug: { type: String, required: true, }, experienceSlug: { type: String, required: true, } }, computed: { destination() { return api.destinations.find( destination => destination.slug == this.slug ); }, experience() { return this.destination.experiences.find( experience => experience.slug == this.experienceSlug ); } } } </script> <style scoped> </style> <!-- http://programmingnotes.org/ --> |
5. Not Found (404) Page
The example below is the ‘NotFound‘ route page. This page catches all non existing routes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<!-- // ============================================================================ // Author: Kenneth Perkins // Date: Dec 25, 2020 // Taken From: http://programmingnotes.org/ // File: NotFound.vue // Description: Not found (404) page // ============================================================================ --> <template> <section> <h1>Not Found</h1> <p>Oops we couldn't find that page. Try going <router-link :to="{name: 'Home'}"> home </router-link> </p> </section> </template> <script> export default { data() { return {} }, methods: {} } </script> <style scoped> </style> <!-- http://programmingnotes.org/ --> |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
Vue || How To Set Up Vue Login Authentication & Route Handling With Vue Router Using Vue
The following is a module which demonstrates how to set up Vue login authentication and route handling using Vue Router.
Note: The examples below assumes your project is already set up and configured. For an overview on how to get started with Vue and Vue Router, visit the official documentation.
1. Router Index File
The example below is a sample router index.js file. This file sets up the routes in the project.
There are 3 routes: a ‘Home‘ page, a ‘User‘ page, and a ‘Login‘ page.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
// ============================================================================ // Author: Kenneth Perkins // Date: Dec 24, 2020 // Taken From: http://programmingnotes.org/ // File: index.js // Description: Vue Router index.js file // ============================================================================ import { createWebHistory, createRouter } from "vue-router"; const routes = [ { path: "/", name: "home", component: () => import(/* webpackChunkName: "home" */ "../views/Home.vue"), }, { path: "/user", name: "user", component: () => import(/* webpackChunkName: "user" */ "../views/User.vue"), meta: {requiresAuth: true} // Indicates that this route requires authentication }, { path: "/login", name: "login", component: () => import(/* webpackChunkName: "login" */ "../views/Login.vue") } ]; const router = createRouter({ history: createWebHistory(), routes }); router.beforeEach((to, from, next) => { // Determine if the route requires authentication if (to.matched.some(record => record.meta.requiresAuth)) { // Get value from somewhere to determine if the user is // logged in or not let isLoggedIn = false; // If user is not logged in, navigate to the named "login" route // with a query string parameter indicating where to navigate to after // successful login if (!isLoggedIn) { // Navigate to login route next({ name: "login", query: {redirect: to.fullPath} }); } else { next(); } } else { next(); } }); export default router; // http://programmingnotes.org/ |
The ‘User‘ route has a meta property that says that it requires authentication.
Next, the route records are iterated over to check if the requested page requires authentication. If it does, the route is redirected to the ‘Login‘ named route, with a query string parameter of the original page to redirect to after successful login.
2. Login Route Page
The example below is the ‘Login‘ route page. It doesn’t do anything special, it just demonstrates how to accept user input and redirect to the specified path after successful login is complete.
Accessing the route redirect path can be done by using the ‘query’ property on the route object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
<!-- // ============================================================================ // Author: Kenneth Perkins // Date: Dec 24, 2020 // Taken From: http://programmingnotes.org/ // File: Login.vue // Description: Login authentication page // ============================================================================ --> <template> <section> <h1> Login </h1> <div class="form"> <label for="username">Username</label> <input v-model="username" type="text" name="username" class="input" autocomplete="off" /> <label for="password">Password</label> <input v-model="password" type="password" class="input" autocomplete="off" /> <button @click="login" class="btn">Login</button> </div> </section> </template> <script> export default { data() { return { username: null, password: null, } }, methods: { login() { // Authenticate user against API console.log(this.username, this.password); // Set value somewhere to indicate that the user is logged in let isLoggedIn = true; // Redirect to page const redirectPath = this.$route.query.redirect || '/'; this.$router.push(redirectPath); } } } </script> <style scoped> .form { display: flex; flex-direction: column; max-width: 400px; margin: 0 auto; } </style> <!-- http://programmingnotes.org/ --> |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
CSS || How To Zoom & Enlarge An Image On Mouse Hover Using CSS
The following is a module which demonstrates how to zoom and enlarge an image on mouse hover using CSS.
1. Usage
The example below demonstrates the use of the Grow CSS.
1 2 3 |
<!-- // Usage --> <img class="grow" src="https://en.wikipedia.org/static/images/project-logos/enwiki.png" /> |
2. Grow CSS
The following is the Grow css file. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* // ============================================================================ // Author: Kenneth Perkins // Date: Dec 23, 2020 // Taken From: http://programmingnotes.org/ // File: Utils.css // Description: General utility Css // ============================================================================ */ .grow:hover { transform: scale(1.1); } .grow { transition: all .2s ease-in-out; } /* http://programmingnotes.org/ */ |
3. More Examples
Below are more examples demonstrating the use of the ‘Grow‘ css. Don’t forget to include the module when running the examples!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<!-- // ============================================================================ // Author: Kenneth Perkins // Date: Dec 23, 2020 // Taken From: http://programmingnotes.org/ // File: demo.html // Description: Demonstrates the use of css styles // ============================================================================ --> <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>My Programming Notes HTML Demo</title> <style> .main { text-align:center; margin-left:auto; margin-right:auto; } </style> <!-- // Include module --> <link rel="stylesheet" type="text/css" href="./Utils.css"> </head> <body> <div class="main"> <div>My Programming Notes HTML Demo</div> <img class="grow" src="https://en.wikipedia.org/static/images/project-logos/enwiki.png" /> </div> </body> </html> <!-- http://programmingnotes.org/ --> |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
CSS || How To Create Horizontal Divider Line With Words In The Middle Using CSS
The following is a module which demonstrates how to create a horizontal divider line with words in the middle using CSS.
1. Usage
The example below demonstrates the use of the Divider CSS.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<!-- // Usage --> <h2> This </h2> <div class="divider"> <span class="divider-line"></span> <span class="divider-content"> or </span> <span class="divider-line"></span> </div> <h2> That </h2> |
2. Divider Line CSS
The following is the Divider css file. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
/* // ============================================================================ // Author: Kenneth Perkins // Date: Dec 23, 2020 // Taken From: http://programmingnotes.org/ // File: Utils.css // Description: General utility Css // ============================================================================ */ .divider-line { -webkit-box-flex: 1; -webkit-flex-grow: 1; -ms-flex-positive: 1; flex-grow: 1; -webkit-flex-shrink: 1; -ms-flex-negative: 1; flex-shrink: 1; background-color: #dbdbdb; height: 1px; position: relative; top: .45em; } .divider { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -webkit-flex-direction: row; -ms-flex-direction: row; flex-direction: row; display: flex; } .divider-content { color: #8e8e8e; -webkit-box-flex: 0; -webkit-flex-grow: 0; -ms-flex-positive: 0; flex-grow: 0; -webkit-flex-shrink: 0; -ms-flex-negative: 0; flex-shrink: 0; font-size: 13px; font-weight: 600; line-height: 15px; margin: 0 18px; text-transform: uppercase; } /* http://programmingnotes.org/ */ |
3. More Examples
Below are more examples demonstrating the use of the ‘Divider‘ css. Don’t forget to include the module when running the examples!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<!-- // ============================================================================ // Author: Kenneth Perkins // Date: Dec 23, 2020 // Taken From: http://programmingnotes.org/ // File: demo.html // Description: Demonstrates the use of css styles // ============================================================================ --> <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>My Programming Notes HTML Demo</title> <style> .main { text-align:center; margin-left:auto; margin-right:auto; } </style> <!-- // Include module --> <link rel="stylesheet" type="text/css" href="./Utils.css"> </head> <body> <div class="main"> <div>My Programming Notes HTML Demo</div> <h2> This </h2> <div class="divider"> <span class="divider-line"></span> <span class="divider-content"> or </span> <span class="divider-line"></span> </div> <h2> That </h2> </div> </body> </html> <!-- http://programmingnotes.org/ --> |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
JavaScript/CSS/HTML || Simple Tic Tac Toe Game With Minimax AI Using Vanilla JavaScript
The following is a module with functions which demonstrates how to create a simple Tic-Tac-Toe game with computer AI using vanilla JavaScript.
This game allows for two or more players, or computer AI vs computer AI. The first player to match 3 pieces horizontally, vertically and diagonally in a row wins!
1. Features
This game allows for two or more players. To add more players, click the “add new” button under the “players” list. To edit a player, click the “edit” button next to a players name.
• Adding and editing a player allows you to change:
1. Name
2. Avatar image url
3. CPU player & difficulty
• To remove a player, click the “remove” button next to the players name.
• A “save game” button allows to save the progress of the game. A file is generated, which consists of the state of the game. This file can be used to reload the game, using the “load game” button.
• Match history is saved, and lets you see the game stats from the previous completed games.
• Player AI uses the minimax algorithm. It has 4 levels of difficulty:
1. Easy
2. Normal
3. Hard
4. Impossible - You will not win!
2. Screenshots
3. Download & Play
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
C++ || How To Create A Simple Predictive Spell Checker Using C++
The following is a module with functions which demonstrates how to create a simple predictive spell checker using C++.
The module demonstrated on this page is an implementation based on the Norvig Spelling Corrector.
1. Overview
In its simplest form, this process works by first telling the spelling corrector the valid words in our language. This is called “training” the corrector. Once the corrector is trained to know the valid words in our language, it tries to choose the word that is the most likely spelling correction.
This process is done by choosing the candidate with the highest probability to show up in our language. For example, should “lates” be corrected to “late” or “latest” or “lattes” or …? This choice is determined by the word which has the highest probability to appear in our language, according to the training text we provide.
Traditionally, spell checkers look for four possible errors: a wrong letter (“wird”), also knows as alteration. An inserted letter (“woprd”), a deleted letter (“wrd”), or a pair of adjacent transposed letters (“wrod”). This process is used when generating probable spelling correction candidates.
The training text used in the example on this page can be downloaded here. This file consists of 80891 distinct words, which is used to train the spelling corrector.
2. Spell Check – Basic Usage
The example below demonstrates the use of the ‘SpellChecker‘ class to load the training file and correct the spelling of a word.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// Spell Check - Basic Usage // Declare spell checker SpellChecker spellchecker; // Declare training text path std::string path = "INPUT_Dictionary_programmingnotes_org.txt"; // Add training text from a file spellchecker.trainFromFile(path); // Optional: Add training text from an std::string //spellchecker.train(); // Correct a word and display results std::cout << spellchecker.correct("KENNtH"); // example output: /* KENNetH */ |
3. Spell Check – Unit Tests
The example below demonstrates the use of the ‘SpellChecker‘ class to load the training file and correct the spelling of a word.
In this example, words are added to a set to determine if the most likely spelling correction is returned by the spelling corrector. The first word in the set is the word to test against (some are spelled correctly, some incorrectly). The second word in the set is the expected result that should be returned by the spelling corrector.
If no spelling suggestion is found, an empty string is returned by the spelling corrector. This is true for one of the words in the test cases below. Even though the word is spelled correctly, it is not defined in our training text, and no correction can be found.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
// Spell Check - Unit Tests // Declare spell checker SpellChecker spellchecker; // Declare training text path std::string path = "INPUT_Dictionary_programmingnotes_org.txt"; // Add training text from a file spellchecker.trainFromFile(path); // Declare words to check spelling. // The first word in the set is the current spelling, the second word // is the expected corrected spell checker result std::pair<std::string, std::string> cases[] = { {"KENNtH", "KENNetH"}, {"Jennierr", "Jennifer"}, {"LYnNn", "Lynn"}, {"Soole", "Sole"}, {"speling", "spelling"}, {"korrectud", "corrected"}, {"bycycle", "bicycle"}, {"inconvient", "inconvenient"}, {"arrainged", "arranged"}, {"peotry", "poetry"}, {"peotryy", "poetry"}, {"word", "word"}, {"quintessential", "quintessential"}, {"transportibility", "transportability"}, {"addresable", "addressable"}, {"auxiliaryy", "auxiliary"}, {"WirD", "WorD"}, {"prplee", "purple"}, {"Succesfuil", "Successful"}, {"AMEIRICUA", "AMERICA"}, {"Langauege", "Language"} }; // Correct the words in the test cases for (const auto& pair : cases) { // Correct word auto correction = spellchecker.correct(pair.first); // Check to see if correction matches the expected result bool casePassed = (strcasecmp(correction.c_str(), pair.second.c_str()) == 0); // Display results if (casePassed) { std::cout << "Passed - Original: " + pair.first + ", Correction: " + correction << std::endl; } else { std::cout << " *** Failed - Original: " + pair.first + ", Correction: " + correction + ", Expected: " + pair.second << std::endl; } } // example output: /* Passed - Original: KENNtH, Correction: KENNetH Passed - Original: Jennierr, Correction: Jennifer Passed - Original: LYnNn, Correction: LYNn Passed - Original: Soole, Correction: Sole Passed - Original: speling, Correction: spelling Passed - Original: korrectud, Correction: corrected Passed - Original: bycycle, Correction: bicycle Passed - Original: inconvient, Correction: inconvenient Passed - Original: arrainged, Correction: arranged Passed - Original: peotry, Correction: poetry Passed - Original: peotryy, Correction: poetry Passed - Original: word, Correction: word *** Failed - Original: quintessential, Correction: , Expected: quintessential Passed - Original: transportibility, Correction: transportability Passed - Original: addresable, Correction: addressable Passed - Original: auxiliaryy, Correction: auxiliary Passed - Original: WirD, Correction: WorD Passed - Original: prplee, Correction: purple Passed - Original: Succesfuil, Correction: Successful Passed - Original: AMEIRICUA, Correction: AMERICA Passed - Original: Langauege, Correction: Language */ |
4. SpellChecker Class
The following is the SpellChecker Class. Include this in your project to start using!
The following is the header file ‘SpellChecker.h‘.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
// ============================================================================ // Author: Kenneth Perkins // Date: Dec 18, 2020 // Taken From: http://programmingnotes.org/ // File: SpellChecker.h // Description: Header file for a predictive spell checker class that // generates spelling corrections // ============================================================================ #pragma once #include <string> #include <unordered_set> #include <utility> #include <unordered_map> #include <cctype> #ifdef _MSC_VER #include <string.h> #define strncasecmp _strnicmp #define strcasecmp _stricmp #else #include <strings.h> #endif class SpellChecker { public: SpellChecker() {} /** * FUNCTION: correct * USE: Corrects the spelling of a word. If the word is spelled incorrectly, * a spelling suggestion is returned. If it is spelled correctly, the * initial word is returned. If no spelling suggestion is found, an empty * string is returned * @param word: The word to correct * @return: The spelling correction of the word */ std::string correct(const std::string& word); /** * FUNCTION: train * USE: Adds training text to the spell checker * @param text: The training text * @return: N/A */ void train(const std::string& text); /** * FUNCTION: trainFromFile * USE: Reads a file containing training text and adds it to the spell checker * @param path: The path of the file containing training text * @return: N/A */ void trainFromFile(const std::string& path); /** * FUNCTION: exists * USE: Determines if a word is a valid word in the spell checker * @param word: The word to test against * @return: True if the word exists in the spell checker, false otherwise */ bool exists(const std::string& word); ~SpellChecker() { NWORDS.clear(); } private: // Makes map keys case insensitive struct case_insensitive { struct comp { bool operator() (const std::string& lhs, const std::string& rhs) const { return strcasecmp(lhs.c_str(), rhs.c_str()) == 0; } }; struct hash { std::size_t operator() (std::string str) const { for (std::size_t index = 0; index < str.size(); ++index) { auto ch = static_cast<unsigned char>(str[index]); str[index] = static_cast<unsigned char>(std::tolower(ch)); } return std::hash<std::string>{}(str); } }; }; typedef std::unordered_map<std::string, unsigned , case_insensitive::hash, case_insensitive::comp> dictionary; std::unordered_set<std::string> edit(const std::unordered_set<std::string>& words); std::unordered_set<std::string> known(const std::unordered_set<std::string>& words); std::string max(const std::unordered_set<std::string>& candidates, const std::string& word); std::unordered_set<std::string> getCandidates(const std::string& word); dictionary NWORDS; const std::string alphabet = "abcdefghijklmnopqrstuvwxyz"; };// http://programmingnotes.org/ |
The following is the implementation file ‘SpellChecker.cpp‘.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
// ============================================================================ // Author: Kenneth Perkins // Date: Dec 18, 2020 // Taken From: http://programmingnotes.org/ // File: SpellChecker.cpp // Description: Implementation file for a predictive spell checker class // that generates spelling corrections // ============================================================================ #include "SpellChecker.h" #include <string> #include <sstream> #include <unordered_set> #include <fstream> #include <stdexcept> #include <algorithm> #include <cmath> #include <cctype> void clean(std::string& word) { auto isInvalidChar = [](unsigned char c) { return std::ispunct(c) && c != '\'' && c != '-'; }; for (int index = (int)word.size() - 1; index >= 0; --index) { if (isInvalidChar(word[index])) { word.erase(index, 1); } } } std::string SpellChecker::correct(const std::string& word) { std::string suggestion = ""; // Get spelling suggestions for the word auto candidates = getCandidates(word); if (!candidates.empty()) { suggestion = max(candidates, word); } return suggestion; } void SpellChecker::trainFromFile(const std::string& path) { std::ifstream infile; infile.open(path); if (infile.fail()) { throw std::invalid_argument{ "Unable to read file at path: '" + path + "'" }; } infile.seekg(0, std::ios::end); auto size = infile.tellg(); std::string contents((std::size_t)size, ' '); infile.seekg(0); infile.read(&contents[0], size); infile.close(); train(contents); } void SpellChecker::train(const std::string& text) { std::stringstream strStream(text); while (strStream) { std::string word; strStream >> word; clean(word); if (word.empty()) { continue; } NWORDS[word] += 1; } } std::unordered_set<std::string> SpellChecker::getCandidates(const std::string& word) { auto candidates = known({ word }); // Edits 1 std::unordered_set<std::string> firstEdit; if (candidates.empty()) { firstEdit = edit({ word }); candidates = known(firstEdit); } // Edits 2 if (candidates.empty()) { candidates = known(edit(firstEdit)); } return candidates; } std::string SpellChecker::max(const std::unordered_set<std::string>& candidates, const std::string& word) { std::string maxKey; const double nullValue = -1987199120102019; auto maxValue = nullValue; for (const auto& candidate : candidates) { int currentValue = NWORDS[candidate]; // Add a penalty to the candidate based on the length change auto lengthChange = std::abs((int)(candidate.size() - word.size())); currentValue -= lengthChange; if (maxValue == nullValue || currentValue > maxValue) { maxKey = candidate; maxValue = currentValue; } } return maxKey; } bool SpellChecker::exists(const std::string& word) { return !NWORDS.empty() && NWORDS.find(word) != NWORDS.end(); } std::unordered_set<std::string> SpellChecker::edit(const std::unordered_set<std::string>& words) { std::unordered_set<std::string> edits; for (const auto& word : words) { for (std::size_t index = 0; index <= word.size(); ++index) { auto a = word.substr(0, index); auto b = word.substr(index); auto c = b.size() > 1 ? b.substr(1) : ""; auto d = b.size() > 2 ? b.substr(2) : ""; if (!b.empty()) { // Deletes edits.insert(a + c); // Transposes if (b.size() > 1) { edits.insert(a + b[1] + b[0] + d); } // Alteration & Inserts for (const auto& letter : alphabet) { // Alteration edits.insert(a + letter + c); // Inserts edits.insert(a + letter + b); } } else { // Inserts (remaining set at the end) for (const auto& letter : alphabet) { edits.insert(a + letter); } } } } return edits; } std::unordered_set<std::string> SpellChecker::known(const std::unordered_set<std::string>& words) { std::unordered_set<std::string> set; for (const auto& word : words) { if (exists(word)) { set.insert(word); } } return set; }// http://programmingnotes.org/ |
5. More Examples
Below are more examples demonstrating the use of the ‘SpellChecker‘ class. Don’t forget to include the module when running the examples!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
// ============================================================================ // Author: Kenneth Perkins // Date: Dec 18, 2020 // Taken From: http://programmingnotes.org/ // File: program.cpp // Description: The following demonstrates the use of the SpellChecker class // ============================================================================ #include <iostream> #include <string> #include <exception> #include <utility> #include "SpellChecker.h" void display(const std::string& message); int main() { try { // Declare spell checker SpellChecker spellchecker; // Declare training text path std::string path = "INPUT_Dictionary_programmingnotes_org.txt"; // Add training text from a file spellchecker.trainFromFile(path); // Optional: Add training text from an std::string //spellchecker.train(); // Correct a word and display results display(spellchecker.correct("KENNtH")); display(""); // Declare words to check spelling. // The first word in the set is the current spelling, the second word // is the expected corrected spell checker result std::pair<std::string, std::string> cases[] = { {"KENNtH", "KENNetH"}, {"Jennierr", "Jennifer"}, {"LYnNn", "Lynn"}, {"Soole", "Sole"}, {"speling", "spelling"}, {"korrectud", "corrected"}, {"bycycle", "bicycle"}, {"inconvient", "inconvenient"}, {"arrainged", "arranged"}, {"peotry", "poetry"}, {"peotryy", "poetry"}, {"word", "word"}, {"quintessential", "quintessential"}, {"transportibility", "transportability"}, {"addresable", "addressable"}, {"auxiliaryy", "auxiliary"}, {"WirD", "WorD"}, {"prplee", "purple"}, {"Succesfuil", "Successful"}, {"AMEIRICUA", "AMERICA"}, {"Langauege", "Language"} }; // Correct the words in the test cases for (const auto& pair : cases) { // Correct word auto correction = spellchecker.correct(pair.first); // Check to see if correction matches the expected result bool casePassed = (strcasecmp(correction.c_str(), pair.second.c_str()) == 0); // Display results if (casePassed) { display("Passed - Original: " + pair.first + ", Correction: " + correction); } else { display(" *** Failed - Original: " + pair.first + ", Correction: " + correction + ", Expected: " + pair.second); } } } catch (std::exception& e) { display("\nAn error occurred: " + std::string(e.what())); } std::cin.get(); return 0; } void display(const std::string& message) { std::cout << message << std::endl; }// http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
Remember to include the training file.
C++ || How To Execute & Get Regex Match Results Using C++
The following is a module with functions which demonstrates how to execute and get regex match results using C++.
The function demonstrated on this page uses regex to search a specified input string for all occurrences of a specified regular expression. The function returns a collection of std::smatch objects found by the search.
1. Get Regex Matches
The example below demonstrates the use of ‘Utils::getRegexMatches‘ to search an input string for all occurrences of a regular expression.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// Get Regex Matches // Declare source std::string input = "Kenneth, Jennifer, Lynn, Sole"; // Declare pattern std::string pattern = R"(\w+)"; // Find matches auto matches = Utils::getRegexMatches(pattern, input); // Display results for (const auto& match : matches) { // Display full match std::cout << "Match: " << match.str() << std::endl; } // example output: /* Match: Kenneth Match: Jennifer Match: Lynn Match: Sole */ |
2. Get Regex Matches – Sub Match
The example below demonstrates the use of ‘Utils::getRegexMatches‘ to search an input string for all occurrences of a regular expression.
In this example, sub matches are expected and displayed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
// Get Regex Matches - Sub Match // Declare source std::string input = "212-555-6666 906-932-1111 415-222-3333 425-888-9999"; // Declare pattern std::string pattern = R"((\d{3})-(\d{3}-\d{4}))"; // Find matches auto matches = Utils::getRegexMatches(pattern, input); // Display results for (const auto& match : matches) { // Display full match std::cout << "Full Match: " << match.str() << std::endl; // Display any submatches for (unsigned index = 1; index < match.size(); ++index) { std::cout << " Sub Match #" << index << ": " << match.str(index) << std::endl; } } // example output: /* Full Match: 212-555-6666 Sub Match #1: 212 Sub Match #2: 555-6666 Full Match: 906-932-1111 Sub Match #1: 906 Sub Match #2: 932-1111 Full Match: 415-222-3333 Sub Match #1: 415 Sub Match #2: 222-3333 Full Match: 425-888-9999 Sub Match #1: 425 Sub Match #2: 888-9999 */ |
3. Utils Namespace
The following is the Utils Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// ============================================================================ // Author: Kenneth Perkins // Date: Dec 11, 2020 // Taken From: http://programmingnotes.org/ // File: Utils.h // Description: Handles general utility functions // ============================================================================ #pragma once #include <regex> #include <vector> namespace Utils { /** * FUNCTION: getRegexMatches * USE: Searches the specified input string for all occurrences of a * specified regular expression * @param pattern: The regular expression pattern to match * @param input: The string to search for a match * @return: A collection of std::smatch objects found by the search. If * no matches are found, the method returns an empty collection */ auto getRegexMatches(const std::string& pattern, const std::string& input) { std::vector<std::smatch> results; std::regex rgx(pattern); for (std::sregex_iterator it(input.begin(), input.end(), rgx), end; it != end; ++it) { results.push_back(*it); } return results; } }// http://programmingnotes.org/ |
4. More Examples
Below are more examples demonstrating the use of the ‘Utils‘ Namespace. Don’t forget to include the module when running the examples!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
// ============================================================================ // Author: Kenneth Perkins // Date: Dec 11, 2020 // Taken From: http://programmingnotes.org/ // File: program.cpp // Description: The following demonstrates the use of the Utils Namespace // ============================================================================ #include <iostream> #include <string> #include <exception> #include "Utils.h" void display(const std::string& message); int main() { try { // Declare source std::string input = "Kenneth, Jennifer, Lynn, Sole"; // input = "212-555-6666 906-932-1111 415-222-3333 425-888-9999"; // Declare pattern std::string pattern = R"(\w+)"; // pattern = R"((\d{3})-(\d{3}-\d{4}))"; // Find matches auto matches = Utils::getRegexMatches(pattern, input); // Display results for (const auto& match : matches) { // Display full match std::cout << "Full Match: " << match.str() << std::endl; // Display any submatches for (unsigned index = 1; index < match.size(); ++index) { std::cout << " Sub Match #" << index << ": " << match.str(index) << std::endl; } } } catch (std::exception& e) { display("\nAn error occurred: " + std::string(e.what())); } std::cin.get(); return 0; } void display(const std::string& message) { std::cout << message << std::endl; }// http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
C++ || How To Trim & Remove The Leading & Trailing Whitespace From A String Using C++
The following is a module with functions which demonstrates how to trim and remove the leading and trailing whitespace from a string using C++.
1. Trim
The example below demonstrates the use of ‘Utils::trim‘ to remove all the leading and trailing whitespace characters from a string.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// Trim // Declare string std::string original = " <-Kenneth-> "; // Trim the string auto trim = Utils::trim(original); // Display result std::cout << "Original: '" << original << "'" << std::endl; std::cout << "Trim: '" << trim << "'" << std::endl; // expected output: /* Original: ' <-Kenneth-> ' Trim: '<-Kenneth->' */ |
2. Trim Start
The example below demonstrates the use of ‘Utils::trimStart‘ to remove all leading whitespace characters from a string.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// Trim Start // Declare string std::string original = " <-Kenneth-> "; // Trim the start of string auto ltrim = Utils::trimStart(original); // Display result std::cout << "Original: '" << original << "'" << std::endl; std::cout << "Trim Start: '" << ltrim << "'" << std::endl; // expected output: /* Original: ' <-Kenneth-> ' Trim Start: '<-Kenneth-> ' */ |
3. Trim End
The example below demonstrates the use of ‘Utils::trimEnd‘ to remove all trailing whitespace characters from a string.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// Trim End // Declare string std::string original = " <-Kenneth-> "; // Trim the end of string auto rtrim = Utils::trimEnd(original); // Display result std::cout << "Original: '" << original << "'" << std::endl; std::cout << "Trim End: '" << rtrim << "'" << std::endl; // expected output: /* Original: ' <-Kenneth-> ' Trim End: ' <-Kenneth->' */ |
4. Utils Namespace
The following is the Utils Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
// ============================================================================ // Author: Kenneth Perkins // Date: Dec 10, 2020 // Taken From: http://programmingnotes.org/ // File: Utils.h // Description: Handles general utility functions // ============================================================================ #pragma once #include <string> #include <algorithm> #include <cctype> namespace Utils { /** * FUNCTION: trimEnd * USE: Returns a new string with all trailing whitespace characters removed * @param source: The source string * @return: A new string with all the trailing whitespace characters removed */ std::string trimEnd(std::string source) { source.erase(std::find_if(source.rbegin(), source.rend(), [](char c) { return !std::isspace(static_cast<unsigned char>(c)); }).base(), source.end()); return source; } /** * FUNCTION: trimStart * USE: Returns a new string with all leading whitespace characters removed * @param source: The source string * @return: A new string with all the leading whitespace characters removed */ std::string trimStart(std::string source) { source.erase(source.begin(), std::find_if(source.begin(), source.end(), [](char c) { return !std::isspace(static_cast<unsigned char>(c)); })); return source; } /** * FUNCTION: trim * USE: Returns a new string with all the leading and trailing whitespace * characters removed * @param source: The source string * @return: A new string with all the leading and trailing whitespace * characters removed */ std::string trim(std::string source) { return trimEnd(trimStart(source)); } }// http://programmingnotes.org/ |
5. More Examples
Below are more examples demonstrating the use of the ‘Utils‘ Namespace. Don’t forget to include the module when running the examples!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
// ============================================================================ // Author: Kenneth Perkins // Date: Dec 10, 2020 // Taken From: http://programmingnotes.org/ // File: program.cpp // Description: The following demonstrates the use of the Utils Namespace // ============================================================================ #include <iostream> #include <string> #include <exception> #include "Utils.h" void display(const std::string& message); int main() { try { // Declare string std::string original = " <-Kenneth-> "; // Trim the string auto trim = Utils::trim(original); // Display result display("Original: '" + original + "'"); display("Trim: '" + trim + "'"); display(""); // Trim the start of string auto ltrim = Utils::trimStart(original); // Display result display("Original: '" + original + "'"); display("Trim Start: '" + ltrim + "'"); display(""); // Trim the end of string auto rtrim = Utils::trimEnd(original); // Display result display("Original: '" + original + "'"); display("Trim End: '" + rtrim + "'"); } catch (std::exception& e) { display("\nAn error occurred: " + std::string(e.what())); } std::cin.get(); return 0; } void display(const std::string& message) { std::cout << message << std::endl; }// http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
C++ || How To Check If A String Starts & Ends With A Certain String Using C++
The following is a module with functions which demonstrates how to determine if a string starts and ends with a certain substring using C++.
1. Starts With
The example below demonstrates the use of ‘Utils::startsWith‘ to determine whether the beginning of a string instance matches a specified string value.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// Starts With // Declare values std::string values[] = { "This is a string.", "Hello!", "Nothing.", "Yes.", "randomize" }; // Declare search std::string search = "Th"; // Check if items starts with search value for (const auto& value : values) { std::cout << "'" << value << "' starts with '" << search << "': " << (Utils::startsWith(value, search) ? "True" : "False") << std::endl; } // example output: /* 'This is a string.' starts with 'Th': True 'Hello!' starts with 'Th': False 'Nothing.' starts with 'Th': False 'Yes.' starts with 'Th': False 'randomize' starts with 'Th': False */ |
2. Ends With
The example below demonstrates the use of ‘Utils::endsWith‘ to determine whether the end of a string instance matches a specified string value.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// Ends With // Declare values std::string values[] = { "This is a string.", "Hello!", "Nothing.", "Yes.", "randomize" }; // Declare search std::string search = "."; // Check if items ends with search value for (const auto& value : values) { std::cout << "'" << value << "' ends with '" << search << "': " << (Utils::endsWith(value, search) ? "True" : "False") << std::endl; } // example output: /* 'This is a string.' ends with '.': True 'Hello!' ends with '.': False 'Nothing.' ends with '.': True 'Yes.' ends with '.': True 'randomize' ends with '.': False */ |
3. Utils Namespace
The following is the Utils Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
// ============================================================================ // Author: Kenneth Perkins // Date: Dec 9, 2020 // Taken From: http://programmingnotes.org/ // File: Utils.h // Description: Handles general utility functions // ============================================================================ #pragma once #include <string> namespace Utils { /** * FUNCTION: startsWith * USE: Determines whether the beginning of a string instance matches * a specified string value * @param source: The source string * @param value: The string to compare * @return: True if 'value' matches the beginning of 'source', * False otherwise */ bool startsWith(const std::string& source, const std::string& value) { return source.size() >= value.size() && source.compare(0, value.size(), value) == 0; } /** * FUNCTION: endsWith * USE: Determines whether the end of a string instance matches * a specified string value * @param source: The source string * @param value: The string to compare to the substring at the end * @return: True if 'value' matches the end of 'source', * False otherwise */ bool endsWith(const std::string& source, const std::string& value) { return source.size() >= value.size() && source.compare(source.size() - value.size(), value.size(), value) == 0; } }// http://programmingnotes.org/ |
4. More Examples
Below are more examples demonstrating the use of the ‘Utils‘ Namespace. Don’t forget to include the module when running the examples!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
// ============================================================================ // Author: Kenneth Perkins // Date: Dec 9, 2020 // Taken From: http://programmingnotes.org/ // File: program.cpp // Description: The following demonstrates the use of the Utils Namespace // ============================================================================ #include <iostream> #include <string> #include <exception> #include "Utils.h" void display(const std::string& message); int main() { try { // Declare values std::string values[] = { "This is a string.", "Hello!", "Nothing.", "Yes.", "randomize" }; // Declare search std::string search = "Th"; // Check if items starts with search value for (const auto& value : values) { std::cout << "'" << value << "' starts with '" << search << "': " << (Utils::startsWith(value, search) ? "True" : "False") << std::endl; } display(""); // Declare values std::string values2[] = { "This is a string.", "Hello!", "Nothing.", "Yes.", "randomize" }; // Declare search std::string search2 = "."; // Check if items ends with search value for (const auto& value : values2) { std::cout << "'" << value << "' ends with '" << search2 << "': " << (Utils::endsWith(value, search2) ? "True" : "False") << std::endl; } } catch (std::exception& e) { display("\nAn error occurred: " + std::string(e.what())); } std::cin.get(); return 0; } void display(const std::string& message) { std::cout << message << std::endl; }// http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
C++ || How To Read An Entire File Into A String & Write A String To A File Using C++
The following is a module with functions which demonstrates how to write a string to a file and read an entire file to a string using C++.
The functions demonstrated on this page uses fstream to read and write data to and from a file.
1. Read All Text
The example below demonstrates the use of ‘Utils::readAllText‘ to open a text file, read all the text in the file into a string, and then close the file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// Read All Text // Declare path std::string path = "C:\\Users\\Name\\Desktop\\text.txt"; // Read the contents of the file at the specified path std::string contents = Utils::readAllText(path); // Display contents std::cout << contents; // example output: /* ... The contents of the file */ |
2. Write All Text
The example below demonstrates the use of ‘Utils::writeAllText‘ to create a new file, write a specified string to the file, and then close the file. If the target file already exists, it is overwritten.
1 2 3 4 5 6 7 8 9 10 11 12 |
// Write All Text // Declare path std::string path = "C:\\Users\\Name\\Desktop\\text.txt"; // Declare file contents std::string contents = "Kenneth, Jennifer, Lynn, Sole"; // Save contents to the specified path Utils::writeAllText(path, contents); // ... Contents are written to the file |
3. Utils Namespace
The following is the Utils Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
// ============================================================================ // Author: Kenneth Perkins // Date: Dec 9, 2020 // Taken From: http://programmingnotes.org/ // File: Utils.h // Description: Handles general utility functions // ============================================================================ #pragma once #include <string> #include <fstream> #include <limits> #include <stdexcept> namespace Utils { /** * FUNCTION: readAllText * USE: Opens a text file, reads all the text in the file into a string, * and then closes the file * @param path: The file to open for reading * @return: A string containing all text in the file */ std::string readAllText(const std::string& path) { std::ifstream infile(path); if (infile.fail()) { throw std::invalid_argument{ "Unable to read file at path: '" + path + "'" }; } infile.ignore(std::numeric_limits<std::streamsize>::max()); std::streamsize size = infile.gcount(); infile.clear(); infile.seekg(0, infile.beg); std::string contents(size, ' '); infile.read(&contents[0], size); return contents; } /** * FUNCTION: writeAllText * USE: Creates a new file, writes the specified string to the file, * and then closes the file. If the target file already exists, it * is overwritten * @param path: The file to write to * @param contents: The string to write to the file * @return: N/A */ void writeAllText(const std::string& path, const std::string& contents) { std::ofstream outfile(path); if (outfile.fail()) { throw std::invalid_argument{ "Unable to write file at path: '" + path + "'" }; } outfile << contents; } }// http://programmingnotes.org/ |
4. More Examples
Below are more examples demonstrating the use of the ‘Utils‘ Namespace. Don’t forget to include the module when running the examples!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
// ============================================================================ // Author: Kenneth Perkins // Date: Dec 9, 2020 // Taken From: http://programmingnotes.org/ // File: program.cpp // Description: The following demonstrates the use of the Utils Namespace // ============================================================================ #include <iostream> #include <string> #include <exception> #include "Utils.h" void display(const std::string& message); int main() { try { // Declare path std::string path = "C:\\Users\\Name\\Desktop\\text.txt"; // Declare file contents std::string contents = "Kenneth, Jennifer, Lynn, Sole"; // Save contents to the specified path Utils::writeAllText(path, contents); // Read the contents of the file at the specified path std::string contents2 = Utils::readAllText(path); // Display contents display(contents2); } catch (std::exception& e) { display("\nAn error occurred: " + std::string(e.what())); } std::cin.get(); return 0; } void display(const std::string& message) { std::cout << message << std::endl; }// http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.