《明解C語言》示例程式碼和練習程式碼[第11章]
阿新 • • 發佈:2019-02-05
第11章 字串和指標
示例程式碼:
示例程式碼11-1
/*
用陣列實現的字串和用指標實現的字串
*/
#include <stdio.h>
int main(void)
{
char str[] = "ABC"; // 用陣列實現的字串
char *ptr = "123"; // 用指標實現的字串
printf("str = \"%s\"\n", str);
printf("ptr = \"%s\"\n", ptr);
return (0);
}
示例程式碼11-2
/* 用陣列實現的字串和用指標實現的字串的相同點 */ #include <stdio.h> int main(void) { int i; char str[] = "ABC"; char *ptr = "123"; for (i = 0; str[i]; i++) putchar(str[i]); // str[i]是第一個字元之後的第i個元素 putchar('\n'); for (i = 0; ptr[i]; i++) putchar(ptr[i]); // str[i]是第一個字元之後的第i個元素 putchar('\n'); printf("str = \"%s\"\n", str); // str是指向第1個字元的指標 printf("ptr = \"%s\"\n", ptr); // ptr是指向第1個字元的指標 return (0); }
示例程式碼11-3
/* 字串賦值(?) */ #include <stdio.h> int main(void) { char str[] = "ABC"; char *ptr = "123"; str = "DEF"; // 錯誤:不能這樣賦值 ptr = "456"; // 正確:指向另一個字串字面量 printf("str = \"%s\"\n", str); printf("ptr = \"%s\"\n", ptr); return (0); }
示例程式碼11-4
/*
用陣列實現的字串和用指標實現的字串(其二)
*/
#include <stdio.h>
int main(void)
{
char str[6] = "ABC"; // 用陣列實現的字串
char *ptr = "123"; // 用指標實現的字串
printf("str = \"%s\"\n", str);
printf("ptr = \"%s\"\n", ptr);
return (0);
}
示例程式碼11-5
/* 用“陣列實現的字串”的陣列和“用指標實現的字串”的陣列 */ #include <stdio.h> int main(void) { int i; char st[3][6] = {"Turbo", "NA", "DOHC"}; char *pt[3] = {"12345", "12", "1234"}; for (i = 0; i < 3; i++) printf("st[%d] = \"%s\"\n", i, st[i]); for (i = 0; i < 3; i++) printf("pt[%d] = \"%s\"\n", i, pt[i]); return (0); }
示例程式碼11-6
/*
判斷字串的長度(指標版)
*/
#include <stdio.h>
// 返回字串s的長度
size_t str_length(const char *s)
{
size_t len = 0;
while (*s++)
len++;
return (len);
}
int main(void)
{
char st[100];
printf("請輸入字串:");
scanf("%s", st);
printf("字串%s的長度為%u。\n", st, (unsigned)str_length(st));
return (0);
}
示例程式碼11-7
/*
複製字串
*/
#include <stdio.h>
// 將字串s複製到d
char *str_copy(char *d, const char *s)
{
char *t = d;
while (*d++ = *s++)
;
return (t);
}
int main(void)
{
char s1[128] = "ABCD";
char s2[128] = "EFGH";
printf("字串s1:"); scanf("%s", s1);
str_copy(s2, s1);
puts("s1複製到了s2。");
printf("s1 = %s\n", s1);
printf("s2 = %s\n", s2);
return(0);
}
示例程式碼11-8
/*
複製字串(誤例)
*/
#include <stdio.h>
// 將字串s賦值到d
char *str_copy(char *d, const char *s)
{
char *t = d;
while (*d++ = *s++)
;
return (t);
}
int main(void)
{
char str[128] = "ABCD";
char *ptr = "EFGH";
printf("字串str:"); scanf("%s", str);
str_copy(ptr, str);
puts("str複製到了ptr。");
printf("str = %s\n", str);
printf("ptr = %s\n", ptr);
return(0);
}
示例程式碼11-9
// 返回字串s的長度
size_t strlen(const char *s)
{
size_t len = 0;
while (*s++)
len++;
return (len);
}
示例程式碼11-10
// 將字串s2新增到s1之後
char *strcat(char *s1, const char *s2)
{
char *tmp = s1;
while (*s1) s1++; // 前進到s1的末尾處
while (*s1++ = *s2++); // 迴圈複製直至遇到s2中的‘\0’
return (tmp);
}
// 將字串s2的前n個字元複製到s1
char *strcat(char *s1, const char *s2, size_t n)
{
char *tmp = s1;
while (*s1) s1++; // 前進到s1的末尾處
while (n--)
if (!(*s1++ = *s2++)) break; // 遇到 ‘\0’就結束迴圈
*s1 = '\0'; // 在s1的末尾插入‘\0’
return (tmp);
}
示例程式碼11-11
// 將字串s2新增到s1之後
char *strcat(char *s1, const char *s2)
{
char *tmp = s1;
while (*s1) s1++; // 前進到s1的末尾處
while (*s1++ = *s2++); // 迴圈複製直至遇到s2中的‘\0’
return (tmp);
}
// 將字串s2的前n個字元複製到s1
char *strcat(char *s1, const char *s2, size_t n)
{
char *tmp = s1;
while (*s1) s1++; // 前進到s1的末尾處
while (n--)
if (!(*s1++ = *s2++)) break; // 遇到 ‘\0’就結束迴圈
*s1 = '\0'; // 在s1的末尾插入‘\0’
return (tmp);
}
示例程式碼11-12
// 比較字串s1和s2
int strcmp(const char *s1, const char *s2)
{
while (*s1 == *s2) {
if (*s1 == '\0')
return (0); // 相等
s1++;
s2++;
}
return ((unsigned char)*s1 - (unsigned char)*s2);
}
// 比較字串s1和s2的前n個字元
int strncmp(const char *s1, const char *s2, size_t n)
{
while (n && *s1 && *s2) {
if (*s1 != *s2) // 不相等
return ((unsigned char)*s1 - (unsigned char)*s2);
s1++;
s2++;
n--;
}
if (!n) return (0); // 相等
if (*s1) return (1); // s1 > s2
return (-1); // s1 < s2
}
示例程式碼11-13
// stoi函式的執行情況
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char str[] = "12345";
printf("str =\"%s\"\n", str);
printf("atoi(str) = %d\n", atoi(str));
return (0);
}
練習程式碼:
練習程式碼e11-1
/*
依次顯示字串中的字元 (不使用下標運算子)
*/
#include <stdio.h>
// 顯示字串(不換行)
void put_string(const char str[])
{
while (*str)
putchar(*str++);
}
int main(void)
{
char str[100];
printf("請輸入字串:");
scanf("%s", str);
put_string(str);
putchar('\n');
return (0);
}
練習程式碼e11-2
/*
編寫如下函式,若字串str中含有字元c(若含有多個,以先出現的為準),、
則返回指向該字元的指標,否則返回NULL。
*/
#include <stdio.h>
char *str_chr(const char *str, int c)
{
char *p = NULL;
while (c == *str) {
p = str;
str++;
}
return (p);
}
int main(void)
{
char str[100];
char c;
printf("請輸入字串:"); scanf("%s", str);
getchar(); // 清除快取
printf("請輸入要查詢的字元:"); scanf("%c", &c);
printf("\n返回的指標地址是:%p。\n", str_chr(str, c));
return (0);
}
練習程式碼e11-3
/*
編寫如下函式,不使用下標運算子,返回字串str中字元c的個數
(若不存在則為0)。
*/
#include <stdio.h>
int str_chnum(const char *str, char c)
{
int n = 0;
while (*str) {
if (c == *str++) n++;
}
return (n);
}
int main(void)
{
char str[100];
char c;
printf("請輸入字串:"); scanf("%s", str);
getchar(); // 清除快取
printf("請輸入要查詢的字元:"); scanf("%c", &c);
printf("\n字串\"%s\"中含有%d個字元\'%c\'。\n", str, str_chnum(str, c), c);
return (0);
}
練習程式碼e11-4
/*
不使用下標運算子,寫出與程式碼清單9-13中的str_toupper函式
和str_tolower函式功能相同的函式。
*/
#include <ctype.h>
#include <stdio.h>
// 將字串中的英文字元轉換為大寫字母
void str_toupper(char *str)
{
while (*str)
*str = toupper(*str++);
}
// 將字串中的英文字元轉換為小寫字母
void str_tolower(char *str)
{
while (*str)
*str = tolower(*str++);
}
int main(void)
{
char str[100];
printf("請輸入字串:");
scanf("%s", str);
str_toupper(str);
printf("大寫字母:%s\n", str);
str_tolower(str);
printf("小寫字母:%s\n", str);
return (0);
}
練習程式碼e11-5
/*
不使用下標運算子,編寫如下函式,刪除字串str中的所有數字字元
(例如將傳入的“AB1C9”變為“ABC”)
*/
#include <stdio.h>
// 返回字串長度
int length(const *str)
{
int len = 0;
while (*str++) len++;
return (len);
}
// 去除字串中的數字
void del_digit(char *s)
{
char *p = s;
while (*p)
if ((*p >= '0') && (*p <= '9'))
p++;
else
*s++ = *p++;
*s = '\0';
}
int main()
{
char s[100];
printf("請輸入字串:"); scanf("%s", s);
printf("輸入的字串是:%s。\n", s);
del_digit(s);
printf("去數的字串是:%s。\n", s);
return (0);
}
練習程式碼e11-6
/*
編寫如下函式,實現與庫函式atoi、atol、atof相同的功能。
*/
int len(const char *nptr)
{
int len = 0;
while (*nptr++) len++;
return (len);
}
double power_10(long n)
{
double p = 1;
if (n > 0)
while (--n) p *= 10;
else if (n < 0)
while (n++) p /= 10;
else
p = 1;
return p;
}
// 字串轉換為整形
int strtoi(const char *nptr)
{
int n = len(nptr);
int num = 0;
while (*nptr) {
num += (*nptr - '0') * power_10(n--);
nptr++;
}
return (num);
}
// 字串轉換為長整形
long strtol(const char *nptr)
{
long n = len(nptr);
long num = 0;
while (*nptr) {
num += (*nptr - '0') * power_10(n--);
nptr++;
}
return (num);
}
// 字串轉換為浮點形
double strtof(char *nptr)
{
char *p1 = nptr;
char *p2;
char *p3;
int n1 = 0;
int n2 = 0;
int n3;
double num = 0.0;
while (*p1 != '.') {
n1++;
p1++;
}
p2 = ++p1;
p3 = p2;
while (*p3++) n2--;
while (*nptr != '.') {
num += (*nptr - '0') * power_10(n1--);
nptr++;
}
n3 = n2;
while (*p2) {
num += (*p2 - '0') * power_10(n3 - ++n2);
p2++;
}
return (num);
}
int main(void)
{
char s[100];
printf("請輸入一個整數:"); scanf("%s", s);
printf("\n轉換成整形:%d\n", strtoi(s));
printf("\n請輸入一個長整數:"); scanf("%s", s);
printf("\n轉換成長整形:%ld\n", strtol(s));
printf("\n請輸入一個浮點數:"); scanf("%s", s);
printf("\n轉換成浮點形:%lf\n", strtof(s));
return (0);
}