Jump to content

Search the Community

Showing results for tags 'c++'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • General
    • General Discussion
    • Artificial Intelligence
    • DevOpsForum News
  • DevOps & SRE
    • DevOps & SRE General Discussion
    • Databases, Data Engineering & Data Science
    • Development & Programming
    • CI/CD, GitOps, Orchestration & Scheduling
    • Docker, Containers, Microservices, Serverless & Virtualization
    • Infrastructure-as-Code
    • Kubernetes & Container Orchestration
    • Linux
    • Logging, Monitoring & Observability
    • Security, Governance, Risk & Compliance
  • Cloud Providers
    • Amazon Web Services
    • Google Cloud Platform
    • Microsoft Azure

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Website URL


LinkedIn Profile URL


About Me


Cloud Platforms


Cloud Experience


Development Experience


Current Role


Skills


Certifications


Favourite Tools


Interests

Found 15 results

  1. Written by: Jacob Thompson The Apache XML Security for C++ library, code named xml-security-c, is part of the Apache Santuario project. The library implements the XML Digital Signature and the XML Signature specifications, making them available to C++ developers. By default, the library resolves references to external URIs passed in Extensible Markup Language (XML) signatures, allowing for server-side request forgery (SSRF). There is no way to disable this feature through configuration alone, and there is no patch available; the developer must either scan their codebase to find every usage of xml-security-c and override the URI resolver to avoid SSRF, or manually patch and recompile the library to remove the capability entirely. We recommend that C++ developers using XML audit their code bases for usage of this library and determine whether they have introduced a security vulnerability, and if so, modify their code to avoid SSRF. Background Server-side request forgery (SSRF) is a class of security vulnerability in which an untrusted party tricks a server into making an HTTP request by passing the server a malicious input. Although the attacker usually cannot view the response, requests to the loopback interface (127.0.0.1), RFC 1918 addresses (e.g., 10.0.0.0/8 or 192.168.0.0/16), or any other destination occur from the point of view of the server, allowing requests that would otherwise be restricted by firewall rules or that would be impossible to perform externally. Consider the obvious consequences if a server's uninterruptible power supply offers a web service bound to 127.0.0.1:8080 without authentication and that accepts a GET request http://127.0.0.1:8080/ups/changePowerState?state=off—and what happens if this service is reachable via server-side request forgery. The Extensible Markup Language (XML) is complex and contains many optional features that are not suitable or even useful in the common case of a server accepting untrusted XML documents on an external interface. Some allow cross-site request forgery just by initializing an XML parser in its default configuration and passing an untrusted document. For example, XML External Entities allow a document to define custom entity values (analogous to &lt; meaning < in HTML) to be replaced by the response from an external URL or the contents of a local file rather than a static string. Despite no real-world relevance to a server accepting and parsing untrusted, potentially malicious documents, this feature was enabled by default in many parsers and plagued the 2010s decade; XML External Entity Injection was promoted to an item in the OWASP Top Ten in 2017. Current versions of many XML parsers have now been hardened to treat support for external entities, document-type definitions, schemas, and so forth as an opt-in feature that is disabled by default. In this post, we present a different form of server-side request forgery affecting XML documents. We have found this issue being actively exploited; it was recently addressed by Ivanti in CVE-2024-21893. XML Signatures External URI Feature The XML Signature specification standardizes a way to digitally sign XML documents. The specification includes features that, from a security perspective, introduce additional paths to server-side request forgery into XML, beyond XML External Entity Injection. The XML Signature Syntax and Processing Version 2.0 specification states that "We RECOMMEND XML Signature applications be able to dereference URIs in the HTTP scheme," which, absent other protections such as egress firewall rules, allows for SSRF. This recommendation is carried over from version 1.1 of the specification and therefore version 1.x signatures are also affected. Figure 1 shows a simple XML document that, when parsed by xml-security-c version 2.0.4 and earlier, causes the parser to make an HTTP request to http://www.example.com/ssrf. <test> <ds:Signature xmlns:ds= "http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm= "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> <ds:SignatureMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#Manifest"/> <ds:Reference URI="http://www.example.com/ssrf"> <ds:Transforms> <ds:Transform Algorithm= "http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> <ds:Transform Algorithm= "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <ds:DigestValue>AAAAAAAAAAAAAAAAAAAAAAAAAAA=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>AAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAA==</ds:SignatureValue> <ds:KeyInfo> <ds:X509Data> <ds:X509SubjectName>CN=nobody</ds:X509SubjectName> </ds:X509Data> </ds:KeyInfo> </ds:Signature> </test> Figure 1: Sample XML document to trigger SSRF in affected xml-security-c library Prior Work Other open-source projects have already identified and modified their software to work around this issue. The Shibboleth xmltooling project reported a server-side request forgery vulnerability as CVE-2023-36661 and implemented a workaround in the xmltooling code to override the default, non-secure URI resolver in xml-security-c with a custom one that does nothing. While this mitigation is sufficient to resolve the issue in xmltooling—so long as every possible instance of xml-security-c is located and fixed—the root cause arguably lies in the xml-security-c library not being secure by default. Fixing the issue in xmltooling rather than upstream did not help other users of xml-security-c who were not aware of the need to reconfigure it. Dangerous XML features such as the ability to make external network requests just by parsing a document should, in our view, be disabled in the default configuration and then only enabled when parsing documents from a trusted source. In fact, a different library under the Apache Santuario project, Apache XML Security for Java, has a "secure validation" feature that is enabled by default. Among other characteristics, the secure validation feature "[d]oes not allow a Reference to call the ResolverLocalFilesystem or the ResolverDirectHTTP (references to local files and HTTP resources are forbidden)." Thus, Java developers, unlike C++ developers, are already protected against SSRF in the default configuration of the Java port of the library. The secure validation feature never made it to the C++ version. Disclosure Mandiant reported the non-secure default configuration in xml-security-c to the Apache Software Foundation (ASF). As external URI resolution is a legitimate feature in the XML Digital Signature specification, the ASF did not issue a CVE or a new release of xml-security-c. The Apache Santuario project did add a new disclaimer for xml-security-c shown in Figure 2, suggesting that XML Signatures and XML Encryption are difficult to implement securely; that xml-security-c is not secure by default and does not provide hardening configuration options; and that the library is not modular, making it difficult to ever add such features. Going forward, Apache Santuario is no longer supported as a standalone library, and the Shibboleth project will be taking over the project as a component of Shibboleth only. The developers suggest finding another solution. Figure 2: Apache Santuario added a disclaimer suggesting to not use the xml-security-c library Recommendations C++ developers should first scan their projects to determine if they use the Apache xml-security-c library. If so, the software may have a server-side request forgery vulnerability unless the code is patched. In some cases, usage of xml-security-c may be very limited, or it may be inconvenient to recompile the library when it is obtained in binary form. If developers can pinpoint each use of the XSECProvider class, they can call the setDefaultURIResolver method on the XSECProvider object, passing a custom implementation of XSECURIResolver that simply does nothing. This avoids the need to recompile xml-security-c and ensures the software remains secure if it is ever linked against the stock xml-security-c. An alternative, and in our view superior approach, is to patch the xml-security-c library to make it secure by default with regard to URI resolution. Mandiant developed a patch to supersede the vulnerable XSECURIResolverXerces with a new default XSECURIResolverNoop that does nothing, thus fixing the SSRF. By applying the patch and recompiling, the library will not be susceptible to this form of SSRF. Note that any legitimate uses of external URIs would need to be changed to manually specify XSECURIResolverXerces as the default URI resolver. The patch is available for download now (note: the download is a ZIP file, which contains the patch as a TXT file). View the full article
  2. Rust developers at Google are twice as productive as C++ teamsView the full article
  3. In C++, Vector is a one dimensional data structure which dynamically increases itself based on the requirement. Data organization (insertion/modification/deletion) can be done efficiently in this data structure. Its applications include the following: Representing the mathematical vectors in scientific and engineering applications Queues, stacks can be implemented using this data structure, etc. Most of the common CRUD operations and functions related to this data structure are discussed scenario-wise in detail with syntax and code snippets. Topic of Contents: Insert an Element into a Vector Insert Multiple Elements into a Vector Access the Elements from a Vector Update the Element in a Vector Remove a Specific Element from a Vector Remove All Elements from a Vector Union of Vectors Intersection of Vectors Check Whether the Vector Is Empty or Not Traverse a Vector Using Const_Iterator Traverse a Vector Using Reverse_Iterator Push the Elements into the Vector Pop the Elements from the Vector Swap the Vectors Fetch the First Element from the Vector Fetch the Last Element from the Vector Assign New Values to a Vector Extend the Vector Using Emplace() Extend the Vector Using Emplace_Back() Maximum Element of a Vector Minimum Element of a Vector Sum of Elements in a Vector Element-Wise Multiplication of Two Vectors Dot Product of Two Vectors Convert a Set into a Vector Remove the Duplicate Elements Convert a Vector into a Set Remove the Empty Strings Write a Vector to a Text File Create a Vector from a Text File Insert an Element into a Vector The std::vector::insert() function in C++ STL is used to insert the elements at the specified position. Syntax: vector.insert(position, element); Let’s utilize this function and pass the first position as a parameter that specifies the position where the element has to be inserted and provide the element as the second parameter. The begin() function can be utilized here to return an iterator that points to the first element of the input vector. By adding the position to this function, the element is inserted at that position. Let’s create the “student_names” vector of type string and insert two strings at the first and second positions, one after another, using the insert() function. #include <bits/stdc++.h> using namespace std; main() { // Initialising the vector - student_names vector<string> student_names; cout << "Existing vector:\n"; for (auto i : student_names) cout << i << endl; // Insert "Sravan Kumar" at the first position student_names.insert(student_names.begin() + 0, "Sravan Kumar"); // Insert "Sravan Kumar" at the second position student_names.insert(student_names.begin() + 1, "Lalitha"); cout << "Final vector:\n"; for (auto j : student_names) cout << j << endl; } Output: Previously, the “student_names” vector was empty. After insertion, the vector holds two elements. Insert Multiple Elements into a Vector We use the same function which is std::vector::insert() in this scenario. But we need to pass the extra/different parameters to the same function to insert multiple elements into a vector. Scenario 1: Inserting a Single Element Multiple Times In this scenario, we add the same element multiple times. Syntax: vector.insert (position, size, element); To do this, we need to pass the size as the second parameter to the insert() function. The total parameters that are passed to this function is three. Here: The position parameter specifies the element position to be inserted. If the size is greater than 1, the start position index will be the position. The size parameter specifies the number of times an element is to be inserted. The element parameter takes the element to be inserted into a vector. Consider the “student_names” vector with two strings. Insert the “Lavanya” strings five times at the second position. #include <bits/stdc++.h> using namespace std; main() { // Initialising the vector - student_names vector<string> student_names{"Sravan Kumar","Lalitha"}; cout << "Existing vector:\n"; for (auto i : student_names) cout << i << endl; // Insert "Lavanya" at the second position 5 times student_names.insert(student_names.begin() + 1,5, "Lavanya"); cout << "\nFinal vector:\n"; for (auto j : student_names) cout << j << endl; } Output: In the existing vector, “Sravan Kumar” is in the first position and “Lalitha” is in the second position. After inserting “Lavanya” five times (from the second position to the sixth position), “Lalitha” moved to the seventh position (last). Scenario 2: Inserting Multiple Elements In this scenario, we add the different elements at a time from another vector. We also use the same function here but the syntax and parameters will change. Syntax: vector.insert (position, first_iterator, second_iterator); To do this, we need to pass the size as the second parameter to the insert() function. The total parameters that are passed to this function is three. Here: The position parameter specifies the element position to be inserted. The “first_iterator” specifies the starting position from which the elements are to be inserted (basically, using the begin() function, an iterator is returned which points to the first element that is present in the container). The “second_iterator” specifies the ending position until which the elements are to be inserted (basically, using the end() function, an iterator is returned which points next to the last point that is present in the container). Create two vectors, “marks1” and “marks2”, of integer type. Insert all the elements that are present in the “marks2” vector into the first position of the “marks1” vector. #include <bits/stdc++.h> using namespace std; main() { // Initialising the vector - marks1 vector<int> marks1{100,89,90,78,98}; cout << "First vector:\n"; for (auto i : marks1) cout << i << endl; // Initialising the vector - marks2 vector<int> marks2{56,45,65}; cout << "Second vector:\n"; for (auto j : marks2) cout << j << endl; marks1.insert(begin(marks1), begin(marks2), end(marks2)); // Final vector cout << "First-Final vector:\n"; for (auto x : marks1) cout << x << " "; } Output: The first vector (marks1) holds five elements and the second vector (marks2) holds three elements. We passed the begin (marks1), begin(marks2), end(marks2) parameters to the “insert” function such that all the elements that are present in the second vector are iterated and inserted into the first vector at the beginning. So, the first vector holds eight elements. Access the Elements from a Vector 1. Using the [] Operator In some scenarios, you may have a requirement to return only the specific elements from the vector. Returning all the elements is not needed. So, to return only the specific elements based on the index, the index operator and at() functions are utilized. Syntax: vector[index_position] In C++, indexing starts from 0 for any data structure. If the element does not exist, it returns empty (No error or a warning is raised). Consider the “products” vector with five items. Access all the elements one by one using the index position. #include <bits/stdc++.h> using namespace std; main() { // Create vector - products with 5 strings vector<string> products{"soap","shampoo","oil","fruits","vegetables"}; //Accessing elements from the products cout << "First Element: " << products[0] << endl; cout << "Second Element: " << products[1] << endl; cout << "Third Element: " << products[2] << endl; cout << "Fourth Element: " << products[3] << endl; cout << "Fifth Element: " << products[4] << endl; // Try to access 9th element cout << "Ninth Element: " << products[8] << endl; } Output: There is no element present at index 8. So, empty is returned. 2. Using the At() Function At() is a member function which is similar to the previous use case but it returns the “std::out_of_range” exception when the index out of range is provided to it. Syntax: vector.at(index_position) We need to pass the index position to this function. Consider the “products” vector with five items. Access all the elements one by one using the index position and try to access the element that is present at the 9th position. #include <bits/stdc++.h> using namespace std; main() { // Create vector - products with 5 strings vector<string> products{"soap","shampoo","oil","fruits","vegetables"}; //Accessing elements from the products cout << "First Element: " << products.at(0) << endl; cout << "Second Element: " << products.at(1) << endl; cout << "Third Element: " << products.at(2) << endl; cout << "Fourth Element: " << products.at(3) << endl; cout << "Fifth Element: " << products.at(4) << endl; //Accessing the elements not in the vector cout << "Ninth Element: " << products.at(8) << endl; } Output: An error occurs for accessing the 9th element: terminate called after throwing an instance of 'std::out_of_range' what(): vector::_M_range_check: __n (which is 8) >= this->size() (which is 5) Update an Element in a Vector 1. Using the [] Operator Using the index position, we can update the element in the vector. The [] operator takes the index position of the element that has to be updated. The new element will be assigned to this operator. Syntax: Vector[index_position] = Element Consider the “student_marks” vector with five values. Update the elements present at indices 1 and 3. #include <iostream> #include <vector> using namespace std; main() { // Create vector - student_marks vector<int> student_marks{ 98,78,90,67,89 }; cout << "Existing marks: " <<endl; for (int itr : student_marks) cout << itr << endl; // Update element at index-3 with 100 student_marks[3]=100; // Update element at index-1 with 60 student_marks[1]=60; cout << "Final marks: " <<endl; for (int itr : student_marks) cout << itr << endl; } Output: We can see that the final vector holds the update elements at indices 1 and 3. 2. Using the At() Function Similar to the index operator, at() is basically a member function which updates the value based on the index in an iterator. If the index that is specified inside this function doesn’t exist, the “std::out_of_range” exception is thrown. vector.at(index_position) = Element Consider the “products” vector with five items. Update all the elements present in the vector with other elements. #include <bits/stdc++.h> using namespace std; main() { // Create vector - products with 5 strings vector<string> products{"soap","shampoo","oil","fruits","vegetables"}; cout << "Existing Products: " <<endl; for (string itr : products) cout << itr << endl; //Updating all the strings products.at(0) = "Cake"; products.at(1) = "Chocolate"; products.at(2) = "Fruits"; products.at(3) = "Onions"; products.at(4) = "Soft-drinks"; cout << "\nFinal Products: " <<endl; for (string itr : products) cout << itr << endl; } Output: Remove a Specific Element from a Vector In C++, the std::vector::erase() function is used to remove a specific element/range of elements from a vector. The elements are removed based on the iterator positions. Syntax: vector.erase (iterator position) Let’s see the syntax for removing the specific element from a vector. We can utilize the begin() or end() functions to get the position of the element that is present in the vector to be removed. Consider the “products” vector with five items. Remove the third element by specifying the begin() iterator. Begin() points to the first element in the vector. If we add two to this function, it points to the third element. Remove the last element by specifying the end() iterator. End() points to the last element in the vector. #include <bits/stdc++.h> using namespace std; main() { // Create vector - products with 5 strings vector<string> products{"soap","shampoo","oil","fruits","vegetables"}; cout << "Existing Products: " <<endl; for (string itr : products) cout << itr << endl; // Remove 3rd element products.erase(products.begin()+2); cout << "\nAfter removing 3rd element:\n"; for (string itr : products) cout << itr << endl; // Remove last element products.erase(products.end()); cout << "\nAfter removing the last element:\n"; for (string itr : products) cout << itr << endl; } Output: Now, there are only three elements (“soap”, “shampoo”, “fruits”) that exist in the “products” vector. Remove All Elements from a Vector Scenario 1: Remove a Range of Elements from a Vector Let’s use the std::vector::erase() function to remove multiple elements in a range. Syntax: vector.erase (iterator first, iterator last) The two iterators (begin() points to the first element and end() points to the last element functions) are used to specify the range. Consider the “products” vector with five items and remove all the elements from the second position. To achieve this, the first iterator is begin (products)+1 that points to the second element and the second iterator is end (products). #include <bits/stdc++.h> using namespace std; main() { // Create vector - products with 5 strings vector<string> products{"soap","shampoo","oil","fruits","vegetables"}; cout << "Existing Products: " <<endl; for (string itr : products) cout << itr << endl; // Remove all the elements from the second position products.erase(begin(products)+1,end(products)); cout << "\nFinal Products:\n"; for (string itr : products) cout << itr << endl; } Output: Now, there is only one element (“soap”) that is present in the “products” vector. Scenario 2: Remove All Elements from the Vector Let’s use the std::vector::clear() function to remove all the elements from the vector. Syntax: vector.clear() No parameters are passed to this function. Consider the same vector that was utilized in the first scenario and remove all the elements using the clear() function. #include <bits/stdc++.h> using namespace std; main() { // Create vector - products with 5 strings vector<string> products{"soap","shampoo","oil","fruits","vegetables"}; cout << "Existing Products: " <<endl; for (string itr : products) cout << itr << endl; // Remove all the elements from the products products.clear(); cout << "\nFinal Products:\n"; for (string itr : products) cout << itr << endl; } Output: We can see that there are no elements in the “products” vector. Union of Vectors It is possible to perform the UNION operation on vectors using the std::set_union() function. Union returns the unique elements from the vectors by ignoring the duplicate elements. We need to pass both the iterators to this function. Along with this, an output iterator has to be passed which stores the result that is returned by both the iterators. Syntax: set_union (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator res); Here: The “first1” points to the first element of the first iterator (vector). The “last1” points to the last element of the first iterator (vector). The “first2” points to the first element of the second iterator (vector). The “last2” points to the last element of the second iterator (vector). Create two vectors – “subjects1” and “subjects2” – of type integer. Sort the two vectors using the sort() function by passing the iterators. Create an output vector (iterator). Find the union of these two vectors using the std::set_union() function. Use begin() as the first iterator and end() as the last iterator. Iterate the output vector to display the elements that are returned by the function. #include <algorithm> #include <iostream> #include <vector> using namespace std; main() { // Create vector - marks1 vector<int> marks1={100,90,80,70,60}; // Create vector - marks2 vector<int> marks2={80,90,60,70,100}; // Sort both the vectors sort(marks1.begin(), marks1.end()); sort(marks2.begin(), marks2.end()); vector<int> outputVector(marks1.size()+ marks2.size()); vector<int>::iterator i, s; i = set_union(marks1.begin(), marks1.end(), marks2.begin(),marks2.end(), outputVector.begin()); cout << "\nmarks1 U marks2:\n"; for (s = outputVector.begin(); s != i; ++s) cout << *s << " " << '\n'; } Output: There are only five unique elements in both vectors (subjects1 and subjects2). Intersection of Vectors Finding the intersection of two vectors can be possible using the std::set_intersection() function. Intersection returns the elements that are present in both vectors. Syntax: set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator res); The parameters that are passed to the set_union() function can be passed to this set_intersection() function, too. Create two vectors – “subjects1” and “subjects2” – of type integer. Sort the two vectors using the sort() function by passing the iterators. Create an output vector (iterator). Find the intersection of these two vectors using the std::set_intersection() function. Use begin() as the first iterator and end() as the last iterator. Iterate the output vector to display the elements that are returned by the function. #include <algorithm> #include <iostream> #include <vector> using namespace std; main() { // Create vector - marks1 vector<int> marks1={100,10,80,40,60}; // Create vector - marks2 vector<int> marks2={50,90,60,10,100}; // Sort both the vectors sort(marks1.begin(), marks1.end()); sort(marks2.begin(), marks2.end()); vector<int> outputVector(marks1.size()+ marks2.size()); vector<int>::iterator i, s; i = set_intersection(marks1.begin(), marks1.end(), marks2.begin(),marks2.end(), outputVector.begin()); cout << "\nmarks1 ∩ marks2:\n"; for (s = outputVector.begin(); s != i; ++s) cout << *s << " " << '\n'; } Output: There are only three elements present in both vectors (subjects1 and subjects2). Check Whether the Vector Is Empty or Not Before working on vectors, it is important to check whether the vector is empty or not. It is also a good practice in software projects to check whether the vector is empty or not before doing the operations like CRUD operations, etc. 1. Using the Std::vector::empty() This function returns 1 if the vector is empty (doesn’t contain any element). Otherwise, 0 is returned. No parameter is passed to this function. 2. Using the Std::vector::size() The std::vector::size() function returns the integer that represents the total number of elements that are present in the vector. Create two vectors – “college1” and “college2”. “College1” holds five elements and “college2” is empty. Apply both functions on both vectors and check the output. #include <algorithm> #include <iostream> #include <vector> using namespace std; main() { // Create vector - college1 vector<string> college1={"college-A","college-B","college-C","college-D","college-E"}; // Create vector - college2 vector<string> college2; // empty() cout << college1.empty() << endl; cout << college2.empty() << endl; // size() cout << college1.size() << endl; cout << college2.size() << endl; } Output: The empty() function returns 0 for “college1” and 1 for “college2”. The size() function returns five for “college1” and 0 for “college2”. Traverse a Vector Using the Const_Iterator When you are working on C++ containers like sets, vectors, etc., it is possible to iterate over all the elements that are present in the container without modifying them. The const_iterator is one of the iterators that achieve this scenario. The cbegin() (points to the first element in the vector) and cend() (points to the last element in the vector) are the two functions provided by each container which is used to return the constant iterator to the beginning and end of the container. While iterating the vector, we can utilize these two functions. Let’s create a vector named “departments” with five strings. Declare a const_iterator – ctr of type <string>. Iterate over the departments using the previous iterator using the “for” loop and display it. #include <iostream> #include <vector> using namespace std; main() { // Create vector - departments vector<string> departments={"Sales","Service", "HR","IT","Others"}; vector<string>::const_iterator ctr; // Iterate over the departments using const_iterator - ctr. for (ctr = departments.cbegin(); ctr != departments.cend();ctr++) { cout << *ctr << endl; } } Output: Traverse a Vector Using the Reverse_Iterator The reverse_iterator is also an iterator that is similar to the const_iterator but it returns the elements in reverse. The rbegin() (points to the last element in the vector) and rend() (points to the first element in the vector) are the two functions provided by each container which is used to return the constant iterator to the ending and beginning of the container. Let’s create a vector named “departments” with five strings. Declare a reverse_iterator – rtr of type <string>. Iterate over the departments using the previous iterator using the “for” loop and display it. #include <iostream> #include <vector> using namespace std; main() { // Create vector - departments vector<string> departments={"Sales","Service", "HR","IT","Others"}; vector<string>::reverse_iterator rtr; // Iterate over the departments using reverse_iterator - rtr. for (rtr = departments.rbegin(); rtr != departments.rend();rtr++) { cout << *rtr << endl; } } Output: Push the Elements into the Vector Pushing or appending the elements into a vector is a one-way insertion that can be done using the vector::push_back() function. Syntax: vector.push_back(element) It takes an element to be pushed into the vector as a parameter. Let’s create an empty vector named “departments” with five strings and push two strings one after another using the push_back() function. #include <iostream> #include <vector> using namespace std; main() { // Initialize vector - departments vector<string> departments; cout << "Actual Departments:" << endl; for (auto itr = departments.begin(); itr != departments.end(); ++itr) cout << *itr << endl; // Push "Sales" departments.push_back("Sales"); // Push "IT" departments.push_back("IT"); cout << "\nFinal Departments:" << endl; for (auto itr = departments.begin(); itr != departments.end(); ++itr) cout << *itr << endl; } Output: First, we push the “Sales”. After that, “IT” is pushed into the vector. Now, the “departments” vector holds two elements. Pop the Elements from the Vector If you want to delete the last item that is present in the vector, utilizing the vector::pop_back() function is the best approach. It deletes the last element that is present in the vector. Syntax: vector.pop_back() No parameter is needed for this function. It shows the undefined behaviour if we try to delete the last element from an empty vector. Let’s create an empty vector named “departments” with five strings and delete the last element using the previous function. Display the vector in both cases. #include <iostream> #include <vector> using namespace std; main() { // Initialize vector - departments vector<string> departments={"Sales","IT","Service","Marketing","HR"}; cout << "Actual Departments:" << endl; for (auto itr = departments.begin(); itr != departments.end(); ++itr) cout << *itr << endl; // Delete the last element departments.pop_back(); cout << "\nFinal Departments:" << endl; for (auto itr = departments.begin(); itr != departments.end(); ++itr) cout << *itr << endl; } Output: “HR” is the last element that is present in the “departments” vector. So, it is removed from the vector and the final vector holds “Sales”, “IT”, “Service”, and “Marketing”. Swap the Vectors The vector::swap() function in C++ STL is used to swap all the elements that are present in two vectors. Syntax: first_vector.swap(second_vector) It does not consider the size of the vectors but the vectors should be of the same type (error is thrown if the vector types are different). Let’s create two vectors – “fruits” and “vegetables” – of string type with different sizes. Swap each of them and display the vectors in both cases. #include <iostream> #include <vector> using namespace std; main() { // Initialize vector - fruits vector<string> fruits={"Apple","Mango"}; cout << "Actual Fruits:" << endl; for (auto itr = fruits.begin(); itr != fruits.end(); ++itr) cout << *itr << endl; // Initialize vector - vegetables vector<string> vegetables={"Potato","Tomato","Brinjal"}; cout << "\nActual Vegetables:" << endl; for (auto itr = vegetables.begin(); itr != vegetables.end(); ++itr) cout << *itr << endl; // Swap the elements in both the vectors fruits.swap(vegetables); cout << "\nFruits after swapping:" << endl; for (auto itr = fruits.begin(); itr != fruits.end(); ++itr) cout << *itr << endl; cout << "\nVegetables after swapping:" << endl; for (auto itr = vegetables.begin(); itr != vegetables.end(); ++itr) cout << *itr << endl; } Output: Previously, the “fruits” vector holds two elements and the “vegetables” vector holds three elements. After swapping, the “fruits” vector holds three elements and the “vegetables” vector holds two elements. Fetch the First Element from the Vector In some cases, the requirement is to return only the first element from the vector. The vector::front() function in C++ STL fetches only the first element from the vector. Syntax: vector.front() This function won’t take any parameter. If the vector is empty, an error is thrown. Let’s create two vectors – “fruits” and “vegetables” – of string type and try to fetch the first element separately from the two vectors. #include <iostream> #include <vector> using namespace std; main() { // Create vector - fruits with 2 elements vector<string> fruits={"Apple","Mango"}; // Return the first element cout << fruits.front() << endl; // Initialize vector - vegetables vector<string> vegetables; // Try to return the first element cout << vegetables.front(); } Output: “Apple” is the first element that is present in the “fruits” vector. So, it is returned. But an error is thrown when we try to fetch the first element from the “vegetables” vector since it is empty. Fetch the Last Element from the Vector The vector::end() function in C++ STL fetches only the last element from the vector. Syntax: vector.back() This function won’t take any parameter. If the vector is empty, an error is thrown. Let’s create two vectors – “fruits” and “vegetables” – of string type and try to fetch the last element separately from the two vectors. #include <iostream> #include <vector> using namespace std; main() { // Create vector - fruits with 2 elements vector<string> fruits={"Apple","Mango"}; // Fetch the last element cout << fruits.back() << endl; // Initialize vector - vegetables vector<string> vegetables; // Try to fetch the last element cout << vegetables.back(); } Output: “Mango” is the last element that is present in the “fruits” vector. So, it is returned. But an error is thrown when we try to fetch the last element from the “vegetables” vector since it is empty. Assign New Values to a Vector In some scenarios, if you want to update all the values with the new value or create a vector with the same values, using the vector::assign() function is the best approach. Using this function, we can: Create the vector with all similar elements Modify the existing vector with the same element Syntax: vector.assign(size, value) Two parameters are required to this function. Here: The size specifies the number of elements to be assigned. The value specifies the element to be assigned. Let’s create a vector named “marks1” with five values and update this vector with four elements such that all the elements in the updated vector are equal to 20. #include <algorithm> #include <iostream> #include <vector> using namespace std; main() { // Create vector - marks1 vector<int> marks1={100,90,80,70,60}; cout << "Actual Vector:" << endl; for (int i = 0; i < marks1.size(); i++) cout << marks1[i] << endl; marks1.assign(4, 20); cout << "\nUpdated Vector:" << endl; for (int i = 0; i < marks1.size(); i++) cout << marks1[i] << endl; } Output: Previously, the vector holds five different elements. Now, it holds only four elements and all are equal to 20. Extend the Vector Using Emplace() We already know that new elements are dynamically inserted at any position in a vector. It is possible using the vector::emplace() function. Let’s quickly look at the syntax and parameters accepted by this function. Syntax: vector.emplace(const_iterator position, element) Two mandatory parameters are passed to this function. Here: The first parameter takes the position so that we can insert the element at any position. We can get the position using the begin() or end() iterator function. The second parameter is the element to be inserted into the vector. Consider the “chemicals” vector with two elements. Insert “Manganese” at the first position – begin(chemicals) Insert “Copper” at the last position – end(chemicals) Insert ‘Sulphur’ at the third position – begin(chemicals)+2 #include <algorithm> #include <iostream> #include <vector> using namespace std; main() { // Create vector - chemicals vector<string> chemicals={"Oxygen","CO"}; cout << "Actual Chemicals:" << endl; for (int i = 0; i < chemicals.size(); i++) cout << chemicals[i] << endl; // Insert element at the first position chemicals.emplace(begin(chemicals), "Manganese"); // Insert element at the last position chemicals.emplace(end(chemicals), "Copper"); // Insert element at the third position chemicals.emplace(begin(chemicals)+2, "Sulphur"); cout << "\nFinal Chemicals:" << endl; for (int i = 0; i < chemicals.size(); i++) cout << chemicals[i] << endl; } Output: Now, the final vector holds five elements (provided in the following screenshot). Extend the Vector Using Emplace_Back() An element can be appended (adding at the end of the vector) which can be done using the vector::emplace_back() function. Syntax: vector.emplace_back(element) It is mandatory to pass the element to be appended to the vector as a parameter. Let’s add two elements one after another using the emplace_back() function. #include <algorithm> #include <iostream> #include <vector> using namespace std; main() { // Create vector - chemicals vector<string> chemicals={"Oxygen","CO"}; cout << "Actual Chemicals:" << endl; for (int i = 0; i < chemicals.size(); i++) cout << chemicals[i] << endl; // Insert Manganese at the end of the vector chemicals.emplace_back("Manganese"); // Insert Manganese at the end of the vector chemicals.emplace_back( "Copper"); cout << "\nFinal Chemicals:" << endl; for (int i = 0; i < chemicals.size(); i++) cout << chemicals[i] << endl; } Output: Now, the final vector holds four elements after adding “Manganese” and “Copper”. Maximum Element of a Vector Create a vector with some elements. To find the maximum element that is present in the vector, use the *max_element() function which accepts two iterators as arguments. These two parameters act as the range and the maximum element is returned within the provided range. The starting position is begin() and the last position is end(). *max_element(first_Index,last_Index) Let’s consider a vector named “item_costs” that holds five integer type values and return the maximum element. #include <vector> #include <iostream> #include <algorithm> using namespace std; main() { // Create vector - item_costs vector<int> item_costs={8900,5677,200,1000,2300}; cout << "Cost of Items:\n"; for (int i = 0; i < item_costs.size(); i++) cout << item_costs[i]<< endl; // Return the maximum element from the above vector - item_costs cout << "\nMaximum Cost: "<< *max_element(begin(item_costs),end(item_costs)); } Output: Here, 8900 is the maximum element among all the elements that are present in the ”item_costs” vector. Minimum Element of a Vector Create a vector with some elements. To find the minimum element that is present in the vector, use the *min_element() function which accepts two iterators as arguments. These two parameters act as the range and the minimum element (less than all the other elements) is returned within the provided range. The starting position is begin() and the last position is end(). *min_element(first_Index,last_Index) Utilize the same vector that is created to find the maximum element and find the minimum element using the *min_element() function. #include <vector> #include <iostream> #include <algorithm> using namespace std; main() { // Create vector - item_costs vector<int> item_costs={8900,5677,200,1000,2300}; cout << "Cost of Items:\n"; for (int i = 0; i < item_costs.size(); i++) cout << item_costs[i]<< endl; // Return the minimum element from the above vector - item_costs cout << "\nMinimum Cost: "<< *min_element(begin(item_costs),end(item_costs)); } Output: Here, 200 is the minimum element among all the elements that are present in the “item_costs” vector. Sum of Elements in a Vector To return the sum of all the elements that are present in the vector, the accumulate() function in C++ STL is used. It accepts three parameters. The first parameter takes the first index that represents the starting element in the range (specify the begin() iterator) and the second parameter takes the last index that represents the ending element in the range (specify the end() iterator) . Lastly, we need to pass the initial value of the sum (in our case, it is 0). accumulate(first_index, last_index, initial_val); Create a vector named “item_costs” with five integer type elements and calculate the sum. #include <bits/stdc++.h> using namespace std; main() { // Create vector - item_costs vector<int> item_costs={8900,5677,200,1000,2300}; cout << "Cost of Items:\n"; for (int i = 0; i < item_costs.size(); i++) cout << item_costs[i]<< endl; // Return the sum of all elements in the above vector - item_costs cout << "\nTotal Cost: "<< accumulate(begin(item_costs),end(item_costs),0); } Output: The sum of 8900, 5677, 200, 1000, 2300 is 18077. Element-Wise Multiplication of Two Vectors Create two vectors with type numeric and two vectors must be of the same size (total number of elements present in the first vector = total number of elements present in the second vector). Declare a new vector and use the for loop, perform the multiplication operation on two elements in each iteration, and store the value into the created vector using the push_back() function. for(int itr=0; i<first_vec.size(); itr++) { result_vector.push_back(first_vec[itr]*sec_vec[itr]); } Display the elements that are present in the resultant vector by iterating it. Create a vector named “item_costs” with five integer type elements and calculate the sum. #include <bits/stdc++.h> using namespace std; main() { // Create two vectors - products1 and products2 with 5 elements each vector<int> products1={10,20,30,40,50}; vector<int> products2={50,40,30,70,60}; vector<int> result_products; // Perform element wise multiplication for(int i=0;i<products1.size();i++){ result_products.push_back(products1[i]*products2[i]); } // Display the resultant vector cout << "Vector Multiplication:\n"; for (int res : result_products) cout << res << endl; } Output: Iteration-1: 10 * 50 => 500 Iteration-2: 20 * 40 => 800 Iteration-3: 30 * 30 => 900 Iteration-4: 40 * 70 => 2800 Iteration-5: 50 * 60 => 3000 Dot Product of Two Vectors In the case of C++ vectors, the dot product is defined as the “sum of the products of the corresponding entries of the two sequences of vectors”. Syntax: inner_product(Vector1 first, Vector1 last, Vector2 first, Initial_Val) Use the inner_product() function to return the dot product. This function takes four required parameters. Here: The first parameter refers to an iterator that points to the beginning of the first vector (specify using the begin() function). The second parameter refers to an iterator that points to the ending of the first vector (specify using the end() function). The third parameter refers to an iterator that points to the beginning of the second vector (specify using the begin() function). The initial value has to be passed as the last parameter which is an integer for the accumulation of the dot product. Utilize the same program that is created for the multiplication of two vectors and use the innsr_product() function to find the dot product of the two vectors. #include <bits/stdc++.h> using namespace std; main() { // Create two vectors - products1 and products2 with 5 elements each vector<int> products1={10,20,30,40,50}; vector<int> products2={50,40,30,70,60}; // Display the resultant vector cout << "Dot Product of products1 and products2: "; cout << inner_product(begin(products1),end(products1),begin(products2), 0); } Output: (10 * 50) + (20 * 40) + (30 * 30) + (40 * 70) + (50 * 60) => 500 + 800 + 900 + 2800 + 3000 => 8000 Convert a Set into a Vector There are many ways to convert a set into a vector by passing all the elements that are raised in a set into a vector. The best and simplest way is using the std::copy() function. Syntax std::copy(sourceIterator first, sourceIterator last, destinationIterator first) Use the std::copy() function which inserts the elements from a set into the vector. It takes three parameters. Here: The first parameter refers to the source iterator that points to the first element in the iterator. Here, set is the source iterator that is specified using the begin() function. Similarly, the second parameter points to the last element (end() function). The third parameter refers to the destination iterator that points to the first element (specified using the begin() function) in the iterator. Let’s create a set with five students and copy all the elements into a vector using the previous function. #include <bits/stdc++.h> using namespace std; main() { // Create a set - students with 5 elements set<string> students={"Sravan","Bobby","Madhu","Meghana","Lavanya"}; cout << "Set:\n"; for (string i : students) cout << i << endl; // Create Vector - student_vcof size equal to the size of the set vector<string> student_vc(students.size()); // Insert elements from a Set - students into a Vector - student_vc. copy(students.begin(), students.end(), student_vc.begin()); cout << "\nVector:\n"; for (string i : student_vc) cout << i << endl; } Output: Now, all the elements that are present in the “Students” set are copied into the “students_vc” vector. Remove the Duplicate Elements First, we need to sort the elements in the vector so that all the duplicate elements will be adjacent to each other using the std::sort() function. std::sort(Vector first, Vector last); Use the std::unique() function so that the duplicate elements will be selected. At the same time, use the erase() function to remove the duplicates that are returned by the std::unique() function. The order of elements may change in the final vector. vector.erase(std::unique(Vector first, Vector last), Vector last)) Create the “students” vector with 10 elements and return the vector by removing the duplicates. #include <bits/stdc++.h> using namespace std; main() { // Create a vector - students with 10 elements vector<string> students={"Sravan","Bobby","Madhu","Meghana","Lavanya", "Sravan","Bobby","Madhu","Meghana","Lavanya"}; cout << "Students:\n"; for (string i : students) cout << i << " "; // Sort all the elements in the students vector. sort(begin(students), end(students)); // Use the unique() function to remove the duplicates with the erase() function students.erase(unique(begin(students), end(students)), end(students)); cout << "\n\nUnique Students:\n"; for (auto itr = cbegin(students); itr != cend(students); ++itr) { cout << *itr << " "; } } Output: Now, all the elements are unique in the vector. Convert a Vector into a Set Set does not allow the duplicate elements. If you are typing to insert a vector into a set with duplicates, they will be ignored. We use the same std::copy() function that was used in the previous scenario that converted the set into a vector. In this scenario: The first parameter takes the vector as the source iterator that is specified using the begin() function. The second parameter takes the vector as the source iterator that is specified using the end() function. Pass the std::inserter() function which is used to overwrite/copy the elements automatically at a specific position in the set by providing the set and iterator that point to the end of the set as parameters. Let’s create a vector with 10 integers and copy the elements into a set. #include <bits/stdc++.h> using namespace std; main() { // Create a set - marks with 10 values vector<int> marks={12,34,56,78,65,78,90,90,78,34}; cout << "Vector:\n"; for (int i : marks) cout << i << " "; // Create Set - marks_set of the size equal to the size of the vector set<int> marks_set; // Insert elements from a Set - students into a Vector - student_vc. copy(begin(marks),end(marks), inserter(marks_set,end(marks_set))); cout << "\n\nSet:\n"; for (int i : marks_set) cout << i << " "; } Output: The existing vector named “marks” has 10 values. After copying it into the “marks_set” set, it holds only six elements because the other four elements are duplicated. Remove the Empty Strings There is no use of empty strings that are present in a vector. It is a good practice to remove the empty strings that are present in the vector. Let’s see how to remove the empty strings from the C++ vector: Iterate the vector using the “for” loop. In each iteration, check if the element is empty (“”) or not using the “==” operator with the at() member function. Using the std::erase() function, remove the empty strings after checking the previous condition. Repeat step2 and step3 until the end of the vector. Let’s create the “companies” vector with 10 strings. Among them, five are empty and we remove them by implementing the previous approach. #include <iostream> #include <vector> using namespace std; main() { vector<string> companies { "Company-A", "", "Company-B", "", "Company-C", "","Company-D","","",""}; // Iterate over companies // and remove empty elements using erase() for ( int itr = 1 ; itr < companies.size(); ++itr) { if ( companies.at(itr) == "" ) { companies.erase(companies.begin() + itr); --itr; } } // Display the vector for(auto& i: companies) { cout << i << endl; } } Output: Now, the “companies” vector holds the non-empty strings. Write a Vector to a Text File Let’s discuss how to write all the elements that are present in a vector to a file using the vector indices using the fstream. Push some elements into it using the push_back function after initializing the vector. Use the open() function from the “fstream” library with the mode as out. Traverse each element that is present in the vector using the indices in a “for” loop and write each element to the provided file. Finally, close the file. Let’s implement the previous approach by running a C++ code. #include <vector> #include <string> #include <iostream> #include <fstream> using namespace std; main() { // Create a Vector - v_data // and push two elements into it. vector<string> v_data; v_data.push_back("Welcome"); v_data.push_back("to LinuxHint"); fstream f; // Open the file f.open("written_file.txt",ios_base::out); // Iterate each element of the vector and write to the file one by one. for(int i=0;i<v_data.size();i++) { f<<v_data[i]<<endl; } // Close the file f.close(); } Output: The “v_data” vector holds two elements and a file is created in the path where the program is executed with the elements that are present in the vector. Create a Vector from a Text File We learned how to write the elements that are present in the vector to a text file. Here, let’s create a vector from the content that is present in the text file. Create an “ifstream” variable which is used to read the information from the text file in which we create the vector from the file. Create an empty vector to store the file content and use an empty string variable as a flag to check the end of the file. Read the next line from the file until it reaches the end (basically using the “while” loop). Use the push_back() function to read the next line and push it into the vector. Display the line that is present in the line separately to see the elements that are present in the vector on the console. Let’s implement the previous approach by running the C++ code. Let’s consider the “data.txt” file with the following content. Here, the name of the vector is “v_data”. #include <bits/stdc++.h> using namespace std; main() { // Open the text file - data ifstream file("data.txt"); // Create vector - v_data of type - string vector<string> v_data; string var; // Read the next line from the data.txt // till it reaches the end. while (file >> var) { // Read the next line and push into the v_data v_data.push_back(var); } // Display the line present in the line separately. copy(v_data.begin(), v_data.end(),ostream_iterator<string>(cout, "\n")); } Output: We can see that “v_data” holds five elements that came from the file. Conclusion In this long article, we explored all the possible examples that are used in real-time applications related to vectors in the C++ programming language. Each example is explained with syntax, parameters, and example with output. Comments are added in each code to get a clear understanding of the code. View the full article
  4. This article is about pointer arithmetic in C++. Pointers are variables that store the memory address of the data. Pointer arithmetic is a powerful hallmark in the world of C++ programming language that permits us to deal with different arithmetic operations in which the addition, multiplication, division, increment, decrement, and subtraction involve a pointer to develop the new memory address in our memory buffers. A pointer arithmetic easily creates the dynamic memory allocation. In this C++ article, we will learn how to manipulate the memory address in different ways with the help of pointers and provide proper guidelines and examples. Scenario 1: Pointer Performs the Increment and Decrement Operations Here, we will learn about pointer manipulation to produce a different memory addresses that have different purposes. The incrementing and decrementing pointers are also the leverage pointers arithmetic that increase or decrease the address by a factor of one multiplied by the size of the data type to which they are pointing. The code snippet related to this scenario is attached in the following: #include<iostream> using namespace std; const int Arr_Max = 5; int main () { int var[Arr_Max] = {20, 150, 270}; int *ptr; //declare pointer ptr = var; for (int i = 0; i < Arr_Max; i++) { std::cout << "Memory address of the element is : [" << i << "] = "; std::cout << ptr << endl; cout << "Value against the address is [" << i << "] = "; cout << *ptr << endl; std::cout<<"pointer incremented successfully"<<endl; ptr++; } std::cout<<"Pointer address before decrement"<<ptr<<endl; ptr--; std::cout<<"Pointer address after decrement"<<ptr<<endl; return 0; } Here, we define a required library in the code at the very start: “<iostream>”. We define a memory allocation to reserve the space in memory which is “Arr_Max=5”. In the main function, we initialize the array and pass the memory size to that array. Next, the “ptr” pointer declaration is also needed to point out the memory address in memory. We pass the array to the pointer to access the address. As we all know, arrays always contain multiple items in different locations. So, we needed a loop with the “help” pointer to access every element of an array. Every time the loop executes, we get the memory address and values against this address with the help of the pointer arithmetic “ptr++” increment operator that shifts the memory address to the next address of the memory. The loop execution cycle depends upon the size of an array. Outside the loop, we want to get the pointer back to the previous memory address by just using the “ptr- -” decrement pointer . Execute this code by clicking the Execute>Compile & Run option and you will get the following output: Hopefully, this output is easy to understand. The memory address and value are changed. Shifting the pointer from one location is only possible from the increment pointer arithmetic in C++. Scenario 2: Subtracting Two Pointers in C++ In this scenario, we will learn how to subtract two or more pointers in C++. All the arithmetic operations in which the subtraction comes are vital processes as we can only subtract two pointers simultaneously if and only if they have the same data type. The other operations like addition, multiplication, and division are not possible in the pointer because they make no sense in memory addressing. The code snippet is attached in the following: #include <iostream> int main() { int Arra[] = {23, 36, 42, 51, 62,77,89,96,100}; int *ptrr1 = &Arra[3]; // Pointer to the third element (42) int *ptrr2 = &Arra[6]; // Pointer to the sixth element (89) ptrdiff_t ptrsubtract= ptrr2 - ptrr1; std::cout << "Difference between these address is: " << ptrsubtract << " elements" << std::endl; return 0; } The subtraction operation is finding the difference between the memory address in C++. In the main function, we take an array that contains different values at different indexes. In an array, every index has a different memory location. We can only find the difference between two pointers with the help of a pointer arithmetic. Here, we use a special pointer type “ptrdiff_t” that must be used to find the differences between two or more pointers in C++. The output of this code is attached in the following: The difference between these addresses is by element vise which is 3. Scenario 3: Compare Two or More Pointers in C++ In this scenario, we will learn how to compare the different pointers in C++ using different relational operators like “==”, “<=”, “>=”, “<”, ”>”. We can only compare the pointers if they point to the address of elements of the same array. Remember that comparing two pointers with different types can cause undefined behavior. The code snippet that is related to the pointer comparison is mentioned in the following: #include <iostream> using namespace std; int main() { int arr1[10]={4,7,9,11,14,16,18,20,22,25}; int *ptr1=&arr1[3]; int *ptr2=&arr1[6]; int *ptr3=&arr1[8]; int *ptr4=&arr1[9]; if(ptr1==ptr2) { std::cout<<"pointers are equal"<<endl; } else if(ptr3<=ptr4) { std::cout<<"ptr3 is less than or equal than ptr4"<<endl;; } else { std::cout<<"pointers are not compared at any stage"<<endl; } return 0; } Here, we take an array with 10 elements. We declare four pointers that point to a different index of the array. After that, we compare these four pointers at different conditions as seen in the given code. In the “if” condition, check if the “ptr1” pointer is equal to the “ptr2” pointer, and then print the “pointers are equal”. When we have multiple conditions where we use the “else if” condition to check if the “ptr3” pointer is less than equal to the “ptr4” pointer. After all that, click on the Execute > Compile & Run option. The output of this code is attached in the following: It displays a valid condition on the console screen and exits the compilation. The “ptr3” pointer contains a value that is less than or equal to the “ptr4” pointer pointing value. Scenario 4: Display an Odd number with Pointer Arithmetic Here, we will see how we can dynamically allocate the memory for an array of an integer. The code snippet related to this case is given in the following: #include <iostream> int main() { int numbers[] = {1, 12, 33, 24, 15, 776, 71, 18, 29, 50}; int *ptrr = numbers; std::cout << "Odd numbers in the arrays: "; for (int i = 0; i < 10; ++i) { if (*ptrr % 2 != 0) { std::cout << *ptrr << " "; } ptrr++; } std::cout << std::endl; return 0; } In the main function, we take an array that contains 10 elements. We need a pointer that points out all the elements in the array to check the odd number in the array. In the “for” loop, check the odd number by dividing the current element of an array. The pointer counter is incremented after checking one element of an array. After executing the code, the output is displayed on the console screen that is given in the following: This way, we can display the odd numbers using the pointer arithmetic on the console screen. Conclusion We conclude here that the pointer arithmetic is the most effective tool that performs different operations in C++. Make sure that the pointer increments or decreases the value of an array that has the same data type. We can compare the values of an array by their memory addresses with the help of pointer arithmetic in the C++ programming language. We can traverse the array and manage the memory easily with the help of pointer arithmetic. View the full article
  5. In C++ programming, there are various situations in which we need to check the conditions. Sometimes, we need to satisfy multiple conditions simultaneously. We utilize the “nested if” condition in C++ programming for this. If we place the “if” condition inside the other “if”, it is said to be the “nested if”. When the first “if” condition is satisfied, we move inside that “if” where we place another “if”. Then, it checks the “if” condition which is placed inside the first “if” condition, and so on. It returns the result which we place inside the “if” when all the conditions are satisfied. Example 1: Let’s do some codes where we utilize the “nested if”. To begin the C++ code, we include the “iostream” header file here and then the “std” namespace. After this, we place the “main()”driver code and initialize three variables, “n1”, “n2”, and “n3”, with the values of “20”, “10”, and “2”, respectively. Then, we utilize the “if” condition here in which we check whether “n1” is greater than “n2”. If this condition is satisfied, we move ahead inside this “if” where we add another “if” condition. Now, the second “if” checks the “n1” values that are greater than “n3”. If this “nested if” condition is also satisfied, the statement below this is executed in which we place the “cout” statement. So, it prints that statement if both conditions of the “nested if” are satisfied in this code. If any of the conditions is false, it will not display any message on the console. Code 1: #include <iostream> using namespace std; int main() { int n1 = 20, n2 = 10, n3 = 2; if (n1 > n2) { if (n1 > n3) { cout << " n1 is the largest values which is " << n1 << endl; } } return 0; } Output: Here, it shows the statement on the console which means both “if” conditions of the “nested if” are true. The statement that we added inside the “nested if” is also rendered here. Example 2: The “std” namespace and the “iostream” header file are included here to start the C++ code. The “main()”driver code is then inserted, and three variables, “var1”, “var2”, and “var3”, are initialized with the values of “8”, “91,” and “32”, correspondingly. Next, we use the “if” condition to determine whether “val1” is smaller than “val2”. If this condition is met, we continue within the “if” condition and add another “if” condition. The second “if” now checks to see if the “val1” value is smaller than “val3”. If this “nested if” condition is also fulfilled, the statement that is placed inside the “cout” is run in the following. Thus, if both of the “nested if” conditions are met in this code, it prints that statement. The console won’t show any message if the conditions are untrue. Code 2: #include <iostream> using namespace std; int main() { int var1 = 8, var2 = 91, var3 = 32; if (var1 < var2) { if (var1 < var3) { cout << " var1 is the smallest values which is " << var1 << endl; } } return 0; } Output: The statement that we added within the “nested if” is now rendered here. The message on the console indicates that both of the “if” conditions of the “nested if” are true. Example 3: Here in the “main()”, we initialize the variables named “x”, “y”, and “z” with the values of “11”, “22”, and “33”, respectively. Then, we utilize an “if” in which we place the condition that is “x == 11” and place another “if” inside this “if” which is the “nested if” where we add the “y == 22” condition. This “nested if” is implemented only when the first “if” condition is fulfilled. After this, we utilize one more “if” inside the second “if” which is executed when both “if” are satisfied which we previously added. The third “if” contains the “z == 33” condition and we include the “cout” inside the last “if” condition. This will only execute when all the three “if” conditions are true. Code 3: #include <iostream> using namespace std; int main() { int x = 11, y = 22, z = 33; if (x == 11) { if (y == 22) { if (z == 33) { cout << "Hey! C++ nested if here!!" << endl; } } } return 0; } Output: This outcome shows that all the “nested if” conditions are satisfied. The statement inside the last “if” is displayed here. This statement won’t appear here if any of the listed conditions is false. Example 4: The “ch1”, “ch2”, and “ch3” variables are initialized as the “char” data type with the “a”, “b”, and “z” characters after invoking the “main()” function. Next, we employ an “if” statement with the “ch1 == a” condition and another “if” inside it (referred to as a “nested if”) with the additional “ch2 == b” condition. This means that only when the first “if” condition is met will this “nested if” be run. Subsequently, we employ an additional “if” within the second “if” which is carried out upon the satisfaction of both of the previously inserted “if” conditions. The “ch3 == z” condition is found in the third “if” and the word “cout” is present in the last “if” condition. This will only pass if all conditions are fulfilled. Code 4: #include <iostream> using namespace std; int main() { char ch1 = 'a', ch2 = 'b', ch3 = 'z'; if (ch1 == 'a') { if (ch2 == 'b') { if (ch3 == 'z') { cout << "The C++ programming nested if..!!" << endl; } } } return 0; } Output: The sentence inside the last “if” is shown here which indicates that all of the “nested if” conditions are satisfied. This statement won’t appear here if any of the conditions is false. Example 5: After calling the “main()” method, the “f1”, “f2”, and “f3” variables are initialized as the “float” data type with the “2.40”, “19.7”, and “43.1” values. Next, we use an “if” statement with the “f1 == 2.40” condition and another “if” (also known as a “nested if”) with the “f2 == 19.7” condition inside of it. This indicates that this “nested if” will only be performed if the first “if” condition is fulfilled. Afterward, we use the third “if” inside the second “if” which is executed if both of the previously added “if” conditions are met. The third “if” condition has the “f3 == 9” condition, and the last “if” condition contains the “cout”. Only in a situation where all three requirements are met will this “cout” statement render. Then, outside all these “if” conditions, we also add the “cout” which is rendered when the “if” condition is not true. Code 5: #include <iostream> using namespace std; int main() { float f1 = 2.40, f2 = 19.7 , f3 = 43.1; if (f1 == 2.40) { if (f2 == 19.7) { if (f3 == 9) { cout << "All nested if conditions are true here!!" << endl; } } } cout << " The condition of the nested if is not satisfied..!! " << endl; return 0; } Output: Here, it displays the statement that we added outside the “nested if” condition and shows that the “nested if” condition is not satisfied. Conclusion The “nested if” concept in C++ is learned thoroughly here. We explored that “nested if” means that we placed an “if” condition inside the other “if” condition. We utilized this “nested if” condition where we had to fulfill numerous conditions simultaneously. We explored some examples in which we utilized the “nested if” condition in our C++ codes and explained how it works. View the full article
  6. This article is about MongoDB in C++, the most powerful and widely used database in our programming world that stores the data in JSON format. MongoDB is an open-source and document-oriented NoSQL database that offers us a flexible approach to storing and managing the records in the database. The user can insert(), delete(), and update() the queries using MongoDB in C++. Let’s learn how the MongoDB driver is installed and used in C++ to manage the database of any system with the help of proper examples for more understanding. How to Install the MongoDB Driver in C++ We will learn how to install the Mongo driver in C++. The official Mongo driver that is used for C++ is the MongoDB C++11 driver which can be installed in your system with a C++ environment. We must install the MongoDB driver library and connect the database to the C++ projects using a URL string. The MongoDB driver is appropriately functional and has built-in management methods that automatically connect the database on user request and reconnect the connection if lost. The MongoDB driver provides full authentication and authorization of the user request that is handled in C++ to the database. Create a MongoDB Database in the System Install the MongoDB setup in our system. After installing the MongoDB, from “C:\Program Files”, open the bin folder from the MongoDB folder. Copy the address of the bin folder address and add the environment variable PATH in Windows to activate the NoSQL MongoDB database. Ensure that MongoDB Compass is installed that has the mentioned user interface. We can see the address of this database, and we can access this database through the local host whose port number is “27017”. Open the command prompt in your system. Run the command -> mongo –version to show the version of MongoDB. Create a New Database in MongoDB Using Cmd We can easily create the new database in MongoDB by just running the command in the cmd of our system. We run the command that is mentioned in the following: > use mydb Show All Running Databases in MongoDB To show all the running databases in the MongoDB, we can run the following mentioned command in our cmd to show all the running databases: > Show dbs To launch the MongoDB server, we just need to follow and fulfill the requirements on the terminal. We can also get the collection of “Mongo” in the current default database which is “test” with records already in it. Only those databases with some data or records are retrieved or shown in the show database. Example: Connecting MongoDB in C++ Here, we connect this NoSQL MongoDB database to interact with C++. We first need to connect to your system’s MongoDB server. Make sure that the C++ setup and MongoDB are active in the system. The MongoDB driver library in C++ is now installed on your system. We can run the essential libraries in our code along the MongoDB C++ driver as “mongodbcxx/client.hpp” and “monodbcxx/instances.hpp”. In the MongoDB libraries, we use the “client” function that contains the URI “mongodb://localhost:27017”. If this URI is correct, display the message as “connected to MongoDB”. The MongoDB that runs locally is only accessible on port “27017” as displayed in the previous MongoDB screenshot. Maintain the CRUD in MongoDB CRUD is the main operation that is needed in the database management system. We can do nothing without CRUD in C++. In a database, CRUD means create, read, update, and delete the records from the database to high performance of the database. Insert the Data in the MongoDB Database C++ We can easily add the records to any new or existing database. We only create new tables in the database easily in C++ by defining the essential MongoDB libraries to connect with the database. After that, we write the connection code in C++ and then write the insert database query in C++ to insert the records in the database. MongoDB is created as a powerful driver that handles the C++ program which is “MongoDB driver C++” and the library that handles all the C++ operations whose name is “mongocxx”. Using the libraries, we create an instance of the C++ driver. Using the insert_one() method, we add the data to the NoSQL database. Delete the Data from the Database In every step, make this thing clear that the MongoDB connection is established and working fine. We access the MongoDB database using the “mongocxx” library and its useful methods that are derived to delete the data from the database in C++ language. We can access the database and its collection easily using the attributes of mongocxx, just like “mongodbcxx::database” with the “db” alias and “mongodbcxx::collection” for collection with the “colle” alias. After that, create the filter for every situation for the document that you definitely want to delete and then specify the criteria for deletion in MongoDB C++. Pass the filter in the “delete” function to remove the record from the database. Update the Records in the Database An update means we can change the existing records in the database. We can easily update the record from the database using the “update” method that is defined in the MongoDB C++ driver instance. Conclusion At the end of the article, we can say that the usage of NoSQL MongoDB is increasing rapidly because of its high efficiency and performance. MongoDB has developed the MongoDB driver to execute or deal with the C++ language. With the help of MongoDB, the users can easily add, delete, update, and show the records, tables, and databases without having any storage or space issues in the system. MongoDB takes its virtual space and easily deals with the C++ language using its special-purpose libraries. Hopefully, this article is very helpful and easy to learn. Remember to use smart techniques or databases to build new programs and applications to make the system more reliable. View the full article
  7. This article focuses on the “const” keyword that is used with the function in C++. The “const” keyword is referred to as the constant value that we cannot modify during the execution of the program. The “const” functions in C++ are those functions whose data members are restricted to be changed in their class. The “cont” functions are efficiently used as they can avoid unexpected modifications to the object’s value. Example 1: Program of a Const Member Function in C++ Here, we have a simple program of the const member function: #include<iostream> using namespace std; class MyClass { int num; public: MyClass(int n = 0) { num = n; } int getValue() const { return num; } }; int main() { const MyClass c(30); MyClass c1(5); cout << "Number using object c : " << c.getValue(); cout << "\nNumber using object c1 : " << c1.getValue(); return 0; } Initially, we define the header file which enables the program input/output streams. Then, we set the “MyClass” class where we declare a “num” variable and the member functions of the MyClass() function and the getVal() function. Inside the MyClass() function, we set the “n” parameter with the value of “0”. Then, the “n” argument is assigned to the “num” variable. Next, we call the getVal() function with the “const” keyword, indicating that the object’s present state can’t be modified on a function call. The getVal() function returns the “num” member variable. Finally, we reach out to the main() function. Here, we define the “c” and “c1” objects of the MyClass() function and also pass the values to these objects. The “c” object is set with the “const” keyword, indicating that the value that is assigned to this object cannot be modified. The output of the const member function that is called by the object is shown in the following. This way, we can use the “const” keyword with the member function and the object: Example 2: Program of a Const Member Function Outside the Class in C++ Now, we have another implementation where the const member function is defined outside of a class definition and set and retrieve a private member variable value using a const member function. #include <iostream> using namespace std; class NewClass { int i; public: void set_record(int); int get_record() const; }; void NewClass::set_record(int x) { i = x; } int NewClass::get_record() const { return i; } int main() { NewClass c; c.set_record(10); cout << c.get_record(); return 0; } Here, we first establish a class, “NewClass”, where we initialize the “i” variable which is kept private. After that, we have a public keyword where the set_record() and get_record() member functions are defined. The set_record() member function is used to set the value of the “i” variable and the get_record() function is used here to return the value of the “i” variable. Note that we use the “const” keyword with the get_record() member function which represents it as a const member function, and the object state cannot be modified. After that, we have a set_record() function definition to set the “i” variable value. Similarly, we have the get_record() function definition to retrieve the “i” variable value. Then, we set the main() function where we have a declaration of the “c” object of the “NewClass” class. Then, the “set_record”, a non-const member function, is called to assign a value to the “z” variable. Moving on, we call the get_record() const member function to print the value of “i”. The value of the private member variable is called by the const member function and is shown in the following prompt: Example 3: Program of a Const Member Function Defined Outside the Class as an Independent Function However, we implement another case of the const member function where the member function with the “const” keyword is called outside the class as a standalone function. #include<bits/stdc++.h> using namespace std; class Equation{ int n1,n2; public: void set_equation(int x, int y) { n1 = x; n2 = y; } void show_equation() { cout<<"The Equation is: "<<n1<<" + "<<n2<<"b"<<endl; } friend void funIs(const Equation); }; void funIs(const Equation obj) { cout<<"The Equation using function is: "<<obj.n1<<" + "<<obj.n2<<"b"<<endl; } int main() { Equation obj; obj.set_equation(5,8); obj.show_equation(); funIs(obj); } Here, we create the “Equation()” class and then declare the “n1” and “n2” variables. Here, we also add the set_Equation() member function to set the values of the “n1” and “n2” variables. The show_Equation() function shows the equation that is generated using these variables. After this, we have a function declaration of funIs() which is defined using the “friend” keyword. This “friend” keyword allows us to access the private member of the “Equation” class. Next, we call the “funIs()” friend function outside the class and input the “obj” parameter of the “Equation” class as const. In the end, we have a main() function where we declare the object of the “Equation” class. Then, we set the values of the “n1” and “n2” variables using the set_Equation() function. The “n1” and “n2” variables are used to display their values using the show_Equation() function. Lastly, we call the “funIs” friend function of the “Equation” class to display the equation. The equation and the equation using the const friend function are displayed on the prompt: Example 4: Program of a Const Member Function to Update the Value in C++ (Worst Case) The program demonstrates the worst scenario of the const member function where we try to modify the value of the variable called “inside the const member function”. #include <iostream> using namespace std; class Data { int v; public: void setValue(int i) { v = i; } int getValue() const { ++v; return v; } }; int main() { Data d; d.setValue(20); cout << endl << d.getValue(); return 0; } Here, we first construct the “Data” class and declare the “v” variable within the class. After this, we set the “public” keyword and then declare the class member functions of “setValue()” which represents the constructor of the class and the getValue() which indicates the getter member function of the class. The setValue() function takes the “i” variable as a parameter. This “i” variable is assigned to the “v” member variable. After this, we have the getValue() function definition where we retrieve the value of the “v” variable. Since the getValue() function is declared with the “const” keyword, representing that the value of the “v” variable cannot be updated in any case. However, we intentionally attempt to increment the “v” variable to change its value. When the program reaches this stage, an error is thrown. Lastly, we have the main() function call where we define the “d” object of the “Data” class and set the value of “20” for this “d” object. After that, we call the getValue() function to get the object’s “d” value. The prompt generates the results of the previous implementation where it gives an error on “++v” because we are not allowed to modify the value of the const member function objects: Conclusion In conclusion, we dive into the const function of C++ which is used to avoid accidental changes in the program’s value. The const member functions in C++ are read-only functions whose modification of the objects on which it is called is not allowed. We also implemented various scenarios of the const function to demonstrate its functionality in C++. View the full article
  8. In the article, we will discuss about the assignment operator which is represented with the equality (=) symbol in C++. Here, we use the assignment operator to overload the values of one instance to another. The right operand value is always assigned to the left operand. The assignment operator in C++ is a predefined operator that can only operate on data types that are built in. Assignment operators are set up to function only with included data types. Example 1: Program to Overload the Assignment Operator in C++ The overloading of assignments using the assignment operator (=) is demonstrated in the following program: #include <iostream> using namespace std; class PinCode { private: int y; public: PinCode(int i) { y = i; } PinCode operator =(PinCode &num) { return PinCode(num.y); } void show() { cout<<"y = "<<y; } }; int main() { PinCode num1(220); PinCode num2 = num1; num2.show(); return 0; } In the given script, we create a “PinCode()”class after defining the header files. Then, we declare a private variable “y” in that class. Then, we define the public member function of the “PinCode()” class which includes a “PinCode()” constructor, the overloaded assignment operator, and the show() function. Within the “PinCode” constructor, we pass the “i” parameter of type integer which is assigned to the “y” variable of the specified class. After this, we use the overload assignment operator and pass the “&num” object reference which returns an object of “PinCode”. Within the overload assignment operator definition, it takes the value of “y” from the parameter object and creates a new “PinCode” object. Then, we have a definition of the show() function to display the variable “y” value in the output. Finally, we have the main() function definition where we declare two objects, “num1” and “num2,” of the “PinCode” class. The “num1” object is assigned with the value of “220” by calling a constructor, whereas the “num2” object is kept equal to the “num1” object using the assignment operator. In the end, the show() function is where we call the “num2” object to display the value of “y”. The output displays the value of “y” which is retrieved using the assignment operator overloading: Example 2: Program to Overload the Assignment Operator to Copy the Points from One Variable to Another in C++ Here’s another example of assignment operator overloading where we copy one team’s points to another: #include <iostream> using namespace std; class TennisTeam { private: int round1; int round2; public: TennisTeam(int r1, int r2) { round1 = r1; round2 = r2; } void operator=(const TennisTeam& t) { round1 = t.round1; round2 = t.round2; } void points() { cout << "Round 1: " << round1 << ", Round 2: " << round2 << endl; } }; int main() { TennisTeam t1(8, 4), t2(3, 9); cout << "TennisTeam A Points : "; t1.points(); cout << "TennisTeam B points : "; t2.points(); t1 = t2; cout << endl; cout << "TennisTeam A points : "; t1.points(); cout << "TennisTeam B points : "; t2.points(); return 0; } In the given script, we have the “TennisTeam” class definition where we declare two private variables, “round1” and “round2”. After this, we have a “TennisTeam” class member function which is kept public. The member functions include TennisTeam() which is a parameterized constructor as we pass “r1” and “r2” there. Inside it, we initialize the private variables “round1” and “round2” with the parameter variables. Then, we call the overload assignment operator which refers to a TennisTeam object “t” as a parameter and returns a TennisTeam object. It creates new TennisTeam objects with the same values of round1 and round2 as the parameter objects. Next, we have a member function, “points()”, to print the points that are gained in rounds 1 and 2. The main() function is then invoked, creating and assigning the points to the “t1” and “t2” objects of the “TennisTeam” class. Then, we use the “cout” command to print the points of “t1” and “t2” by calling them with the points() function. After that, the assignment operator moves the points from the “t1” object to the “t2” object. The copy-over points are shown to the console by calling the “t1” and “t2” objects with the points() function. Hence, the points of the “t1” object that are assigned to “t2” using the overloading assignment operator are now shown on the console: Example 3: Program to Overload the Assignment Operator in C++ as Virtual In addition, we have a program where the assignment operator is defined as virtual in a particular class. #include <iostream> using namespace std; struct X { X& operator=(char) { cout << "X& X::operator=(char)" << endl; return *this; } virtual X& operator=(const X&) { cout << "X& X::operator=(const X&)" << endl; return *this; } }; struct Y : X { Y& operator=(char) { cout << "Y& Y::operator=(char)" << endl; return *this; } virtual Y& operator=(const X&) { cout << "Y& Y::operator=(const X&)" << endl; return *this; } }; struct Z : Y { }; int main() { Y y1; Y y2; X* xp1 = &y1; X* xp2 = &y1; *xp1 = 'a'; *xp2 = y2; } In the given script, we create the “struct X” base class. Inside the “X” class, we utilize the assignment operator function which is passed with the “char” type and then display it to the prompt. Then, we invoke the assignment operator function again and pass the “&X” reference. Note that this operator function is a virtual function that the “child” class can override. After this, we create another class, “struct Y”, that is inherited from the “struct X” base class. Here, we call the override assignment operator functions that are inherited from the “X” base class twice. We assign the “char” type for the first assignment operator function, and the second overridden assignment operator function takes the “X&” reference. Both the overridden assignment operator functions print a different message on the console. Next, we define another class, “Z”, which is inherited from the “Y” class. Within this class, we don’t invoke any assignment operator function because we pass the functions of the “Y” class to it. Finally, we have the main() function definition where we set the “y1” and “y2” objects of the “Y” class. After that, we define the “xp1” and “xp2” pointers of type “*X” and assign them the “y1” object addresses using the reference(&) operator. Then, we set the assignment operator on the “xp1” and “xp2” pointers. The “xp1” pointer is assigned with the “a” character and the “xp2” pointer is assigned with the “y2” instance. Lastly, we call the “z1” instance of the “Z” class which is also set with the “a” character using the assignment operator. This generates an error during compilation because we implicitly define the “clone” assignment operator that is specified in “Z hides Y& Y::operator=(char)” class. The output is shown on the following console where it prints the “X& X::operator=(char)” by the “xp1= ‘a’” assignment because the declaration of this function is not virtual. Then, the “print Y& Y::operator=(const &Y)” output is called by the “xp2 = y2” assignment as it was declared virtual. The compiler’s function depends on the type of object that the “xp1” pointer points to. Conclusion In conclusion, we are now familiar with the assignment operator overloading in C++. Thus, the assignment operator overloading causes all the object’s values to be copied to another object in C++. We have an explanation and implementation of overloading an assignment operator in the given examples. View the full article
  9. In this article, we will learn about reading a binary file in C++. The concept of reading the binary file means reading the raw bytes of the file instead of the data inside the file. In C++, there are many ways and methods through which we can read any type of file like binary files, text files, pdf files, and many more. This programming language uses the stream for file processing to achieve these tasks. Here, we will learn about the reading operation of binary files using a stream-based library. We will explore how to read a binary file with proper examples. What Is a Binary File in C++? A binary file is a file in C++ that always stores the data that is not in an easily understandable format for humans. Only computer reads the binary data; binary means data in the sequence of “0,1” or ASCII format. It contains the encrypted data. Humans cannot understand this type of file, and only computers can operate with this type of binary file. The primary operator reads the raw binary data in C++ and handles the data at the binary level. So, these file manipulations are very complex for humans. Dealing with this type of file is such a complicated or complex task in the programming world. The standard libraries that are used to read the binary file in C++ are file stream classes such as “ifstream” and “ofstream” from the main <fstream> stream header. We use the “ifstream” library to read a binary file. We open the binary file using the flag which is “ios::binary”. The binary file opening is a must to ensure that the data is read in its binary format. Handling the binary files requires a very careful consideration of data types and file structures. Importance of Binary File in C++ The binary file plays a vital role in handling the file processing in C++. The binary file requires a critical approach in gaining the appropriate storage of data and their retrieval. The binary files facilitate us in the programming world in different ways: Data Integrity The binary files store the data or information byte by byte without any further occupation of formatting and additional interpretation. It also overcomes the risk of a sudden data corruption event. The integrity of binary files is retained in this proper way. More Efficient The binary files are more efficient and valuable in terms of file storage. This file’s data is in numeric storage like IEEE or 5765 instead of long characters or text. The data is in encrypted form, so the speed of this file is fast and more efficient for handling the essential data. Compatibility Due to the consistency and accessible comprehension of binary data representation, users are encouraged to use the binary files for compatibility across various environment platforms and programming languages. In Which Scenario should We Read the Binary Files? Let’s take a quick example to learn about the read action of binary files in proper programs. These examples help us discover more emerging techniques for handling the binary files in the C++ programming language. Scenario 1: Read the Binary Files Using the Read() Function along with Ifstream In C++, we can read the binary files using the streams and different methods to store or transfer the data in different locations. In this scenario, we will learn how to read a binary file in C++ easily by just calling the “if” stream and “read” function with the help of standard libraries. The code snippet of this scenario is mentioned in the following for better understanding: #include <iostream> #include <fstream> int main() { std::ifstream file("binaryData.bin", std::ios::binary); if (file.is_open()) { char buffer[200]; //buffer is used to store temporary data file.read(buffer, sizeof(buffer)); std::cout<<"File Open Successfully"; } else { std::cout << "Unable to open file"; } return 0; } In this code snippet, we open a binary file that is already created in our system, and the text data is stored there. The binary file contains an encrypted data, so the visualization of this type of data is challenging. After declaring the valid utilities or libraries, we use a stream file handling in the main function using the “std:: ifstream file()” method. We pass the “address of the file that needs to be read” and “type of file in binary format std::ios:binary” in this file function. After that, we implement the condition if the address and format of the file are correct. Then, we open the file. Otherwise, we show the error on the console window. Ensure that the given file exists in your system, and the address is correct. At the end, run the code, and the console window that has the output opens. The output screen shows that the binary file is open and the content is read. The content can be displayed on the screen because the data is not in a text format. Scenario 2: Read the Binary File Using the Fread() Method In this scenario, we will learn how to read the binary file data using the fread() method. The fread() function reads the data of files in blocks from the stream. We use another way to open a binary file using the “FILE” pointer. Let’s take an example of this scenario with a proper code snippet that is attached in the following: #include <stdio.h> #include <iostream> #include <fstream> int main() { FILE *file = fopen("binaryData.bin", "rb"); if (file != NULL) { char buffer_arr[100]; fread(buffer_arr, sizeof(char), sizeof(buffer_arr), file); std::cout<<"Read Successfully.....Binary File is read through fread()"; fclose(file); } else { std::cout<<("Unable to open file"); } return 0; } Here, we add libraries like <iostream> and <fstream> which are a must for file stream and output purposes. In the main function, open a file using the “fopen()” method and pass the binary file address with the “.bin” extension and the read mode. Initialize fopen() to a “file” pointer since we know that the pointer stores the data in the buffer. After that, check if the file is opened or not. If the file is not null, we read a file using fread(). Otherwise, we show the error that the file is not opened. We compile this code in your Dev C++ environment and generate a result on the following console screen: The given output screenshot shows that the file is opened and read successfully. Conclusion Finally, we can say that binary files are complicated files that are not understandable for humans, and the data inside these files are also encrypted and not in visible format. Here, we discussed in detail about the “read” mode of binary files. Remember that the extension of binary files must be in “.bin”, and the methods to read a binary file must be valid and defined. Here, we mentioned some best examples for understanding the concept more clearly and concisely. Practice these code snippets in your environment to understand the core concepts better. View the full article
  10. In C++, the cout object is an object of the iostream class. It is specified in the iostream header file. It is linked to the typical output device which is generally a console. For the output to be exhibited on a screen, the cout is utilized with the stream insertion operator (<<). Syntax: The syntax of cout is as follows: cout << variable; or cout << “string”; Now, using this syntax, we perform the various illustrations in this article. Using Cout to Display the Character String In this illustration, we demonstrate the easiest and simplest way to utilize the cout object. We first include the header files and then utilize the cout object inside the main() function to display a string of characters on the console. #include <iostream> using namespace std; int main() { cout << "This is a cout format guide."; return 0; } The program begins with the inclusion of the required library which is “iostream”. Then, we use the “namespace std” library. This library allows us to use all the functions, variables, and classes that are available under the standard library namespace. The main() function starts and we use the cout object with the insertion operator within its braces. Then, we specify the text that we need to display between the double quotation marks as “This is a cout format guide.” The return “0” means that the program ran successfully. The following snapshot shows that the provided text is displayed on the console: Using Cout to Print the Integer Value that Is Stored in a Variable Another way to use the cout in C++ to display the output is to initialize a variable first. Then, provide it to the cout object to print it on the console. In this example, we initialize an integer type variable with “a” value. Then, it is displayed on the console using the count object. #include <iostream> using namespace std; int main() { int s = 1000; cout << "The value of s is " << s; return 0; } First, we include the "iostream” header file. Then, the std namespace library is used to make the execution of the error-free code. The main() function is initialized and we initialize a variable “s” inside the main() function with int datatype and assign it with the value of 1000. Now, to display the value of this variable, we use the cout object with the insertion operator and then specify the variable name. We can also display a text string with the cout object by writing it in between the double quotation marks after the insertion operator. The cout simply prints whatever is defined between the double quotation marks as it is on the console. Here, we define it as "The value of s is" followed by the insertion operator. Then, we define the name of the variable whose value has to be displayed. Lastly, put a semicolon(;) to determine the end of a statement. The output image shows the provided text string with the value which is stored in variable “s”: Using Cout to Display the Sum of Two Numbers Apart from displaying the values on the console, the cout object can also be used to perform arithmetical operations. We can simply specify the operation in the count statement and the calculated output is displayed on the console. #include <iostream> using namespace std; int main() { int p; int r; cout << "Enter first number:"; cin >> p; cout << "Enter second number:"; cin >> r; cout << "The first number is: " <<p<<endl; cout << "The second number is:" <<r<<endl; cout << "The sum of p and r is:"<<p+r<<endl; return 0; } After including the required libraries, we enter the main() function of the program. Here, we declare two variables – “p” and “r” – both having the integer datatype. Now, we take the input values for both these variables from the user, one by one. A cout object is used to display the text “Enter first number:” on the screen. Then on the next line, we use the cin object which takes the input from the user and stores the user-provided number in the “p” variable. After that, we display another text “Enter second number:” with the use of cout. Cin takes the input value for the “r” variable. As you can see in the snapshot, the user enters the first number and hits “Enter”. The control asks the user to input a second value. Here, the first number that is entered by the user is 20 and the second number is 7. We then exhibit both the number on the console. To do that, we simply add a text and the variable name to the cout object with the use of the insertion operator. At the end of each cout statement, we use the “endl” function which immediately adds a new line after the following code. Now, to count the sum of these two numbers, we write the athematic operator “+” between both the variables “p” and “r” along with the “The sum of p and r is:” statement. As the program is executed, the cout object calculates the sum of values that are stored in these variables and displays it on the console with the specified text. The following image shows both the entered values and the sum of these two values: Using Cout to Display the Character and Integer Variables in a Single Line We can display multiple variables with a single cout statement. Here is the program to implement this technique: #include <iostream> using namespace std; int main() { string Name = "Harry"; string Country = "America"; int Age = 28; cout << "My Name is " << Name <<" , my age is "<< Age << " and I live in " << Country << endl; return 0; } In this program, we initialize two strings and one int value. The first string is “Name” which is initialized as “Harry”. The second string is “Country” which is given with the value of “America”. Lastly, we have the int variable “Age” with the value of “28”. Now, we use the cout object with the insertion operator to display all these values in a single line. First, we write the cout object followed by the insertion operator. Then, with the help of double quotation marks, we defined the “My name is” text. Then, the variable that stores the name is added after the insertion operator, “Name”. By following the same pattern, we add the other two variables with the specified text in this cout statement. Finally, the execution of the program gives us a single-line output. The output statement includes all three variables with the text and is displayed on the console: Conclusion The C++ cout format is defined and explained in this article. We provided you with the syntax to use this object. Various illustrations are demonstrated practically with a thorough exaplanation of their details. We first showed you the easiest and simplest format to employ a cout statement. Also, we carried out an example in calculating the sum of two variables in cout. Each example is elaborated on the different formats that are used for the cout object in C++. View the full article
  11. Today, we’re going to study one of the C++ string at() methods, and we will use a variety of examples to demonstrate how to transform string at() methods in C++ language. As we know, it is an object-oriented programming language that gives programs a clear structure, making it possible for code to be read within the same program. C++ is a relatively basic and easy-to-understand language. Introduction In C++, a bundle of various characters or elements is contained in one of the C++ datatypes called a string enclosed in double quotation marks. The C++ string performs a wide range of methods, and the at() method is one of those methods. The string at() method is used to access the exact position of the character or element from the string. In simple words, in the at() method, we can access the individual character from the whole input string at the specified location. Now, let’s discuss the at() method, and let’s see how this method works. Syntax Here is the syntax of the string at() method, and it lets us understand how we implement it. To call the string at() method, we first write the predefined keyword, which is “char”. It will tell the compiler that we are accessing a character from the input character string. Then we will write the variable name of the input string (the variable where we have stored the input string) and concatenate it with the at() method. In the aSt() method, we will pass some arguments. Parameter idx: the index number of the input string from where we want to access the element of the input string. Keep in mind that the index number will be less than or equal to the length of the input string. size_type: an unsigned integer used to display the size in bytes of any object. Return Value In return, we will get the exact location of the input string character, and then we can access the character by passing the index number in the at() method. Errors & Exceptions There is no exception if we enter the index value of the string character as less than or equal to the input string length. If we pass the index greater than the length of the input string, then the exception thrown will be out of range. Example 01 Now, let’s start explaining our first and simple example of the string at() method. We need any C++ compiler compatible with the string methods to implement our program. To code the Program in C++, we always need basic libraries to use manipulators of C++ in the existing program. The first library we are using in this program is “#include <iostream>”. The “#” sign instructs the compiler to load the header file, the “include” keyword incorporates the header file into the program, and the “iostream” specifies inputting the data from the user and display of data. To use strings and string methods across the entire program, we have included the second header file, which is “#include <string>”. Then we used the “using namespace std” directive, which prevents classes, functions, and variables from utilizing the same context throughout the entire program. After importing the basic libraries and directives, we now move on to the main() function of the program. The main() function is used to write the actual line of code that we want to implement and get the results from it. In line 8, we declared a variable “str” of type “string”, and then we initialized the character string to the “str” variable. Next, we initialized another character string to the same variable “str” and printed it using the predefined cout() method of C++. Then we want to get the size of the string we recently created. For that, we have called the size() function with the concatenation of the string variable, which is “str,” and passed the whole function into the cout() method so that we can display it. Then we also want to print the initialized capacity for the input character string. For that, we will use the capacity() function with the concatenation of the “str” variable. We have initialized the first string to get the string capacity from it. After getting the size and capacity of the input character string, we move forward. Then we declare another variable, “res”, of type “char”, which means we are creating a character type variable. In this variable, we will store the character from the input string which we want to access. So we will call the at() method and pass the index number of the character in it and then concatenate it with the input string “str”. Then we wanted to print the element, so we used the cout() method, which is the predefined method of C++, and passed the “res” variable in it. As discussed in the at() method, we can replace the character. For replacing each character that we have accessed is; first, we will write the variable or any symbol in a single quotation mark and then assign this to the at() method by writing the variable name “str” first and then concatenating it with the at() method and passing the index number in it. And then, we will display it by using the cout() method. Example 02 Here is the second example of the at() method of string datatype in C++ language. The implementation of this example is the same as we have implemented above. Still, the only difference is that we are accessing only one character simultaneously. Here, we are accessing the whole input string. For that, we declared the “str” variable of string type and assigned the input string to it. Then we have another variable, “res”, of the “int” type, and we have stored the length of the string in it. And then, we have a “for loop” so that we can print the input string characters one by one in a single line. Here is the result of the overhead illustration: Conclusion In this editorial, we have come to know what the string at() method is and how we will use this method. We have also learned the writing style of the at() method and which kinds of errors and exceptions we will get through if we make logical mistakes. We have employed several illustrations to explain every line of code comprehensively. I hope you will learn a lot from this tutorial. View the full article
  12. C++ is one of the most popular and oldest programming languages used for the development of high-performance applications. It is used among highly expert programmers and novice developers. It is mainly used in game development and is an ideal option for developing operating systems. When writing code in the C++ language, you may come across converting data from one type to another. In this article, you will learn to convert a string into a long integer. It is quite difficult to convert a string into any other format. However, the C++ programming language provides a quick and efficient way to convert strings into integers. stol Function in C++ The stol is a C++ built-in function provided in the std library. It converts strings to long integer numbers. It converts the string content into an integer number of the specified base and returns a long integer value. It takes three parameters, one is the input string, the second is the object parameter, and the third one is the numerical base. The syntax of the stol function is given below, have a look: The function stol takes three parameters: input_string, size, and base. The “input_string” represents the input string that needs to be converted into a long integer number. The “size” parameter represents the object of type size_t which carries the next character position in the input string after the numerical value. It can be a null pointer if it is not required to use. The third parameter, the “base” parameter represents the base in which the string needs to be interpreted. For example, if the “2” base is given, the string will be interpreted as the integer base 2 number. The default value of the base parameter is 10 and if 0 is provided then the base value will be determined by the format in the sequence. The stol function returns the long integer number representing the int value of a given string. Now, let us explore some examples to understand how the stol function works in C++. Example # 1 In this example, we will provide decimal and hexadecimal strings to check how the stol function converts them into decimal and hexadecimal integer numbers. The “dec = 123456789” is a decimal string and converted into a long integer using the stol function stol(dec,&size). Note that the base is not provided in the function as an input parameter which as result uses the default base 10 to convert the string into a decimal number. However, for converting the string from a hexadecimal number to a decimal number, base 16 is provided as the input parameter stol(hex, nullptr, 16). As we know, the 16 base represents a hexadecimal number. #include <iostream> #include <string> #include <stdlib.h> int main () { std::string dec = "123456789"; std::string hex = "a2bf3c"; std::string::size_type size; long lidec = std::stol (dec,&size); long lihex = std::stol (hex,nullptr,16); std::cout << "Input decimal string "<<dec << " converted to long int " << lidec << '\n'; std::cout << "Input hexadecimal string "<<hex << " converted to long int " << lihex << '\n'; return 0; } Here is the following output. Note that the decimal string “123456789” converted to “123456789” decimal long integer. While the hexadecimal string “a2bf3c” converted to “10665788” hexadecimal number. Here are the required steps that you can follow to learn how the conversion is done by the stol function: (A2BF3C)₁₆ = (10 × 16⁵) + (2 × 16⁴) + (11 × 16³) + (15 × 16²) + (3 × 16¹) + (12 × 16⁰) = (10665788)₁₀ Example # 2 In this example, we will convert a binary number using the stol function. Let’s see the code below and understand the working of the code. The “1010110110” is given as the input string and base 2 is provided as the input base parameter stol(bin,&size, 2), representing the number in binary format. The stol function will convert the binary number into a decimal number by following these steps: (1010110110)₂ = (1 × 2⁹) + (0 × 2⁸) + (1 × 2⁷) + (0 × 2⁶) + (1 × 2⁵) + (1 × 2⁴) + (0 × 2³) + (1 × 2²) + (1 × 2¹) + (0 × 2⁰) = (694)₁₀ #include <iostream> #include <string> #include <stdlib.h> int main () { std::string bin = "1010110110"; std::string::size_type size; long libin = std::stol (bin,&size,2); std::cout << "Input binary string "<<bin << " converted to long int " << libin << '\n'; return 0; } As you can see that the stol function returned the same result as the general binary to decimal conversion process did. Example # 3 In this example, we are going to see what happens if we test the stol function with invalid input. A string of multiple characters will be provided to the stol function and 0 will be provided as the base value so that the function will determine the base of the string automatically. Here is the code: A set of characters is provided as an input string which is not determined by any base values, i.e., 10, 16, 2, etc. so the function will return an error value. #include <iostream> #include <string> #include <stdlib.h> int main () { std::string chr = "abcdefgh"; std::string::size_type size; long str = std::stol (chr,nullptr,0); std::cout << "Input character string "<<chr << " converted to long int " << str << '\n'; return 0; } See the output below. Note that the compiler has raised an “invalid_argument” exception since the function does not cater to strings that cannot be determined with any base value. Example # 4 In this example, we will provide a combination of valid and invalid input to see the result of the stol() function. The input string is a combination of valid and invalid characters, “123xf25”. The “0” isg provided as an input base so that the function determines the base of the input string automatically based on the type of characters. #include <iostream> #include <string> #include <stdlib.h> int main () { std::string chr = "123xf25"; std::string::size_type size; long str = std::stol (chr,nullptr,0); std::cout << "Input string "<<chr << " converted to long int " << str << '\n'; return 0; } Here is the output that shows the working of stol function with a combination of valid and invalid input: Note that the function converted the “123” into decimal number “123” and discarded the rest of the string as it received an invalid input “x”. The string after the character “x” is not converted by the stol function, returning only the first characters of the string as long int. Conclusion In this post, we explored the stol function of the C++ programming language. With the help of some useful and simple examples, we learned how the stol function works with different types of inputs. The stol function takes three parameters, the input string that is to be converted, a size parameter that represents the position of the function in the string, and the base value that represents the base of the input string. It returns the long int value of the input string. View the full article
  13. This article provides a guide to operator overloading in C++. Operator overloading is a useful and powerful feature of the C++ programming language. C++ allows overloading of most built-in operators. In this tutorial, we will use several examples to demonstrate the operator overloading mechanism. What is Operator? An operator is a symbol that indicates to the compiler to perform a particular operation. For example, there are various types of operators in C++, such as Arithmetic Operators, Logical Operators, Relational Operators, Assignment Operators, Bitwise Operators, and more. What is Operator Overloading? The C++ language allows programmers to give special meanings to operators. This means that you can redefine the operator for user-defined data types in C++. For example, “+” is used to add built-in data types, such as int, float, etc. To add two types of user-defined data, it is necessary to overload the “+” operator. Syntax for Operator Overloading C++ provides a special function called “operator” for operator overloading. The following is the syntax for operator overloading: class sampleClass { .............. Public: returnType operator symbol (arguments) { .............. } .............. }; Here, “operator” is a keyword, and “symbol” is the operator that we want to overload. Examples Now that you understand the overall concept of operator overloading, let us go through a couple of working example programs for you to understand this idea more concretely. We will cover the following examples: Example 1: Unary Operator Overloading (1) Example 2: Unary Operator Overloading (2) Example 3: Binary Operator Overloading Example 4: Relational Operator Overloading Example 1: Unary Operator Overloading (1) In this example, we will demonstrate how a unary operator can be overloaded in C++. We have defined the class, “Square_Box,” and the public functions, “operator ++ ()” and “operator ++ (int),” to overload both the prefix and the postfix increment operators. In the “main()” function, we have created the object, “mySquare_Box1.” We have then applied the prefix and postfix increment operators to the “mySquare_Box1” object to demonstrate the unary operator overloading. #include <iostream> using namespace std; class Square_Box { private: float length; float width; float height; public: Square_Box() {} Square_Box(float l, float w, float h) { length = l; width = w; height = h; } // Operator Overloading - "++" prefix operator void operator ++ () { length++; width++; height++; } // Operator Overloading - "++" postfix operator void operator ++ (int) { length++; width++; height++; } void output() { cout << "\tLength = " << length << endl; cout << "\tWidth = " << width << endl; cout << "\tHeight = " << height << endl; cout << endl; } }; int main() { Square_Box mySquare_Box1(3.0, 5.0, 6.0); cout << "Dimensions of mySquare_Box1 = " << endl; mySquare_Box1.output(); mySquare_Box1++; cout << "Dimensions of mySquare_Box1 = " << endl; mySquare_Box1.output(); ++mySquare_Box1; cout << "Dimensions of mySquare_Box1 = " << endl; mySquare_Box1.output(); return 0; } Example 2: Unary Operator Overloading (2) This is another example in which we will demonstrate how a unary operator can be overloaded in C++. We have defined the class, “Square_Box,” and the public functions, “operator — ()” and “operator — (int),” to overload both the prefix and postfix decrement operators. In the “main()” function, we have created the “mySquare_Box1” object. We have then applied the prefix and postfix decrement operators to the “mySquare_Box1” object. #include <iostream> using namespace std; class Square_Box { private: float length; float width; float height; public: Square_Box() {} Square_Box(float l, float w, float h) { length = l; width = w; height = h; } // Operator Overloading - "--" prefix operator void operator -- () { length--; width--; height--; } // Operator Overloading - "--" postfix operator void operator -- (int) { length--; width--; height--; } void output() { cout << "\tLength = " << length << endl; cout << "\tWidth = " << width << endl; cout << "\tHeight = " << height << endl; cout << endl; } }; int main() { Square_Box mySquare_Box1(3.0, 5.0, 6.0); cout << "Dimensions of mySquare_Box1 = " << endl; mySquare_Box1.output(); mySquare_Box1--; cout << "Dimensions of mySquare_Box1 = " << endl; mySquare_Box1.output(); --mySquare_Box1; cout << "Dimensions of mySquare_Box1 = " << endl; mySquare_Box1.output(); return 0; } Example 3: Binary Operator Overloading Now, we will look at an example of binary operator overloading. The syntax for binary operator overloading will be somewhat different from unary operator overloading. In this example, we will overload the “+” operator to add two “Square_Box” objects. #include <iostream> using namespace std; class Square_Box { private: float length; float width; float height; public: Square_Box() {} Square_Box(float l, float w, float h) { length = l; width = w; height = h; } // Operator Overloading - "+" operator Square_Box operator + (const Square_Box& obj) { Square_Box temp; temp.length = length + obj.length; temp.width = width + obj.width; temp.height = height + obj.height; return temp; } void output() { cout << "\tLength = " << length << endl; cout << "\tWidth = " << width << endl; cout << "\tHeight = " << height << endl; cout << endl; } }; int main() { Square_Box mySquare_Box1(3.0, 5.0, 6.0), mySquare_Box2(2.0, 3.0, 5.0), result; cout << "Dimensions of mySquare_Box1 = " << endl; mySquare_Box1.output(); cout << "Dimensions of mySquare_Box2 = " << endl; mySquare_Box2.output(); result = mySquare_Box1 + mySquare_Box2; cout << "Dimensions of resultant square box = " << endl; result.output(); return 0; } Example 4: Relational Operator Overloading Now, we will look at an example of relational operator overloading. The syntax for relational operator overloading is just like that of the binary operator overloading. In this example, we will overload the “<” and “>” operators to apply to the “Square_Box” objects. #include <iostream> using namespace std; class Square_Box { private: float length; float width; float height; public: Square_Box() {} Square_Box(float l, float w, float h) { length = l; width = w; height = h; } // Operator Overloading - "<" operator bool operator < (const Square_Box& obj) { if(length < obj.length) return true; else return false; } // Operator Overloading - ">" operator bool operator > (const Square_Box& obj) { if(length > obj.length) return true; else return false; } void output() { cout << "\tLength = " << length << endl; cout << "\tWidth = " << width << endl; cout << "\tHeight = " << height << endl; cout << endl; } }; int main() { Square_Box mySquare_Box1(2.0, 3.0, 5.0), mySquare_Box2(4.0, 6.0, 8.0); bool result; cout << "Dimensions of mySquare_Box1 = " << endl; mySquare_Box1.output(); cout << "Dimensions of mySquare_Box2 = " << endl; mySquare_Box2.output(); result = mySquare_Box1 < mySquare_Box2; cout << "mySquare_Box1 < mySquare_Box2 = " << result < mySquare_Box2; cout < mySquare_Box2 = " << result << endl; return 0; } Conclusion C++ is a general-purpose and flexible programming language that is widely used in a variety of domains. This programming language supports both compile-time and run-time polymorphism. This article showed you how to perform operator overloading in C++. This is a very useful feature of C++ that adds some extra effort for the developer to define the operator for overloading, but it definitely makes life easier for the user of the class. View the full article
  14. Computer Science is one of the hottest prospects these days. With the world around us relying heavily on technology, this comes off as no surprise as everything is gradually becoming digitized and the demand for people skilled in this field keeps on increasing. The Internet has also exploded in the last couple of years and this has in turn led to an increase in the market for computers and devices related to it. However, the beauty of Computer Science isn’t only in its high success in the industry but also in how it is structured. It offers the best blend of mathematics and engineering, along with providing a platform where programmers can create and develop things simple with just a computer, similar to how an artist does with a paintbrush. Since Computer Science itself is composed of multiple subfields, there have been various programming languages developed each of which has been specifically designed for certain tasks. One such programming language that is immensely popular and lies at the crux of game development, animations, and operating systems is C++ which shall also be the topic of our discussion in this article where we would be looking at the best editors that are available for C++ programming. 1) VS Code The first name to appear on this list has to be VS Code, the powerful, open-source code editor designed by Microsoft that is available on all major platforms including Windows, Linux, and Mac OS. Although VS Code does not fall under the category of IDEs, it offers much more than what a traditional code editor does and is jam-packed with features that make it an excellent choice for writing and editing C++ programs. VS Code is well-known for its fluidity and flexibility, offering an interface that is extremely fast and easily customizable. Features like auto-completion, code refactoring color highlighting, and having support for multiple extensions make it an excellent choice for C++ programming. Editor Features: Extensions: VS Code also comes with a built-in command-line interface as well as an integrated source control from where users can perform version control tasks such as pulling and pushing data, making commits, creating branches, and so on. Preview of Source Control: 2) Sublime Text Another great option available for C++ programming is Sublime Text, the simple, cross-platform text editor. Although Sublime Text is closed source and not free, it still has one of the largest communities to back it and is well regarded mainly due to its speed and efficiency. Sublime Text has one of the slickest and sleek user interface that is bundled with a large set of features such as having multiple cursors, an innovative command palette, and an extremely customizable interface, and this can further be topped with by using its wide variety of plugins. Editing Tools: Snippets from Command Palette: Another awesome feature of Sublime is its unique search function which allows you to search and replace regular expressions, numbers, text, or case sensitive words. It also has the GoTo Anywhere Function, with which you can jump to any words, lines, or symbols that are specified instantly. 3) Atom Atom is an Electron-based free and open-source, cross-platform code editor that has risen in popularity among developers. What makes Atom so good is the fact that it has support from thousands of packages each of which offers different functionalities. It even allows users to create their own packages which they can then provide it to the Atom community. Atom is extremely customizable and is built with numerous excellent features such as auto-completion, providing multiple panes to split your screen into, and a very powerful search feature. Editing features: Multiple Panes: Split Left Pane: Another excellent feature that comes along with Atom is its integration with GitHub and thus, you can perform all operations of it such as creating new branches, pushing, and pulling, and making commits. 4) Brackets Brackets is a cross-platform and open-source code editor developed by Adobe that falls under the MIT License and is, therefore, free to use. Brackets is well-known for being lightweight and providing an immaculate performance while not comprising any of its features which clearly indicates its powerful nature. Brackets are extremely customizable, and you can quickly change the UI of its interface according to your interests. For example, if you just want the editor to appear in your workspace, you can easily hide the sidebar. Similarly, if you are working with numerous files and want to check the differences between them, you can split your window into vertical or horizontal splits. Horizontal split: Vertical Split: It also allows users to add extensions inside of it which provides more power to this simple-looking editor and allows users to manage their projects much more efficiently. 5) Geany Geany is another powerful text editor whose name deserves a mention in this list. It is an extremely lightweight and cross-platform text editor that makes use of GTK and Scintilla and provides a variety of features to its users without putting a strain on their systems. Features like auto-completion, syntax highlighting, and code navigation are some of its key highlights. In addition to this, it also has a built-in terminal along with a build system that allows it to compile and execute your programs which often leads to people calling it a small IDE. Geany also provides snippets to C++ Headers which can help users in writing their code in a much more efficient manner. Which are the Best Editors for C++ Programming? C++ is one of the most popular programming languages and is widely used in all sorts of areas of Computer Science. With so much importance being given to it, it is imperative to choose an editor that provides the best features and eases the work of the developer. All five editors mentioned above are excellent choices for writing and editing C++ code and are worth considering. View the full article
  15. A string literal is a sequence of characters in a constant array pointer terminated by the nul character, \0. When identified, by a variable, the string literal cannot really reduce or increase in length. Many operations cannot be done on the string literal. So, there is a need for a string class. The C++ string class is for a data structure, a collection of characters in sequence, which allows member functions and operators to act on the characters. The string class allows more manipulations on the corresponding string literal, than just the string literal. You need to have good knowledge of string literal, to understand this article. Class and Objects A class is a set of variables and functions that work together; where the variables do not have values assigned to. When values are assigned to the variables, the class becomes an object. Different values given to the same class result in different objects; that is, different objects are the same class with different values. Creating an object from a class is said to be instantiating the object. The name, string, is a class. An object created from the string class has a programmer chosen name. A function that belongs to the class is needed to instantiate an object from the class. In C++, that function has the same name as the name of the class. Objects created (instantiated) from the class have different names given to them, by the programmer. Creating an object from a class means constructing the object; it also means instantiating. A C++ program which uses the string class, starts with the following lines at the top of the file: #include <iostream> #include <string> using namespace std; The first line is for input/output. The second line is to allow the program to use all the features of the string class. The third line allows the program to use the names in the standard namespace. Overloading a Function When two or more different function signatures have the same name, that name is said to be overloaded. When one function is called, the number and type of arguments, determine which function is executed. Construction string() The following statement constructs a string of zero length with no character. string strCol = string(); It begins with the name of the class (object type), string. This is followed by the name for the object string, given by the programmer. The assignment operator follows; then the name of the constructor with empty parentheses. Here, strCol is the instantiated object with all the data members (properties) and member functions (methods). string(str) This is similar to the above, but takes either a string literal or an identifier as an argument, in the constructor. The following statement illustrates this: string strCol = string("I love you"); Construction with Initializer List The following code illustrates this: string strCol = string({'I',' ','l','o','v','e',' ','y','o','u','\0'}); The string literal is “I love you”. Note the nul character at the end of the initializer list. string(str, n) This forms a string collection, of the first n characters of another string. The following code illustrates this: char str[] = "I love you"; string strCol = string(str, 6); cout << strCol << '\n'; The output is “I love” with the first 6 characters from “I love you”. Remember: the single space is a character. string(str, pos, n) This forms a string collection of n characters, beginning from the zero-based indexed position, pos, of another string. The following code illustrates this: char str[] = "I love you"; string strCol = string(str, 2, 4); cout << strCol << '\n'; The output is, “love”. For the above two cases, if n is greater than the size of the string, the out_of_range exception is thrown – see later. string(n, ‘c’) Forms a collection of n characters, where all the characters are the same. Consider, string strCol = string(5,'e'); cout << strCol << '\n'; The output is, “eeeee”, 5 e’s. Assigning a String A string can be assigned as follows, after having declared both strings: string strCol1 = string("I love you"); string strCol2; strCol2 = strCol1; cout << strCol2 << '\n'; The output is, “I love you”. Constructing with Iterator An iterator provides a generic representation of scanning, through the values of a collection. A syntax to create a string with iterator, is: template<class InputIterator> basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator()); This constructs a string for the range [begin, end) – see details later. Destroying a String To destroy a string, just let it go out of scope. String Class Element Access An instantiated string object can be sub-scripted (indexed) like an array. Index counting begins from zero. stringName The operation “stringName” returns a reference to the character (element) at the ith index of the character collection. The following code outputs v: string strCol = string("I love you"); char ch = strCol[4]; cout << ch << '\n'; stringName const The operation “stringName const” is executed instead of “stringName” when the string object is a constant object. It is used in the following code for example: const string strCol = string("I love you"); char ch = strCol[4]; cout << ch << '\n'; The expression returns a constant reference to the ith element of the string object. None of the elements of the string can be changed. Assigning a Character with Subscript A character can be assigned to a non-constant string object, as follows: string strCol = string("I call"); strCol[2] = 'f'; cout << strCol << '\n'; The output is “I fall”. ‘c’ was changed to ‘f’. stringName.at(i) “stringName.at(i)” is similar to “stringName”, but “stringName.at(i)” is more reliable. The following code shows how it should be used: string strCol = string("I love you"); char ch = strCol.at(4); cout << ch << '\n'; at() is actually a string class member function. stringName.at(i) const “stringName.at(i) const” is similar to “stringName const”, but “stringName.at(i) const” is more reliable. “stringName.at(i) const” is executed instead of “stringName.at(i)” when the string object is a constant string object. It is used in the following code, for example: const string strCol = string("I love you"); char ch = strCol.at(4); cout << ch << '\n'; “at() const” is actually a string class member function. Assigning a Value with the at() Function A value can be assigned to a non-constant string object, with the at() function, as follows: string strCol = string("I call"); strCol.at(2) = 'f'; cout << strCol << '\n'; The output is “I fall”. Problem with Sub-scripting The problem with sub-scripting (indexing) is, that if the index is out of range, the wrong result may be obtained, or an error may be issued at run-time. front() This returns a reference to the first element of the string object, without removing the element. The output of the following code is ‘I’. string strCol = string("I love you"); char ch = strCol.front(); cout << ch << '\n'; The character is not removed from the string object. front() const When the string object construction is preceded by const, the expression “front() const” is executed instead of “front()”. It is used in the following code, for example. const string strCol = string("I love you"); char ch = strCol.front(); cout << ch << '\n'; A constant reference is returned. The element is not removed from the string object. No character can be changed for a constant string object. back() This returns a reference to the last element of the string object, without removing the element. The output of the following code is ‘u’. string strCol = string("I love you"); char ch = strCol.back(); cout << ch << '\n'; back() const When the string object construction is preceded by const, the expression “back() const” is executed instead of “back()”. It is used in the following code, for example. const string strCol = string("I love you"); char ch = strCol.back(); cout << ch << '\n'; A constant reference is returned. The element is not removed from the string object. String Capacity size_type capacity() const noexcept The total number of characters the string can hold without requiring reallocation, is returned by this capacity member function. A code segment for this is: string strCol = string(); int num = strCol.capacity(); cout << num << '\n'; The output is 15 on my computer. reserve(n) Memory space is not always available in free store. Extra space can be reserved in advance. Consider the following code segment: string strCol = string("love"); strCol.reserve(6); cout << strCol.capacity() << '\n'; The output is 15 on my computer. size() const noexcept This returns the number of characters in the string. The following code illustrates: string strCol = string("I love you"); int num = strCol.size(); cout << num << '\n'; The output is 10, which does not include the nul, \0 character. length() const noexcept - same as size(). Note: size() <= capacity() . shrink_to_fit() Can reduce capacity() to size() by causing reallocation; it is not obligatory. The following code demonstrates this: string strCol = string("I love you"); strCol.reserve(12); strCol.shrink_to_fit(); int sz = strCol.size(); cout << sz << '\n'; The output is 10 and not 12 or 16. The function returns void. resize(sz), resize(sz,’c’) This resizes the string. If the new size is smaller than the old size, then the elements towards the end are erased. If the new size is longer, then some default character is added towards the end. To have a particular character added, use the resize() function with two arguments. The following code segment illustrates the use of the two functions: string strCol = string("I love you"); strCol.resize(6); cout << "New size of strCol: " << strCol.size() << '\n'; string strCol1 = string("I love", 'e'); strCol1.resize(12); cout << "New size of strCol1: " << strCol1.size() << '\n'; The output is: New size of strCol: 6 New size of strCol1: 12 The function returns void. clear() noexcept Removes all elements from the string, as the following code segment illustrates: string strCol = string("I love you"); strCol.clear(); cout << strCol.size() << '\n'; The output is 0. The function returns void. empty() const noexcept This returns 1 for true if there is no character in the string object, or 0 for false if the string object is not empty. The following code illustrates this: string strCol1 = string("I love you"); cout << strCol1.empty() << '\n'; string strCol2 = string(); cout << strCol2.empty() << '\n'; The output is: 0 1 Returning Iterators and the String Class An iterator is like a pointer but has more functionality than the pointer. begin() noexcept Returns an iterator that points to the first character (element) of the string object, as in the following code segment: string strCol = string("I love you"); basic_string<char>::iterator iter = strCol.begin(); cout << *iter << '\n'; The output is ‘I’. Note the way the declaration that receives the iterator, has been declared. The iterator is dereferenced in a return expression to obtain the value, in the same way, that a pointer is dereferenced. begin() const noexcept; Returns an iterator that points to the first element of the string object collection. When the object construction is preceded by const, the expression “begin() const” is executed instead of “begin()”. Under this condition, the corresponding element in the object cannot be modified. It is used in the following code, for example. const string strCol = string("I love you"); basic_string<char>::const_iterator iter = strCol.begin(); cout << *iter << '\n'; The output is ‘I’. Note that const_iterator has been used this time, instead of just iterator, to receive the returned iterator. end() noexcept Returns an iterator that points immediately beyond the last element of the string object. Consider the following code segment: string strCol = string("I love you"); basic_string<char>::iterator iter = strCol.end(); cout << *iter << '\n'; The output is null, which is nothing, as there is no concrete element beyond the last element. end() const noexcept Returns an iterator that points immediately beyond the last element of the string object. When the string object construction is preceded by const, the expression “end() const” is executed instead of “end()”. Consider the following code segment: const string strCol = string("I love you"); basic_string<char>::const_iterator iter = strCol.end(); cout << *iter << '\n'; The output is null. Note that const_iterator has been used this time, instead of just iterator, to receive the returned iterator. Reverse Iteration It is possible to have an iterator that iterates from the actual end to just before the first element: rbegin() noexcept Returns an iterator that points to the last element of the string instantiated object, as in the following code segment: string strCol = string("I love you"); basic_string<char>::reverse_iterator iter = strCol.rbegin(); cout << *iter << '\n'; The output is ‘u’. Note the way the declaration that receives the reverse iterator, has been declared. The iterator is dereferenced in a return expression to obtain the value, in the same way, that a pointer is dereferenced. rbegin() const noexcept; Returns an iterator that points to the last element of the string object. When the object construction is preceded by const, the expression “rbegin() const” is executed instead of “rbegin()”. Under this condition, the corresponding element in the object cannot be modified. The feature is used in the following code, for example. const string strCol = string("I love you"); basic_string<char>::const_reverse_iterator iter = strCol.rbegin(); cout << *iter << '\n'; The output is ‘u’. Note that const_reverse_iterator has been used this time, instead of just reverse_iterator, to receive the returned iterator. rend() noexcept Returns an iterator that points just before the first element of the string object. Consider the following code segment: string strCol = string("I love you"); basic_string<char>::reverse_iterator iter = strCol.rend(); cout << *iter << '\n'; The output is null, which is nothing, as there is no concrete element just before the first element. rend() const noexcept Returns an iterator that points just before the first element of the string object. When the object construction is preceded by const, the expression “rend() const” is executed instead of “rend()”. Consider the following code segment: const string strCol = string("I love you"); basic_string<char>::const_reverse_iterator iter = strCol.rend(); cout << *iter << '\n'; The output is null. Note that const_reverse_iterator has been used this time, instead of just reverse_iterator, to receive the returned iterator. String Modifiers A modifier that modifies the string object, can also take or return an iterator. Appending basic_string& operator+=(const basic_string& str) Appends the right string object to the left string object. Example: string strCol1 = string("I love"); string strCol2 = string(" you"); strCol1 += strCol2; cout << strCol1 << '\n'; The output is “I love you”. Do not forget that “strCol1 += strCol2” is same as “strCol1 = strCol1+strCol2”. basic_string& operator+=(const charT* s) Appends a string literal to a string object collection. Example: string strCol = string("I love"); strCol += " you"; cout << strCol << '\n'; Output: “I love you”. basic_string& operator+=(charT c) Appends a single character to an object string. Example: string strCol = string("I love yo"); strCol += 'u'; cout << strCol << '\n'; Output: “I love you”. basic_string& operator+=(initializer_list<charT>) Appends an initializer list. Example: string strCol = string("I love"); strCol += {' ','y','o','u','\0'}; cout << strCol << '\n'; Output: “I love you”. It is always good to add the nul, \0 at the end of a character initializer list. basic_string& append(const basic_string& str) Appends the argument string object to the main string object. Example: string strCol1 = string("I love"); string strCol2 = string(" you"); strCol1.append(strCol2); cout << strCol1 << '\n'; Output: “I love you”. basic_string& append(const charT* s) Appends a string literal argument to the main string. Example string strCol = string("I love"); strCol = strCol.append(" you"); cout << strCol << '\n'; Output: “I love you”. basic_string& append(initializer_list<charT>) Appends the initializer list, which is an argument, to the main string. Example: string strCol = string("I love"); strCol = strCol.append({' ','y','o','u','\0'}); cout << strCol << '\n'; Output: “I love you”. It is always good to add the nul, \0 character at the end of an initializer list. basic_string& append(size_type n, charT c) Appends n of the same character. Example: string strCol = string("tab"); strCol = strCol.append(2, 'o'); cout << strCol << '\n'; Output: “taboo”. basic_string& append(const charT* s, size_type n) Appends the first n elements of a string literal to the main string object. Example: string strCol = string("I love"); strCol = strCol.append(" you so", 4); cout << strCol << '\n'; The output is: “I love you”. If n is greater than the length of the literal, a length_error exception is thrown. basic_string& append(const basic_string& str, size_type pos, size_type n = npos) Appends n characters from the index, pos to the main string. Example: string strCol = string("I love"); strCol = strCol.append("ve you so", 2, 4); cout << strCol << '\n'; Output: “I love you”. An exception would also be thrown here, see later. Assigning basic_string& assign(const basic_string& str) Assigns the argument string object to the main string, replacing any content that was there. string strCol1 = string("I love you"); string strCol2 = string("She needs me"); strCol1 = strCol1.assign(strCol2); cout << strCol1 << '\n'; Output: “She needs me”. basic_string& assign(const charT* s) Assigns a string literal argument to the main string, replacing any content that was there. string strCol = string("I love you"); strCol = strCol.assign("She needs me"); cout << strCol << '\n'; Output: “She needs me”. basic_string& assign(initializer_list<charT>) Assigns an initializer list argument to the main string, replacing any content that was there. [cc lang="c" escaped="true" width="780"] string strCol = string("I love you"); strCol = strCol.assign({'S','h','e',' ','n','e','e','d','s',' ','m','e','\0'}); cout << strCol << '\n'; Output: “She needs me”. It is good to always add the nul, \0 at the end of the character list, to form a string literal. basic_string& assign(const charT* s, size_type n) Assigns the first n characters of a string literal argument to the main string, replacing any content that was there. string strCol = string("I love you"); strCol = strCol.assign("She needs me", 9); cout << strCol << '\n'; Output: “She needs”. basic_string& assign(size_type n, charT c) Assigns an argument of n of the same characters to the main string, replacing any content that was there. string strCol = string("I love you"); strCol = strCol.assign(4, 'e'); cout << strCol << '\n'; Output: eeee basic_string& assign(const basic_string& str, size_type pos, size_type n = npos) Assigns n characters of a string object argument, beginning from pos, to the main string, replacing any content that was there. string strCol = string("I love you"); strCol = strCol.assign("She needs me", 4, 5); cout << strCol << '\n'; Output: “needs”. Would throw an exception – see later. Inserting basic_string& insert(size_type pos, const basic_string& str) Inserts the string object argument to the main string, at index, pos. string strCol1 = string("I love you"); string strCol2 = string("hate and "); strCol1 = strCol1.insert(2, strCol2); cout << strCol1 << '\n'; Output: “I hate and love you”. Would throw an exception – see later. basic_string& insert(size_type pos1, const basic_string& str,size_type pos2, size_type n = npos) Inserts a length of n characters from pos2 of string object argument, to the main string, at index, pos1. string strCol1 = string("I love you"); string strCol2 = string("hate, want and need"); strCol1 = strCol1.insert(2, strCol2, 6, 9); cout << strCol1 << '\n'; Output: “I want and love you”. iterator insert(const_iterator p, charT c) Inserts a particular character, which is an argument, into the position pointed to by the iterator. Returns an iterator for the position of the newly inserted character. string strCol = string("I love you"); basic_string<char>::iterator iter = strCol.begin(); ++iter; ++iter; ++iter; ++iter; ++iter; ++iter; basic_string<char>::iterator retI = strCol.insert(iter, 'd'); cout << *retI << '\n'; cout << strCol << '\n'; The output is: ‘d’ “I loved you” iterator insert(const_iterator p, size_type n, charT c) Inserts n of the same character of the argument, into the position, pointed to by the iterator. Returns an iterator for the position of the beginning of the newly inserted same characters. string strCol = string("Tab in the land."); basic_string<char>::iterator iter = strCol.begin(); ++iter; ++iter; ++iter; basic_string<char>::iterator retI = strCol.insert(iter, 2, 'o'); cout << *retI << '\n'; cout << strCol << '\n'; The output is: ‘o’ “Taboo in the land.” basic_string& insert(size_type pos, const charT* s) Inserts an argument string literal at the index, pos in the main string. string strCol = string("Tab in the land."); strCol = strCol.insert(3, "oo"); cout << strCol << '\n'; Output: “Taboo in the land.” basic_string& insert(size_type pos, const charT* s, size_type n) Inserts the first n characters of the argument string literal, at the index, pos in the main string. string strCol = string("Tab in the land."); strCol = strCol.insert(3, "oooo", 2); cout << strCol << '\n'; Output: “Taboo in the land.” Replacing basic_string& replace(size_type pos1, size_type n1, const basic_string& str)) Replaces n1 characters in the main string object from index, pos1, with the argument string object. string strCol1 = string("I love you"); string strCol2 = string("hate you and"); strCol1 = strCol1.replace(2, 4, strCol2); cout << strCol1 << '\n'; Output: “I hate you and you”. Would throw an exception – see later. basic_string& replace(size_type pos1, size_type n1, const basic_string& str,size_type pos2, size_type n2 = npos) Replaces n1 characters in the main string object from the index, pos1, with n2 characters of the argument string object from the index, pos2. string strCol1 = string("I love you"); string strCol2 = string("we hate him and her"); strCol1 = strCol1.replace(2, 4, strCol2, 3, 12); cout << strCol1 << '\n'; Output: “I hate him and you”. basic_string& replace(size_type pos1, size_type n1, const charT* s, size_type n2) Replaces n1 characters in the main string object from the index, pos1, with the first n2 characters of the literal string argument. string strCol1 = string("I love you"); strCol1 = strCol1.replace(2, 4, "hate him and her", 12); cout << strCol1 << '\n'; Output: “I hate him and you”. basic_string& replace(size_type pos, size_type n, const charT* s) Replaces n characters in the main string object from index, pos, with the literal string argument. string strCol1 = string("I love you"); strCol1 = strCol1.replace(2, 4, "hate him and"); cout << strCol1 << '\n'; Output: “I hate him and you”. basic_string& replace(size_type pos1, size_type n1, size_type n2, charT c) Replaces n1 characters in the main string object from the index, pos1, with n2 of the same character of the argument. string strCol1 = string("A bad tablet there."); strCol1 = strCol1.replace(9, 3, 2, 'o'); cout << strCol1 << '\n'; Output: “A bad taboo there.”. iterator erase(const_iterator p) Removes a character at the position pointed to by the iterator; then returns the iterator position, which is now occupied by the character that was next to this character (or end()). The following code illustrates this: string strCol = string("abcd"); basic_string<char>::iterator iter = strCol.begin(); ++iter; ++iter; strCol.erase(iter); cout << strCol[0] << ' ' << strCol[1] << ' ' << strCol[2]<< '\n'; The output: a b d basic_string& erase(size_type pos = 0, size_type n = npos) Removes n characters from the index, pos. string strCol = string("abcd"); strCol.erase(1, 2); cout << strCol[0] << ' ' << strCol[1] << '\n'; Output: a d void push_back(charT c) To add a single character at the end of the string: string strCol = string("abcd"); strCol.push_back('5'); cout << strCol << '\n'; Output: abcd5 void pop_back() Removes the last character without returning it. The size of the string is reduced by 1. string strCol = string("abcde"); strCol.pop_back(); cout << strCol << '\n'; Output : abcd void swap(basic_string& s) The literals of two string objects can be swapped. string strCol1 = string(<a id="post-69618-__DdeLink__781_3724385525"></a>"abcde"); string strCol2 = string("1234567"); strCol1.swap(strCol2); cout << strCol1 << '\n'; cout << strCol2 << '\n'; The output is: "1234567" "abcde" String Operations const charT* c_str() const noexcept Returns a pointer to the first element of the string. The pointer can be incremented. const string strCol = string("abcde"); const char* p = strCol.c_str(); cout << *p << '\n'; ++p; cout << *p << '\n'; Output is: a b Because of the second const in the heading, the program cannot change any character in the string. The construction is preceded by const. const charT* data() const noexcept Returns a pointer to the first element of the string. The pointer can be incremented. const string strCol = string("abcde"); const char* p = strCol.data(); cout << *p << '\n'; ++p; cout << *p << '\n'; Output is: a b Because of the second const in the heading, the program cannot change any character in the string. The construction is preceded by const. basic_string substr(size_type pos = 0, size_type n = npos) const Returns a string object of n characters for the sub-string beginning from the index, pos. const string strCol = string("abcdefghij"); const string retStr = strCol.substr(2, 4); cout << retStr << '\n'; Output: cdef find() Member Functions size_type find(const basic_string& str, size_type pos = 0) const noexcept Looks for a sub-string object beginning from the index, pos. If found, returns the beginning of the sub-string in the main string. string strCol = string("We are the world!"); string strCol1 = string("the"); int num = strCol.find(strCol1, 2); cout << num << '\n'; Output: index: 7 Returns -1, when not found. size_type find(const charT* s, size_type pos = 0) const Looks for a sub-string literal beginning from the index, pos. If found, returns the beginning of the sub-string in the main string. string strCol = string("We are the world!"); int num = strCol.find("are", 0); cout << num << '\n'; Since “pos = 0” is the default, 0 in the argument could have been omitted. Output: 3 Returns -1, when not found. size_type find (const charT* s, size_type pos, size_type n) const Looks for the first n characters of a sub-string literal beginning from the index, pos. If found, returns the beginning of the sub-string in the main string. string strCol = string("The biggest boy"); int num = strCol.find("bigger", 1, 3); cout << num << '\n'; Output: 4 Returns -1, when not found. size_type find(charT c, size_type pos = 0) const Looks for the character, c beginning from the index, pos. If found, returns the beginning of the sub-string in the main string. If not found, returns -1. string strCol = string("We are the world!"); int num = strCol.find('z'); cout << num << '\n'; Output: -1 The following reverse find() member functions exist: size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; size_type rfind(const charT* s, size_type pos = npos) const; size_type rfind(const charT* s, size_type pos, size_type n) const; size_type rfind(charT c, size_type pos = npos) const; Comparison Member Functions int compare(const basic_string& str) const noexcept Compares the argument string object with the main string object. If the main string occurs before the argument (in the dictionary) it returns a positive number. If it occurs after the main string, it returns a negative number. If the two strings are the same, it returns zero. string strCol1 = string("crowd"); string strCol2 = string("people"); int num = strCol1.compare(strCol2); cout << num << '\n'; Output: -13 int compare(const charT* s) const Same as above, but the argument is a string literal. string strCol1 = string("people"); int num = strCol1.compare("people"); cout << num << '\n'; Output: 0 String Operators These operators are applicable to string objects and not necessarily string literals. + Concatenates two string objects, and returns the concatenation. string strCol1 = string("dancing on"); string strCol2 = string(" the moon"); string strCol = strCol1+strCol2; cout << strCol << '\n'; Output: “dancing on the moon”. == Returns 1 for true, if the string objects are the same; and zero for false, if they are not. string strCol1 = string("dancing on"); string strCol2 = string(" on the moon"); bool bl = strCol1 == strCol2; cout << bl << '\n'; Output: 0 != Returns 1 if the string objects are not the same, and zero if they are. string strCol1 = string("dancing on"); string strCol2 = string(" on the moon"); bool bl = strCol1 != strCol2; cout << bl << '\n'; Output: 1 < Returns 1, if the left operand is less than the right operand according to the dictionary, or zero if it is not. string strCol1 = string("dancing on"); string strCol2 = string(" on the moon"); bool bl = strCol1 < strCol2; cout << bl << '\n'; Output: 0 For ordinary characters in C++, in ascending order, numbers come before uppercase letters, which come before lowercase letters. The space character comes before zero and all of them. C++ Main String Character Types char The char type is the original C++ type and would typically store a character in 8 bits. char16_t This stores a character in 16 bits. char32_t This stores a character in 32 bits. wchar_t char16_t and char32_t are wide characters. wchar_t is a wide-character that is proprietary and implementation-defined. These types are called traits. However, C++ refers to them technically as, specializations of traits. This article has focused on the char type. The approach to the other types is slightly different – see later. Other String Operation Member Functions The signatures of other string operation functions are: size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; size_type find_first_of(const charT* s, size_type pos, size_type n) const; size_type find_first_of(const charT* s, size_type pos = 0) const; size_type find_first_of(charT c, size_type pos = 0) const; size_type find_last_of (const basic_string& str, size_type pos = npos) const noexcept; size_type find_last_of (const charT* s, size_type pos, size_type n) const; size_type find_last_of (const charT* s, size_type pos = npos) const; size_type find_last_of (charT c, size_type pos = npos) const; size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; size_type find_first_not_of(const charT* s, size_type pos, size_type n) const; size_type find_first_not_of(const charT* s, size_type pos = 0) const; size_type find_first_not_of(charT c, size_type pos = 0) const; size_type find_last_not_of (const basic_string& str, size_type pos = npos) const noexcept; size_type find_last_not_of (const charT* s, size_type pos, size_type n) const; size_type find_last_not_of (const charT* s, size_type pos = npos) const; size_type find_last_not_of (charT c, size_type pos = npos) const; Conclusion C++ has string literals and string objects. The string object has a collection of characters in sequence, similar to an array of characters in sequence. The difference between the string collection and an array, is, that the string collection can grow in length or shrink in length. A string object is instantiated (constructed) from a string class. A string object is a data structure with member functions. The member functions can be classified under the headings of object construction, element access, string capacity, string member functions with iterator arguments and return types, and string modifiers. String equality and relational operators also exist. View the full article
  • Forum Statistics

    43.5k
    Total Topics
    43k
    Total Posts
×
×
  • Create New...