Learn C ++ From Scratch (2 Strings, Vectors, and Arrays)

Learn C ++ From Scratch (2 Strings, Vectors, and Arrays)

It can be said that string and vector are the two most important types in the C++ standard library. String supports variable-length strings, and vector represents a variable-length collection.

It can be said that string and vector are the two most important types in the C++ standard library. String supports variable-length strings, and vector represents a variable-length collection.

STRING

Header: <string>

Defined in the namespace std, using std :: string;

string s1;                         // default initialization, s1 is an empty string 
string s2 (s1);                   // s2 is a copy of s1 
string s3 = s1;                 // s3 is a copy of s1 
string s4 ( " value " );            // s4 is A copy of the literal "value", except for the empty character at the end of the literal 
string s5 = " value " ;          // equivalent to the parentheses initialization 
string s6 (n, ' c ' );               // initialize s6 as A string of n consecutive characters	

Here you need to distinguish between direct initialization and copy initialization (you will know after learning about the class, these two initialization calls call a constructor and a copy control of a certain constructor, respectively).

Use the equal sign (=) to initialize a variable. In fact, copy initialization is performed . The compiler copies the initial value to the right of the equal sign to the newly created object. Conversely, without using the equal sign, direct initialization is performed .

string operations

os << s writes s to the output stream os and returns os

is >> s reads the string from is assigned to s, the string is separated by white space, returns is

getline (is, s) reads a line from is assigned to s and returns is

s [n] returns a reference to the nth character in s, position n starts at 0

s1 + s2 returns the result of connecting s1 and s2

// Read an unknown number of string objects

int main ()
{
    string word;
     while (cin >> word)
        cout << word << endl;
     return  0 ;
}	

The size () function of string returns a type of string :: size_type, which is an unsigned value, and it can hold the size of any string object.

When adding a string object to a character literal or string literal, you must ensure that at least one of the operands on both sides of each addition operator (+) is a string object:

int main()
{
    string str1("hell");
    string str2 = str1 + 'o' + " world";
    cout << str2 << endl;
    return 0;
}

What about characters in string objects?

A set of standard library functions is defined in the header file cctype

isalnum (c) is true when c is a letter or number

isalpha (c) is true when c is a letter

iscntrl (c) is true when c is a control character

isdigit (c) is true when c is a number

isgraph (c) is true when c is not a space but printable

islower (c) is true when c is a lowercase letter

isprint (c) is true when c is a printable character

ispunct (c) is true when c is punctuation

isspace (c) is true when c is blank (ie c is a space, horizontal tab, vertical tab, carriage return, line feed, paper feed)

isupper (c) is true when c is an uppercase letter

isxdigit (c) is true when c is a hexadecimal digit

tolower (c) If c is an uppercase letter, output the corresponding lowercase letter; otherwise, output c as is

toupper (c) If c is a lowercase letter, output the corresponding uppercase letter; otherwise, output c as is

string str3 ( " abcdefgh0123 " );
     for (auto c: str3) {
         if (isxdigit (c)) {
            cout << " 0x " << c << endl;
        } else {
            cout << c << endl;
        }
}	
Vector

Also called (container), header <vector>, using std :: vector;

vector is a class template . A template itself is not a class or function. You can think of a template as a description written by a compiler-generated class or function. The process by which a compiler creates a class or function from a template is called instantiation. When using a template, you need to indicate what type the class or function should be instantiated by the compiler.

Use of vector

vector <int> ivec; // ivec holds objects of type int

vector <ClassObj> co_vec; // co_vec holds an object of type ClassObj

vector <vector <string >> files; // elements stored in files are vector objects

Definition and initialization

vector <T> v1; // v1 is an empty vector, its potential elements are of type T, and default initialization is performed

vector <T> v2 (v1); // v2 contains copies of all elements of v1

vector <T> v2 = v1; // equivalent to v2 (v1)

vector <T> v3 (n, val); // v3 contains n repeated elements, and the value of each element is val

vector <T> v4 (n); // v4 contains n objects that repeatedly perform value initialization

vector <T> v5 {a, b, c ...}; // list initialization, including the elements in {}

vector <T> v6 = {a, b, c ...}; // same as above

When using list initialization, note:

vector <int> v1 {10}; // v1 has only one element

vector <int> v2 (10); // v2 has 10 elements

vector <int> v3 {10, 1}; // 2 elements, 10, 1

vector <int> v4 (10, 1); // 10 elements with a value of 1

Use parentheses: the value provided is used to `(construct vector) object

Use a curly brace: list to initialize the vector object, that is, the initialization process will treat the values in the curly braces as a list of element initial values as much as possible. Only when the list initialization cannot be performed, other initialization methods are considered.

vector <string> v5 {10}; // v5 has 10 elements initialized by default

vector <string> v6 {10, "hi"}; // v6 has 10 elements whose value is "hi"

Although the above two statements use curly braces, the value (10) in the curly braces does not match the element type (string) and cannot be used as the initial value of the element. The compiler will try to initialize the object using the constructor.

vector <string> v7 {10, "hi", "hello"}; // error

Add elements to a vector object using push_back

    vector <int> ivec;

    for (int i = 0; i! = 10; ++ i) {

      ivec.push_back (i);

    }
Iterator

Provides the type of iterator. It has begin and end member functions. Begin returns an iterator pointing to the first element (or first character); end returns an iterator of the container (or string object) "next position of the tail element" .

auto b = ivec.begin (), e = ivec.end ();

If the container is empty, begin and end return the same iterator, both after-tail iterators.

Standard library types with iterators use iterator and const_iterator to represent the type of iterator:

    vector <int> :: iterator iter1; // iter1 can read and write elements of vector <int>

    string :: iterator iter2;

    vector <int> :: const_iterator iter3; // iter3 can only read elements, not elements

Operations supported by vector and string iterators

iter + n iter-n iter + = n iter-= n

iter1-iter2 The result of subtracting two iterators is the distance between them. The two iterators participating in the element must point to the next position of the element or the tail element in the same container

>,> =, <, <=

Note: Two iterators cannot be added together! !! !! (Pointless)

Array

In C ++ code, use vectors instead of arrays whenever possible.

Array declaration: a [d], where a is the name of the array, and d is the dimension of the array. The dimension indicates the number of elements in the array, so it must be greater than 0. The number of elements in the array is also part of the array type. The dimension must be known at compile time. Therefore, the dimension must be a constant expression:

    unsigned cnt = 10;

    constexpr unsigned sz = 10;

    int arr [10]; // correct

    int * parr [sz]; // array containing 10 integer pointers

    string err [cnt]; // Error: cnt is not a constant expression

    string strs [GetSize ()]; // true when GetSize () is constexpr, otherwise wrong

The type of the array index is size_t. Size_t is a machine-dependent unsigned type. It is designed to be large enough to represent the size of any object in memory.

In many places where array names are used, the compiler will automatically replace them with a pointer to the first element of the array:

    string nums [] = {"a", "b", "c"};

    string * p = & nums [0]; // points to the first element of nums

    string * ps = nums; // equivalent

In some cases, the operation of an array is actually a pointer operation, so when using an array as the initial value of an auto variable, the inferred type is a pointer instead of an array:

    int ia [] = {0,1,2,3,4,5};

    auto ia2 (ia); // ia2 is an integer pointer to the first element of ia

The above conversion does not occur when using the decltype keyword:

    decltype (ia) ia3 = {0,1,2,3,4,5};

    ia3 [4] = 10;

The standard library functions begin and end are similar to the two members of the same name in the container, and they work on arrays.

C-style string

It is not a type, but a convention written to express and use strings. Strings written in this way are stored in a character array and end with a null character.

  strlen (p) returns the length of p, excluding null characters

  strcmp (p1, p2) compares p1 and p2, if p1 == p2, returns 0, if p1> p2, returns a positive value, otherwise returns a negative value

  strcat (p1, p2) appends p2 to p1 and returns p1

  strcpy (p1, p2) copies p2 to p1 and returns p1

  string object is converted to a C-style string: str.c_str ();

I originally wanted to write the vector implementation in "STL Source Code Analysis ", but there are too many contents, so at this stage I will only write the basic knowledge of C ++, and then write other in-depth content separately.

Read a string char by char from an associative pointer array

I hope the title of my question is correct.

I hope the title of my question is correct.

I have a stringpool

char **string_pool;

that gets initiated in a function like

string_pool = malloc( sizeof(char *) * 1024);

i get strings from stdin and scanf them into the array

scanf("%[^\n]s", &string_pool[index]);

so i can print it out using printf

printf("gets %s\n", &string_pool[index]);

how can i

  • get the length of string_pool[index]
  • read string_pool[index] char by char in a loop

Thank you

Edit

Maybe i should explain it a bit more, its a virtual machine with a virtual instruction set and a program like

push 1
read
gets

should :

  • push 1 on the stack -> let x be 1
  • read stdin as string into string_pool[x]
  • push all characters onto the stack

the functions looks like

    case GETS: {
        int index = popv(); // index is already on top of the stack
        int strl = strlen(&string_pool[index]);
    printf("gets %s with a length of %d\n", &amp;string_pool[index], strl);
    // pseudo code
    // push each char as integer on the stack
    foreach(char in string_pool[index]) push((int)char);

    break;
}

case READ: {  
    int index = popv();          
    scanf("%[^\n]s", &amp;string_pool[index]);
    break;
}

case WRITE: {  
    int index = popv();          
    printf("%s", &amp;string_pool[index]);
    break;
}

My problem is in the GETS case. I want to push every char as int onto the stack.

Increased array size. after increaseSize function some arguments of the same array are invalid. C lang

The program takes some txt input from "numbers.txt" file. It first counts the&nbsp;<strong><em>amount</em></strong>&nbsp;of all the numbers (freqCount)in that text file, than reads the file again and with the use of malloc it creates two arrays A and B , of which both have size equal to the&nbsp;<strong>amount</strong>&nbsp;of all the numbers in the text file. So far so good.

The program takes some txt input from "numbers.txt" file. It first counts the amount of all the numbers (freqCount)in that text file, than reads the file again and with the use of malloc it creates two arrays A and B , of which both have size equal to the amount of all the numbers in the text file. So far so good.

Now i want to increase the size of the array A, so that I can put "freqCount" more arguments in it. In the freqRepeat function I created, there is a function increaseSize which takes that same array A, and uses realloc to add 2*freqCount more arguments in it.

After calling the mentioned function increaseSize there is a problem, because only part of the arguments remain unchanged, and there are few arguments that become some huge number. This is a major issue. Can anyone please provide me with some help ? thanks

ps. I include the expemplary text file input at the end of the code.

#include <stdio.h>
#include <stdlib.h>
int read_ints(const char *file_name, int *result);
int *scanFreq(const char *file_name, int *A, int *B, int *resultTab);
int freqRepeat(int *A, int *B, int freqCount);
int *increaseSize(int *A, int freqCount);
void calcmalc(int freqCount);
int *nextArray(int *A, int *B, int freqCount, int freqStart);

int main()
{
int result = 0;
int resultTab = 0;
int freqCount;
freqCount = read_ints("numbers.txt", &result);
printf("freqCount is %d", freqCount);
int *A = (int *)malloc(freqCount * sizeof(int));
int *B = (int *)malloc(freqCount * sizeof(int));
scanFreq("numbers.txt", A, B, &resultTab);
freqRepeat(A, B, freqCount);

}
int read_ints(const char *file_name, int *result)
{
FILE *file = fopen("numbers.txt", "r");
int i = 0;
int n = 0; //row number//

if (file == NULL)
{
printf("unable to open file %s", file_name);
}

while (fscanf(file, "%d", &i) == 1)
{
n++;
printf("%d\n ", i);
*result += i;
printf("\n we are at row nr. %d sum of this number and all numbers before is: %d\n", n, *result);
}
fclose(file);
return n;
}
int *scanFreq(const char *file_name, int *A, int *B, int *resultTab)
{
FILE *file = fopen("numbers.txt", "r");
int i = 0;
int n = 0; //row number//

if (file == NULL)
{
printf("unable to open file %s", file_name);
}

while (fscanf(file, "%d", &i) == 1)
{
n++;
*resultTab += i;
B[n] = i;
A[n] = *resultTab;
}
fclose(file);
return 0;
}

int freqRepeat(int *A, int *B, int freqCount)
{
int lastFrequency;

lastFrequency = freqCount;
freqCount = freqCount + freqCount;
A = increaseSize(A, freqCount);

printf("\n\nwcis enter\n\n");
getchar();

for (int i = 1; i < 15; i++)
{
printf("array argument after increasing array size %d \n", A[i]);

// why some of the arguments have been changed ????????
}

return 0;
}
int *increaseSize(int *A, int freqCount)
{

return realloc(A, 2 * sizeof(int));
}

text input:
-14
+15
+9
+19
+18
+14
+14
-18
+15
+4
-18
-20
-2
+17
+16
-7
-3
+5
+1
-5
-11
-1
-6
-20
+1
+1
+4
+18
+5
-20
-10
+18
+5
-4
-5
-18
+9
+6
+1
-19
+13
+10
-22
-11
-14
-17
-10
-1
-13
+6
-17