Basic Concepts
Strings can be assigned to different areas of memory, typically using pointers to support string manipulation. A string is a sequence of characters ending with an ASCII character Nul. The ASCII character Nul is represented as a. Strings are usually stored in an array or in memory allocated from the heap. However, not all character arrays are strings. For example, a character array might not have nul characters.
There are two types of strings in C.
* Single-byte string . A sequence that consists of a char data type.
* wide string . A sequence consisting of wchar_t data types.
The wchar_t data type is used to represent a wide string, possibly 16-bit or 32-bit wide. Both of these strings end with NUL. Wide characters are primarily used to support non-Latin character sets and are useful for applications that support foreign languages.
The length of the string is the number of characters except for the NUL character. When allocating memory for a string, remember to reserve space for the NUL character. Note that NUL is a character that is defined as \ s and is not the same as null (void* (0)). Null is used to represent a special kind of pointer.
A character constant is a sequence of characters that is caused by single quotation marks. Character constants are usually composed of one character or more than one character, such as an escape character. In C, they are of type int. The length of a char is 1 bytes, and the length of a character literal is 4 bytes.
printf ("%d\n", sizeof (' a '));//4
There are 3 ways to declare a string: literal , character array , character Pointer . String literals are sequences of characters that are enclosed in double quotation marks and are commonly used for initialization, which are in the string literal pool. If you declare an array of 32 characters, you can only put 31 string literals, because the string ends with nul. The position of the string in memory depends on the location of the declaration.
When you define a literal, you typically assign it to a literal pool, and when you use the same literal multiple times, there is usually only one copy in the pool. The literal is generally considered immutable. You can turn off the literal pool to generate multiple replicas. Where it is not important to use string literals, it has no scope concept.
Some compilers allow you to modify a string, so it is a good idea to declare a string that you do not want to be modified as a constant.
The way the string is initialized depends on whether the variable is declared as an array or a pointer, and the memory used by the string is either a block of memory that the pointer points to. We can get characters from string literals or other places, such as standard input.
Char head[] = "Hello man";p rintf ("Size of the head is:%d\n", sizeof (head));//size of head is:10
you can see that "Hello Man" has 9 characters, but the length is 10 because there are nul characters. You can also strcpy the function to initialize the HA array.
Char head1[10];strcpy (head1, "Hello Man");
Be careful not to use the name of the array as the left value.
Dynamic memory allocation can provide more flexibility, or may cause memory to exist longer. You typically use malloc and strcpy to initialize a string.
Char* head2;
Head2 = (char*) malloc (strlen ("Hello Man") +1); strcpy (head2, "Hello-man");
Note When using malloc to determine the required memory length, reserve space for NUL and use strlen instead of sizeof. sizeof returns the length of the array and the pointer, not the length of the string. Initializing a pointer with a string literal causes the pointer to point to the string literal pool. Note that the character literal is not assigned to the pointer because it is of type int. The character literal can be assigned to the pointer after the solution.
* (head2 + 7) = ' E ';p rintf ("Head2 is%s\n", head2);//head2 are Hello men
In summary, the string may be in global or static memory (global or static array), or it may be in a string literal pool ({...} ), which may be on the heap (malloc), may be in the stack frame of the function (char array[]). The position of the string determines how long it can exist and which programs can access it. A string of global memory is always present and can be accessed by multiple functions, and a static string is always present, but only the function that defines it can access it, and the string on the heap may be accessed by multiple functions until it has been released.
Standard string Manipulation
The standard way to compare strings is the strcmp function. Its prototype is as follows.
int strcmp (const char* s1, const char* s2);
Returns 0 if two strings are equal. S1 is greater than S2 and returns a positive number. S1 is less than S2 and returns a negative number.
Char command[16];p rintf ("Enter a command:"), scanf ("%s", command), if (strcmp (command, "quit") ==0)
{ printf ("You typed quit!\n");} else{ printf ("I don ' t know what do you typed!\n");}
Note If the IF (Command = = "Quit") is used here, the actual command address and string literal address are compared.
The copy string is typically implemented using the strcpy function, which is prototyped as follows:
char* strcpy (char* s1, const char* s2);
there is a class of applications that read into a series of strings that are stored in the array of least memory. Create a string of characters that is long enough to hold the longest string that the user is allowed to enter, and then read it into the array. With the read string, we can allocate the appropriate memory based on the length of the string.
Char mynames[32];char* myname[30];size_t count = 0;printf ("Enter a name:"); scanf ("%s", mynames); Myname[count] = ( char*) malloc (strlen (mynames) +1); strcpy (Myname[count], mynames); count++;
You can repeat this operation in a loop.
Two pointers can refer to the same string. Two pointers refer to the same address as an alias . Assigning a pointer to another pointer simply copies the address of the string.
String concatenation involves merging of two strings. This is usually done with strcat . The prototype of this function is:
char* strcat (char* s1, const char* s2);
Here's how to use the buffer stitching string.
char* error = "error:"; char* errormsg = "Not Enough memory!"; char* _buffer = (char*) malloc (strlen (Error) + strlen (errormsg) + 1); strcpy (_buffer, error); strcpy (_buffer, errormsg); printf ("%s\n", _buffer);p rintf ("%s\n", error);p rintf ("%s\n", errormsg);
If you use strcpy (Error, errormsg) directly, some unknown content after the error string literal address may be overwritten because we do not allocate independent memory for the new string. The common mistake of stitching a string is that there is no extra space allocated for the new string. Also be careful not to use character literals instead of string literals as arguments to the function.
passing and returning strings
Define a function first.
size_t strlength (char* string) {size_t length = 0;while (* (string++)) {length++;} return length;} Char simplearray[] = "simple string"; char* simpleptr = (char*) malloc (strlen ("simple string") +1); strcpy (Simpleptr, "Simp Le string ");p rintf ("%d\n ", Strlength (Simpleptr));//13
to call this function on a pointer, you only need to pass in the name of the pointer. This function can also be used for arrays. The name of the array here is interpreted as the address.
You can also use the Fetch address operator for the 0 subscript of the array, but that's too cumbersome: Strlength (&simplearray[0]).
Declaring a parameter as a pointer to a character constant prevents the string from being modified. If you want the function to return a string initialized by the function, you must decide whether the function caller is responsible for freeing the allocated memory. If memory is allocated dynamically within the function and returns a pointer to that memory, the caller must be responsible for eventually releasing the memory, which requires the caller to be aware of how the function is used.
The main function is usually the first function that an application executes. For command-line-based programs, it is common to switch on certain features by passing some information on them. For example, the LS command under Linux performs different behaviors by accepting parameters such as-la. C supports command-line arguments through the argc and argv parameters. The first parameter, ARGC, is an integer that specifies the number of arguments to pass. The system will pass at least one parameter, which is the name of the executable file. The second parameter, argv, is usually seen as a one-dimensional array of string pointers, each referencing a command-line argument.
int main (int argc, char** argv) {int i =0;while (I<ARGC) {printf ("Argv[%d]is%s\n", I,argv[i]);//argv[0]is./mysenderi+ +;}}
As you can see, without any parameters attached, one of the parameters that comes with the default is./mysender, which is the name of my compiled file. Try the following:./mysender-f jack-la limit = 100, at which time the output is:
Argv[0]is./mysenderargv[1]is-fargv[2]is jackargv[3]is-laargv[4]is limitargv[5]is =argv[6]is 100
Since I separated the "=" symbol with a space, the result "=" is treated as a parameter. You should actually separate each parameter with a space, and the argument itself should not contain a space.
When a function returns a string , the actual address of the string is returned. This could be the address of a string literal, possibly the address of a dynamic memory, or the address of a local string variable.
Let's look at the first case. For static pointers to string literals, it should be noted that repeated use in different places overwrites the last result. Strings are not always treated as constants, and the string constant pool can be closed by command, and declaring a string as a constant prevents the string from being modified. If you are returning dynamically allocated memory, be sure to keep a memory leak in mind. It may be problematic to return the address of the local variable string, since the memory may be covered by another stack frame after the function has finished executing. For example, if you declare an array of strings in a function and initialize them, and then return the address of the array, the memory used by this array is unsafe and faces the risk of being covered by the stack frame of other functions.
function pointers and strings
Program execution through function pointers is a very flexible approach.
#include <stdio.h> #include <stdlib.h> #include <string.h>char* stringtolower (const char* string) { char* tmp = (char*) malloc (strlen (string) + 1) char* start = Tmp;while (*string! = 0) {* (tmp++) = ToLower (* (string++));} *tmp = 0;return start;} Main () {typedef int (fptroperation) (const char*, const char*), int compare (const char* s1, const char* s2) {return strcmp (S1, s2);} int compareignorecase (const char* s1, const char* s2) {char* T1 =stringtolower (S1); char* T2 =stringtolower (s2); int result = strcmp (T1,T2); free (t1), free (T2); return result;} void sort (char* array[], int size, fptroperation operation) {int swap = 1;while (swap) {swap = 0;int L = 0;while (l<size-1) {if (operation (array[l],array[l+1]) >0) {swap = 1;char* tmp = array[l];array[l] = array[l+1];array[l+1] = tmp;} l++;}}} void display (char* names[], int size) {int i = 0;while (i<size) {printf ("%s", Names[i]); i++;} printf ("\ n");} char* names[] = {"Jack", "Rose", "Titanic", "Hello", "World"};char* newnames[] = {"Jack", "Rose", "Titanic"," Hello "," World "};sort (names, 5, Compare);d isplay (names,5);//titanic World Hello Jack Rose Sort (newnames, 5, Compareignorecase);d isplay (Newnames, 5);//hello Jack Rose Titanic World}
This example uses a function pointer to implement string comparisons under different rules.
In-depth understanding of the C pointer V: Pointers and strings