Advanced C/C++ Programming - String, Array

Page created by Dorothy Romero
 
CONTINUE READING
Advanced C/C++
Programming
String, Array
Goal of this lecture
                ▪ Get to know the string library and built-in arrays

Dr. Juan J. Durillo
Namespaces
                ▪ Large problems tend to use independently developed libraries, which tend to
                  define a large number of global names, such classes, functions or templates
                ▪ When using libraries from many different vendors is almost inevitable that some
                  names will clash
                ▪ To avoid this, some programmers use very long names for classes, function,
                  variables or any global entity that they define
                      ▪ This solution makes code more complicate

                ▪ In C++, namespaces provide a much more controlling mechanism to avoid name
                  collision

Dr. Juan J. Durillo
Note
                                                                                          In contrast with class declarations,
                Namespaces                                                             namespace declarations do not finish with a
                                                                                                      semilcolon

                ▪ A namespace definition begin with the keyword namespace followed by the
                  namespace name
                ▪ Each name within a namespace must refer to a unique entity within that
                  namespace                                                                            Note
                                                                                                Namespaces are scopes
                      ▪ Different namespaces may have members with the same name

                ▪ Names within a namespace can be directly accessed by other members of the
                  namespace, including nested scopes within these members
                      ▪ Names outside namespace must must indicated the namespace where a name is
                        located

Dr. Juan J. Durillo
Namespaces
                ▪ Namespaces can be discontinuous
                ▪ A namespace declaration either declares a new namespace if no namespace
                  exist or adds to an existing namespace

Dr. Juan J. Durillo
Namespace using Declarations
                ▪ When working with libraries and namespaces, there are two alternatives to
                  indicate that we want a name of a given namespace
                      ▪ Using the complete name (including the namespace and the scope operator ::)
                        ▪ std::cin, every time we want to refer to the cin name include in the standard (std) library
                      ▪ With using declarations                                                                            Note
                                                                                                          Header files should not include using
                        ▪ using std::cin;                                                               declarations. The reason is that the code
                                                                                                        of the header is copied into the including
                        ▪ once included a using declaration, the name (cin) is accessible directly       program’s text. If a header has a using
                        ▪ Each using declaration includes a single namespace member                       declaration, then every program that
                                                                                                           includes that header gets that using
                                                                                                         declaration. As a result, a program that
                                                          using std::cout; using std::endl;              didn’t intend to use the specific library
                                                                                                        name might encounter unexpected name
                                                                                                                         conflicts

Dr. Juan J. Durillo
Library string type
Dr. Juan J. Durillo
C++ strings
▪ A string is a variable-length sequence of characters
▪ The string type is defined in the string header and it is defined in the standard
  (std) namespace
▪ Therefore, to work with string we need to
                                     #include 
                                     using std::string;

      Ways to initialize a string
      string s1                               Default initialization; s1 is the empty string
      string s2(s1)                           s2 is a copy of s1
      string s2 = s1                          Equivalent to s2(s1), s2 is a copy of s1
      string s3(“value”)                      s3 is a copy of the string literal, not including the null
      string s3 = “value”                     Equivalent to s3(‘”value”), s3 is a copy of the string literal
      string s4(n,’c’)                        Initialize s4 with n copies of the character ‘c’
Performing operations with strings
                ▪ Reading and writing strings is possible by using the same IO operators defined in
                  the iostream library to read built-in types
                                          string s;            //empty string
                                          cin >> s;            //read a whitespace-separate string
                                          cout
Performing operations with strings                                                        Note
                                                                                       the operator >> reads and discards leading
                                                                                       whitespace (spaces, newlines, tabs). It then
                                                                                           reads the characters until the next
                ▪ How to read an unknown number of words/strings                          whitespace character is encountered

                                                                                                            Note
                                     string word;                                        the condition of this program tests the
                                     while (cin >> word)                                 stream after the read completes. If the
                                                 cout
Performing operations with strings
                ▪ The empty() function returns a bool indicating whether a given string is or not
                  empty. It is a member function of string
                                           // program to discard empty lines
                                           while (getline(cin,line))
                                                        if (!line.empty())
                                                                     cout
Performing operations with strings
                ▪ When comparing strings, == compares whether two strings contains the same
                  characters
                      ▪ It is case sensitive

                ▪ Additionally we can compare whether a string is smaller or bigger than other
                  using the following operators: 
                      1. If two strings have different lengths and if every character in the shorter string is equal
                         to the corresponding character of the longer string, then the shorter string is less than
                         the longer one
                      2. If any characters at the corresponding positions in the two strings differ, then the result
                         of the string comparison is the result of comparing the first character at which the
                         strings differ        string str = “Hello”;                                            Note
                                                                                                  By rule 1, we see that str is less than phrase
                                               string phrase = “Hello World”;                     By rule 2, we see that slang is greater than
                                               string slang = “Hiya”;                                          both str and phrase

Dr. Juan J. Durillo
Performing operations with strings
                ▪ Most of the library types support assignment
                ▪ The string type is not an exception so we can assign a string object to another

                                        string st1(10,’c’), st2; // st1 is cccccccccc, st2 empty
                                        st1 = st2; // replace the contents of st1 with a copy of st2
                                                      // both st1 and st2 are now the empty string

                ▪ Adding two strings yields a new string that is the concatenation of the left-hand
                  followed by the right-hand operand
                ▪ The string library let us to convert both character literals and character string literals
                  to objects of the string class
                ▪ When mixing strings objects with string literals at lest one operand should be a string
                  when using the concatenation operator +

Dr. Juan J. Durillo
Dealing with characters in a string. Case 1:
                processing every character in a string
                ▪ By far the best approach is to use a range for statement available since C++11
                                      for (declaration : expression)
                                                  statement

                ▪ When dealing with a string object, a string represents a sequence of characters,
                  so we can use it in a range for
                                      string str(“some string”)
                                      for (auto c : str)
                                                   cout
Functions to deal with characters in the cctype
                library
                Ways to initialize a string
                isalnum(c)                    true is c is a letter or a digit
                isalpha(c)                    true if c is a letter
                iscntrl(c)                    true if c is a control character
                isdigit(c)                    true if c is a digit
                isgraph(c)                    true if c is not a space but is printable
                islower(c)                    true if c is a lowercase letter
                isprint(c)                    true if c is a printable character
                ispunct(c)                    true if c is a punctuation character
                isspace(c)                    true if c is whitespace
                isupper(c)                    true if c is an uppercase letter
                isxdigit(c)                   true if c is hexadecimal digit
                tolower(c)                    if c is uppercase, returns is lowercase equivalent
                toupper(c)                    if c is lowercase, returns is uppercase equivalent

Dr. Juan J. Durillo
Dealing with characters in a string. Case 2:
                processing only some characters
                ▪ There are two ways to access individual characters in a string
                      ▪ Using the subscript operator []
                      ▪ Using an iterator

                ▪ The subscript operator [] requires to provide an index that should be >= 0 and <
                  that the string size

                                     // using a subscript for iteration
                                     for (decltype(s.size()) index = 0;index != s.size() && !isspace(s[index]); ++index)
                                                  s[index] = toupper(s[index]);

Dr. Juan J. Durillo
Additional string
                      operations
Dr. Juan J. Durillo
Other ways to construct a string
Additional ways to construct strings
string s(cp, n);                           s is a copy of the first n characters in the array to which cp points. That
                                           array must have at least n characters
string s(s2,pos2);                         s is a copy of the characters in the string s2 starting at the index pos2;
                                           undefined if pos2>s2.size()
string s(s2,pos2,len2);                    s is a copy of len2 characters from s2 starting at the index pos2;
                                           undefined if pos2> s2.size(); regardless of the value of len2, copies at
                                           most s2.size()-pos2 characters

                          const char *cp = “hello world”; // null terminated array                                                 Note
                          char noNull[] ={‘H’, ‘i’};             //not null terminated                                    substr(pos,n) returns n
                                                                                                                         characters from a string,
                          string s1(cp);             // copy up to the null in cp; s1==“hello world”
                                                                                                                            starting from pos
                          string s2(noNull,2);       // copy two characters from noNull, s2==“Hi”
                          string s3(noNull);         // undefined: noNull is not terminated
                          string s4(cp+6, 5);        // copy 5 characters starting at cp[6]; s4==“world”
                          string s8(s1,16);          // throws an out_of_range exception
More operations in the string library
                ▪ A string is a sequential container, and therefore, it provides all the operations that
                                                                                                            Note
                  can be performed on sequential containers                                we will devote a lecture to sequential
                                                                                                           containers in the future
                ▪ The append() member allows to insert. It is a shorthand of inserting at the end of
                  a given string
                ▪ The replace() member is a shorthand way of calling erase and insert

Dr. Juan J. Durillo
String search operations
                ▪ The string class provides six different search functions; they all return a
                                                                                                            Note
                  string::size_type value, which is the index of where the match occurred        searching is case sensitive

                ▪ If there is not match, the function returns a static member named string::npos
                ▪ find() does the simplest search: it looks for its argument and returns the index of
                  the first match that is found, or npos if there is no match
                ▪ A slightly more complicated problem requires finding a match to any character in
                  the search string; the member find_first_of allow us to do it                              Note
                                                                                                  All the search operations
                                string numbers(“0123456789”), name(“r2d2”);                          are also available to
                                // returns 1, i.e, the index of the first digit in name          perform backward searches
                                auto pos = name.find_first_of(numbers);
                                                                                                              Note
                ▪ Similarly, we have the function find_first_not_of(numbers);                     All of them also accept an
                                                                                                      optional parameter
                                                                                                   indicating from where to
                                                                                                        start the search

Dr. Juan J. Durillo
Compare and numeric conversions
                ▪ In addition to the relational operators, the class string also provides a member
                  called compare(), which perform in a similar way as strcmp() (the C library
                  function)
                ▪ Strings frequently contain characters that represent numbers; the new standard
                  introduces
                      Conversions between strings and numbers
                      to_string(val);                 Overloaded function returning the string representation of val, where can
                                                      be any arithmetic type
                      stoi(s,p,b);                    Return the initial substring of s that has numeric content as int, long,
                      stol(s,p,b);                    usigned long, long long, unsigned long long, respectively. b indicates the
                      stoul(s,p,b);                   numeric base to use for the conversion; b defaults to 10. p is a pointer ot
                      stoll(s,p,b);                   a size_t in which to put the index of the first nonnumeric character in s; p
                      stoull(s,p,b);                  defaults to 0, in which case the function does not store the index
                      stof(s,p);                      Return the initial numeric as a float, double or long double, respectively.
                      stod(s,p);                      p has the same behavior as described for the integer conversions
                      stold(s,p);

Dr. Juan J. Durillo
C-Style character string
Dr. Juan J. Durillo
C-Style string
▪ Null-terminated character arrays
          C-style strings
          strlen(p)                           Returns the length of p, not counting the null
          strcmp(p1,p2)                       Compares p1 and p2 for equality; return 0 if p1==p2, a
                                              positive if p1> p2, a negative value if p1< p2
          strcat(p1,p2)                       appends p2 to p1; return p1
          strcpy(p1,p2)                       copies p2 into p1, returns p1

▪ Comparing C-style strings using the relational operators will compare the pointer
  values, not the content of the string
  ▪ The solution is to use strcmp

▪ The strcmp and strcpy functions do not allocate any memory; the programmer is
  responsible
Mixing library string and C-style
                ▪ We can use a null-terminated character array anywhere that we can use a string
                  literal
                      ▪ To initialize or assign a string object
                      ▪ As one operand (but not both) to the string addition operator or as the right-hand
                        operand in the string compound assignment (+=) operator

                ▪ The reverse is not provided: there is no way to use a library string when a C-Style
                  string is required
                      ▪ However, there is a member function named c_str, which we can often use to
                        accomplish what we want
                                      char *str = s; // error: cant’t initialize a char* from a string
                                      const char *str = s.c_str(); // ok

Dr. Juan J. Durillo
Built-in arrays
Dr. Juan J. Durillo
Arrays
▪ An array is a data structure that allow to store sequentially a collection of objects
  of a given type, offering a tradeoff between performance and flexibility
▪ Arrays have fixed-size
▪ An array declaration has the form a[d], where a is the name being defined and d
  is the dimension of the array
▪ The dimension specifies the number of elements and must be greater than zero
▪ The number of elements of the array is part of the array’s type; as a result it
  should be known in compile time, meaning that it needs to be a constant
  expression
Arrays
                 unsigned cnt = 42; // not a constant expression
                 constexpr unsigned sz = 42; // constant expression
                 int array[10]; // array of ten ints
                 int *parr[sz]; // array of 42 pointers to int
                 string bad[cnt]; // error: cnt is not a constant expression
                 string strs[get_size()]; // ok if get_size is constexp, error otherwise

▪ By default, the elements in an array are default-initialized
▪ An array hold objects; therefore there are no arrays of references
▪ We can list initialize the elements in an array, and in this case, omit the dimension
  ▪ If we do omit the dimension, the compiler infers it from the number of initializers
  ▪ If we specify a dimension, the number of initializer must not exceed that dimension
Arrays
                ▪ Character arrays can also be initialized from a string literal
                      ▪ As string literals are null-ended, that null character is copied into the array (the array
                        should be big enough to hold it)
                                      char a1[]={‘C’,’+’, ‘+’};          //list initialization, no null
                                      char a2[] = {‘C’,’+’, ‘+’,’\0’};   // list initialization, explicit null
                                      char a3[] = “C++”;                 // null terminator added automatically
                                      const char a4[6] = “Daniel”;       // error: no space for the null

                ▪ We cannot initialize nor assign one array to another

Dr. Juan J. Durillo
Understanding complicated array declarations
                ▪ Defining arrays that hold pointers is fairly straightforward; defining a pointer or
                  reference to an array is a bit more complicated
                                     int *ptrs[10];              // ptrs is an array of ten pointers to int
                                     int &ref[10];               // error: no arrays of references
                                     int (*Parray)[10] = &arr;   // Parray points to an array of ten ints
                                     int (&arrRef)[10] = arr;    //arrRef refers to an array of ten ints

                ▪ By default, type modifiers bind right to left
                      ▪ The definition of ptrs should be read as we are defining an array of size 10, named ptrs
                        that holds pointer to int
                      ▪ Reading from right to left is not always as useful with array declarations; reading them
                        from inside out makes it much easier to understand the type of Parray for example

Dr. Juan J. Durillo
Pointers and Arrays
                ▪ Pointers and arrays are closely related; in particular, when we use an array, the
                  compiler ordinarily converts the array to a pointer
                ▪ Arrays have a special property- in most places when we use an array, the
                  compiler automatically substitutes a pointer to the first element
                                string nums[] = {“one”, “two”, “three”};
                                string *p2 = nums; // equivalent to p2 = &nums[0];
                ▪ Actually, when we use an array as initializer for a variable defined using auto, the
                  deduced type is a pointer not an array
                                int ia[]={0,1,2,3,4,5,6,7,8,9}; // ia is an array of ten ints
                                auto ia2(ia); // ia2 is an int* that points to the first element in ia
                                ia2 = 42; // error: ia2 is a pointer, and we can’t assign an int to a pointer
                ▪ The conversion to pointer does not happen when we use decltype; the type
                  returned by it is an array of ten ints

Dr. Juan J. Durillo
Pointers are iterators
                ▪ Pointers that address elements in an array have additional operations; in
                  particular they have the same operations as provided by iterator
                ▪ An example is the use of the increment operator to move to one element in the
                  array to the next
                ▪ In an array of ten elements, the end pointer can be obtained as &array[10]; since
                  it points to one past the last valid element in the array (which is array[9])
                ▪ Since C++11, the library provide already the functions begin() and end() which
                  return a pointer to the first and one past the last element in an array

Dr. Juan J. Durillo
Pointers arithmetic
                ▪ Adding (or subtracting) an integral value to or from a pointer, the result is a new
                  pointer, which points to the element the given number ahead (or behind) the
                  original pointer
                ▪ After adding an integral value to a pointer, the result is an element in the same
                  array or a pointer past the end of the array                                     Note
                                                                                                           remember that the compiler transform the
                       constexpr size_t sz = 5;                                                             name of the array as a pointer to the first
                       int arr[sz] = {1, 2, 3, 4, 5};                                                                 element of the array
                       int *ip = arr;                   //equivalent to int *ip = &arr[0];
                       int *ip2 = ip + 4;               // ip2 points to arr[4], the last element in arr
                ▪ Subtracting two pointers give us the difference between those pointers; the
                  pointers must point to elements in the same array
                ▪ Pointer arithmetic is also valid for the null pointer (which has a 0 value)

Dr. Juan J. Durillo
You can also read