← Back to Index
Research & Engineering Archive

LPC 10. Strings

By Jingnan Huang · March 27, 2025 · 4352 Words

Last Edit: 25/3/27

Throughout this book, we study different data types. None of the data types discussed before stores a word or sentence, because in C programming language there is no data type that stores a word/sentence.

所以在这里将找到一个储存 String 的解决方案

10.1. What are strings?
#

10.1.1 Store a String
#

10.1.1.1 Declare and Initialize
#

image.png

10.1.1.2. Method 2: Declare now and Initialize later
#

char myString[4];
myString[0] = 'T';
myString[1] = 'h';
myString[2] = 'e';
myString[3] = '\0';

10.1.1.3. Method 3: Declare a Pointer Pointing to a Constant String
#

image.png

image.png

int main(void) {
    char str[] = "Hello";
    str = "APS105";  // 尝试更改数组标识符
    return 0;
}

10.1.2. What is the usage of the '\0' in a string?
#

10.2 Input/Output Strings
#

10.2.1 Output Strings
#

10.2.1.1 Using pringf
#

#include <stdio.h>
int main(void) {
  char s[] = "Hello";
  printf("%.2s\n", s);
  return 0;
}

Printing character vs. a string
#

10.2.1.2 Using puts
#

#include <stdio.h>
int main(void) {
  char s[] = "Hello";
  puts(s);
  return 0;
}

10.2.2 Input Strings
#

10.2.2.1 Using scanf
#

char st[10];
scanf("%s", st);

How does sanf work
#

#include <stdio.h>
int main(void) {
  char st[10];
  printf("Enter a string: \n");
  scanf("%s", st);
  printf("s is saved as: %s\n", st);
  scanf("%s", st);
  printf("s is now saved as: %s\n", st);
  return 0;
}

What if str is longer than array
#

#include <stdio.h>
int main(void) {
  char st[7 + 1];
  printf("Enter a string: \n");
  scanf("%s", st);
  printf("s is saved as: %s\n", st);
  return 0;
Enter a string:
ABCDEFJI
s is saved as: ABCDEFJI

Buffer Overflow
#

10.2.2.2. Using fgets to avoid buffer overflow in scanf
#

Enter a string:
ABCDEFGHI
st is saved as: AB

10.2.2.3. Implement a getStringSafely function

getchar() function
#

#include <stdio.h>
char* getStringSafely(char* s, int n);
int main(void) {
  char st[10];
  printf("Enter string: \n");
  printf("User entered: %s\n", getStringSafely
(st, 7));
  scanf("%s", st);
  printf("This is what's left: %s\n", st);
  return 0;
}
char* getStringSafely(char* s, int n) {
  int charCount = 0;
  char c;
  while ((charCount < n - 1) && ((c = getchar()) 
!= '\n')) {
    s[charCount] = c;
    charCount++;
  }
  s[charCount] = '\0';
  return s;
}

10.3. String Functions
#

10.3.1. Length of the string
#

#include <stdio.h>
#include <string.h>
int main(void) {
  char s[] = "Hello";
  int size = strlen(s);
  printf("String length is %d.\n", size);
  return 0;
}

10.3.1.1. Implementation of strlen
#

#include <stdio.h>
#include <string.h>
// 函数声明
int stringLength(char* s);
int main(void) {
    char s[] = "Hello";                   // 定义字符串
    int size = stringLength(s);           // 调用自定义的 stringLength 函数
    printf("String length is %d.\n", size); // 打印字符串长度
    return 0;
}
// 函数定义
int stringLength(char* s) {
    int count = 0;
    while (s[count] != '\0') {  // 遍历直到遇到 \0
        count++;
    }
    return count;
}

10.3.2. Copy a string into another string
#

10.3.2.1. strcpy
#

#include <stdio.h>
#include <string.h>
int main(void) {
  char s[] = "Hello";
  char d[6];
  printf("d after copying has '%s\'.\n", strcpy(d, s));
  return 0;
}

-> d after copying has 'Hello'

10.3.2.1.1. Implementation of strcpy
#

  #include <stdio.h>
#include <string.h>
char* stringCopy(char* dest, const char* src);
int main(void) {
  char s[] = "Hello"; // 定义源字符串 s 
  char d[6];          // 定义目标字符串 d,有 6 个字符空间
  printf("d after copying has '%s'.\n", 
stringCopy(d, s));
  return 0;
}
char* stringCopy(char* dest, const char* src) {
  int ind = 0;
  
  while (src[ind] != '\0') {
    dest[ind] = src[ind];  // 逐个字符复制
    ind++;
  }
  dest[ind] = '\0';        // 添加结束符
  return dest;             // 返回目标字符串地址
}
char* stringCopy(char* pdest, const char* psrc) {
    char* pdestCopy = pdest;         // 保存目标字符串原始地址

    while (*psrc != '\0') {          // 当源字符串未结束
        *pdestCopy = *psrc;          // 拷贝字符
        pdestCopy++;                 // 移动目标指针
        psrc++;                      // 移动源指针
    }

    *pdestCopy = '\0';               // 添加字符串结束符
    return pdest;                    // 返回目标字符串起始地址
}

10.3.2.2. strncpy
#

image.png

If n is same as the size of src
#

char d[] = "Hello world!";
strncpy(d, "Hello", 5);

If n is larger than size of src
#

char d[] = "Hello world!";
strncpy(d, "Hello", 7);
源字符串 d 原内容: 'H' 'e' 'l' 'l' 'o' ' ' 'w' 'o' 'r' 'l' 'd' '!' '\0'
复制后变成     'H' 'e' 'l' 'l' 'o' '\0' '\0' ...
字符位置:        1   2   3   4   5    6    7

10.3.3 Concatenating Strings
#

10.3.3.1 strcat
#

image.png

10.3.3.2. strncat
#

char s[4] = "Oh";   // s 有 4 个字符空间:"O", "h", '\0', '\0'
char t[] = "No";    // t 是源字符串:"N", "o", '\0'
strcat(s, t);

10.3.4. Comparing Strings
#

10.3.4.1 strcmp
#

#include <stdio.h>
#include <string.h>

int main(void) {
    char s1[40];
    char s2[40];

    printf("Enter two strings separated by new line or white space: ");
    scanf("%s", s1);    // 输入第一个字符串
    scanf("%s", s2);    // 输入第二个字符串

    if (strcmp(s1, s2) < 0) {
        printf("'%s' is before '%s' in dictionary!\n", s1, s2);
    } else if (strcmp(s1, s2) > 0) {
        printf("'%s' is after '%s' in dictionary!\n", s1, s2);
    } else if (strcmp(s1, s2) == 0) {
        printf("'%s' is identical to '%s'!\n", s1, s2);
    }

    return 0;
}
场景 返回值 示例
s1 < s2 小于 0 "apple" VS "banana"
s1 > s2 大于 0 "zebra" VS "apple"
s1 等于 s2 等于 0 "hello" VS "hello"

10.3.4.2 strncmp
#

10.3.5 Looking for in a string
#

10.3.5.1 strchr
#

#include <stdio.h>
#include <string.h>

int main(void) {
    char s[] = "Programming";  // 原始字符串
    char c = 'm';              // 要查找的字符
    int dist = strchr(s, c) - s;  // 找到字符后,计算其在字符串中的索引
    printf("The first %c is found at index %d in '%s'\n", c, dist, s);
    return 0;
}

10.3.5.2 strstr
#

10.4 Array of Strings
#

10.4.1 2D Array of Characters
#

char months[][10] = {
    "January", "February", "March", ...
};
months[0] 是 {'J', 'a', 'n', 'u', 'a', 'r', 'y', '\0', '\0', '\0'}
months[1] 是 {'F', 'e', 'b', 'r', 'u', 'a', 'r', 'y', '\0', '\0'}
...

image.png

10.4.2. 1D array of char*
#

char* months[12];
months[0] = "January";
months[1] = "February";
...
声明方式 指针变量位置 指向内容位置
char* p = "abc"; 静态区(只读)
static char* p = "abc"; 静态区 静态区(只读)
char s[] = "abc"; 栈(拷贝内容)
char* p = malloc(...);
特性 char months[12][10] char* months[12]
是否可改内容 ✅ 可以修改字符内容 ❌ 通常不可以(字符串常量)
是否可换整行字符串 ❌ 不行,不能对数组赋值 ✅ 可以 months[0] = "new"
每行长度是否一致 是(固定长度) 否(每个字符串长度可以不同)
字符串存储在哪里 所有内容在栈(stack) 指针在栈,字符串常量在静态区(只读区)
是否可以初始化时一次性写完 ✅ 可以 ✅ 也可以