C-style string

C-style string

A string is a series of characters stored in consecutive bytes in memory. There are two ways to process strings in C++. The first one comes from the C language and is often called C-style string; the other is a method based on the string library.

This article introduces C-style strings.

A series of characters stored in consecutive bytes means that the string can be stored in a char array , where each character is in its own array element. C-style strings have a special property: they end with a null character, which is written as \0 , and at least the ASCII code is 0, which is used to mark the end of the string. E.g:

char dog[8] = {'b','e','a','u','x',' ','I','I'};   //不是字符串
char cat[8] = {'f','a','t','e','s','s','a','\0'};   //是字符串
  • Both of these are char arrays, but only the second is a string. Null characters are essential for C-style strings. C++ has many functions for processing strings, including those used by cout, which process the characters in the string one by one until a null character is found.

If you use cout to display the above dog array (it is not a string), cout will print out the 8 letters in the array, and then interpret the subsequent bytes in the memory as the characters to be printed until it encounters a null character.

In the cat array example, the method of initializing the array to a string requires a lot of single quotes, and you must remember to add null characters, which is very troublesome. There is a better way to initialize a character array to a string-just use a double-quoted string that is lavish. This kind of string is called a string constant or string literal ( string literal), as follows:

char bird[11] = "Mr. Cheeps";                 //结尾自动包含\0
char fish[] = "Bubbles";                      //让编译器自动计数

The string enclosed in double quotes implicitly contains the trailing null character. When various C++ input tools input the string into the char array, the trailing null character will be automatically added.

Make sure that the array is large enough to store all characters in the string-including null characters. When initializing character arrays with string constants, it is safer to let the compiler automatically calculate the number of elements.

String constants (using double quotes) and character constants (using single quotes) are not interchangeable.
Character constants (such as'S') are shorthand representations of string encoding, and "S" is not a character constant, it represents a string composed of characters S and \0. Moreover, "S" actually represents the memory address where the string is located.

char shirt_size = 'S';               //合理,将83赋给shirt_size
char shirt_size = "S";               //类型不匹配,试图将一个内存地址赋给shirt_size                   

1. Concatenate string constants

Sometimes, the string is too long to fit on one line. C++ allows you to concatenate string constants. Two strings enclosed in double quotes are combined into one. In fact, any two character creation constants separated by whitespace (space, tab, and newline) will be automatically spliced ​​into one. Therefore, all the output statements in the west are equivalent:

cout << "I'd give my right arm to be" " a great violinist.\n";
cout << "I'd give my right arm to be a great violinist.\n";
cout << "I'd give my right ar"
"m to be a great violinist.\n";

Note: Spaces will not be added between the connected strings during splicing, and the first character of the second string will immediately follow the last character of the first string (without considering \0). The \0 in the first string will be replaced by the first character of the second string.

2. Use strings in arrays

Procedure 4.2

#include<iostream>
#include<cstring>           //使用strlen()函数
int main()
{
    using namespace std;
    const int Size = 15;
    char name1[Size];                               //空数组
    char name2[Size] = "C++owboy";                  //初始化数组

    cout << "Howdy! I'm " << name2;
    cout << "! What's your name?\n";
    cin >> name1;
    cout << "Well, " << name1 << ", your name has ";
    cout << strlen(name1) << " letters and is stored\n";
    cout << "in an array of " << sizeof(name1) << " bytes.\n";
    cout << "Your initial is    " << name1[0] << ".\n";
    name2[3] = '\0';                               //设置空字符
    cout << "Here are the first 3 charaters of my name: ";
    cout << name2 << endl;
    cin.get();
    cin.get();
    return 0;
}

operation result:
Write picture description here

sizeof() returns the length of the entire array: 15 bytes;
strlen() returns the length of the string stored in the array, not the length of the array itself. strlen() only counts visible characters, not null characters.

Program 4.2 sets name2[3] to a null character, so that the string ends after the third character.

3. String input

Program 4.2 has a flaw, but the flaw was masked due to carefully selected inputs.
Procedure 4.3

#include<iostream>
int main()
{
    using namespace std;
    const int ArSize = 20;
    char name[ArSize];
    char dessert[ArSize];

    cout << "Enter your name:\n";
    cin >> name;
    cout << "Enter your favorite dessert:\n";
    cin >> dessert;
    cout << "I have some delicious " << dessert;
    cout << " for you, " << name << ".\n";
    cin.get();
    cin.get();
    return 0;
}

Row result:
Write picture description here

After entering the name (CSDN blog), the program will display it without entering the dessert, and immediately display the last line.

How does cin determine the completion of string input?
Since you cannot use the keyboard to enter a null character, cin uses white space (spaces, tabs, and newlines) to determine the end of the string.

This means that cin only reads one word when getting the character array input. After reading the word, cin puts the string into the array and automatically adds a null character at the end.

Therefore, in program 4.3, cin takes CSDN as the first string, puts it in the name array, and automatically adds a null character at the end. This leaves the blog in the input queue. When cin searches for the dessert in the input queue, the blog is found, so cin reads the blog and stores it in the dessert.

Another problem is that the length of the input string may be longer than the target array.

4. Read one line of string input at a time

Reading one word at a time is usually not the best option. To enter an entire phrase instead of a word as a string, a line-oriented rather than word-oriented approach is required.
The classes in istream (such as cin) provide some line-oriented class member functions: getline() and get(). Both functions can read a line until a newline character is reached. The difference is that getline() will discard the newline character, while get() will keep the newline character in the input sequence.

1. Line-oriented input: getline()

Using the cin.getline() function has two parameters. The first parameter is the name of the array used to store the input line; the second parameter is the number of characters to be read. If this parameter is 20, it will read up to 19 Characters, the remaining space is used to store the empty characters added at the end of the animation. The getline() member function stops reading when reading the specified number of characters or when it encounters a newline character.

cin.getline(name,20);  //将输入读入到一个包含20个元素的name数组中

Procedure 4.4

#include<iostream>
int main()
{
    using namespace std;
    const int ArSize = 20;
    char name[ArSize];
    char dessert[ArSize];

    cout << "Enter your name:\n";
    cin.getline(name, ArSize);       //读取一行
    cout << "Enter your favorite dessert:\n";
    cin.getline(dessert, Arsize);
    cout << "I have some delicious " << dessert;
    cout << " for you, " << name << ".\n";
    cin.get();
    cin.get();
    return 0;
}

Write picture description here

2. Line-oriented input: get()

Cin.get() is similar to getline(), and their parameters are the same. But when it reaches the end of the line, get() does not discard the newline character, but keeps the newline character in the input queue. Suppose we call get() twice in a row:

cin.get(name, Arsize);
cin.get(dessert, Arsize);   //第二次调用看到的第一个字符便是换行符,因此get()认为已到达行尾,
                            //而没有发现任何可读取的内容.

There is another variant of get(). Use cin.get() without any parameters to read the next character (even a newline character), so it can be used to handle the newline character, just to read the next line Prepare, such as:

cin.get(name, Arsize);
cin.get();
cin.get(dessert, Arsize);

Or merge the two class member functions:

cin,get(name, Arsize).get();     
  •  

This is possible because cin.get(name,Arsize) returns a cin object, which then calls the get() function. Similarly, the following statement reads two consecutive input lines into the arrays name1 and name2, respectively, and its effect is the same as calling cin.getline() twice:

cin.getline(name1, Arsize).getline(name2, Arsize);
  •  

Procedure 4.5

#include<iostream>
int main()
{
    using namespace std;
    const int ArSize = 20;
    char name[ArSize];
    char dessert[ArSize];

    cout << "Enter your name:\n";
    cin.get(name, ArSize).get();       //读取一行
    cout << "Enter your favorite dessert:\n";
    cin.get(dessert, ArSize).get();
    cout << "I have some delicious " << dessert;
    cout << " for you, " << name << ".\n";
    cin.get();
    cin.get();
    return 0;
}

3. Blank lines and other issues

When get() reads the blank line, the failbit will be set, and the following input will be blocked, but the following command can be used to restore the input:

cin.clear();
  •  

If the input line contains more characters than specified, getline() and get() will leave the remaining characters in the input queue. getline() will also set the invalid bit and close the subsequent input.

5. Mixed input string and number

Mixing numbers and line-oriented strings can cause problems.
Procedure 4.6

#include<iostream>
int main()
{
    using namespace std;
    cout << "What year was your house built?\n";
    int year;
    cin >> year;
    cout << "What is its street address?\n";
    char address[80];
    cin.getline(address, 80);
    cout << "Year built: " << year << endl;
    cout << "Address: " << address << endl;
    cout << "Done!\n";
    cin.get();
    cin.get();
    cin.get();
    return 0;
}

Operation result: The
Write picture description here
user has no opportunity to enter the address at all. The problem is that when cin reads the year, it leaves the linefeed generated by the enter key in the input queue. After cin.getline() sees the newline character, it will consider it as a blank line and assign an empty string to the address array.
The solution is to discard the newline character before reading the address. Such as:

cin>>year;
cin.get();            //or cin.get(ch);
  •  
(cin>>year).get();         //or (cin>>year).get(ch);
  •  

C++ programs often use pointers (not arrays) to handle strings.

Guess you like

Origin blog.csdn.net/digitalkee/article/details/111815552