第十一章 字符串和字符串函数

程序清单11.1,strings1.c:

// strings1.c
#include 
#define MSG "I am a symbolic string constant." 
#define MAXLENGTH 81

int main(void)
{
    char words[MAXLENGTH] = "I am a string in an array.";
    const char * pt1 = "Something is pointing at me.";
    
    puts("Here are some strings:");
    puts(MSG);
    puts(words);
    puts(pt1);
    words[8] = 'p';
    puts(words);
    
    return 0;
}

输出结果:

第十一章 字符串和字符串函数_第1张图片

  • 程序清单11.2,strptr.c:

/* strptr.c -- 把字符串看作指针 */ 
#include 

int main(void)
{
    printf("%s, %p, %c\n", "We", "are", *"space farers");
    
    return 0;
}

输出结果:

  • 程序清单11.3,addresses.c:

#include 
#define MSG "I'm special"

int main(void)
{
    char ar[] = MSG;
    const char * pt = MSG;
    
    printf("address of \"I'm special\": %p \n", "I'm special");
    printf("address of ar: %p\n", ar);
    printf("address of pt: %p\n", pt);
    printf("address of MSG: %p\n", MSG);
    printf("address of \"I'm special\": %p \n", "I'm special");
    
    return 0;
}

输出结果:

第十一章 字符串和字符串函数_第2张图片

  • 程序清单11.4,arrchar.c:

#include 
#define SLEN 40
#define LIM 5

int main(void)
{
    const char * mytalents[LIM] = { // 指针的数组 
        "Adding numbers swiftly",
        "Multyplying accurately", "Stashing data",
        "Following instructions to the letter",
        "Understanding the C language"
    };
    char yourtalents[LIM][SLEN] = {
        "walking in a straight line",
        "Sleeping", "Watching television",
        "Mailing letters", "Reading email"
    };
    int i;
    
    puts("Let's compare talents.");
    printf("%-36s %-25s\n", "My Talents", "Your Talents");
    for (i = 0; i < LIM; i++)
        printf("%-36s %-25s\n", mytalents[i], yourtalents[i]);
    printf("\nsizeof mytalents: %zd, sizeof yourtalents: %zd\n",
                    sizeof(mytalents), sizeof(yourtalents));
                        
    return 0;
} 

输出结果:

第十一章 字符串和字符串函数_第3张图片

  • 程序清单11.5,p_and_s.c:

/* p_and_s.c -- 指针和字符串 */ 
#include 

int main(void)
{
    const char * mesg = "Dont't be a fool!";
    const char * copy;
    
    copy = mesg;
    printf("%s\n", copy);
    printf("mesg = %s; &mesg = %p; value = %p\n", mesg, &mesg, mesg);
    printf("copy = %s; © = %p; value = %p\n", copy, ©, copy);
    
    return 0;
}

输出结果:

第十一章 字符串和字符串函数_第4张图片

  • 程序清单11.6,getsputs.c:

/* getsputs.c -- 使用 gets() 和 puts() */ 
#include 
#define STLEN 81

int main(void)
{
    char words[STLEN];
    
    puts("Enter a string, please.");
    gets(words); // 典型用法 
    printf("Your string twice:\n");
    printf("%s\n", words);
    puts(words);
    puts("Done.");
    
    return 0;
}

输出结果:

第十一章 字符串和字符串函数_第5张图片

  • 程序清单11.7,fgets1.c:

/* fgets1.c -- 使用 fgets() 和 fputs() */ 
#include 
#define STLEN 14

int main(void)
{
    char words[STLEN];
    
    puts("Enter a string, please.");
    fgets(words, STLEN, stdin);
    printf("Your string twice (puts(), then fputs()):\n");
    puts(words);
    fputs(words, stdout);
    puts("Enter another string, please.");
    fgets(words, STLEN, stdin);
    printf("Your string twice (puts(), then fputs()):\n");
    puts(words);
    fputs(words, stdout);
    puts("Done.");
    
    return 0;
}

输出结果:

第十一章 字符串和字符串函数_第6张图片

  • 程序清单11.8,fgets2.c:

/* fgets2.c -- 使用 fgets() 和 fputs() */ 
#include 
#define STLEN 10

int main(void)
{
    char words[STLEN];
    
    puts("Enter string (empty line to quit):");
    while (fgets(words, STLEN, stdin) != NULL && words[0] != '\n')
        fputs(words, stdout);
    puts("Done.");
    
    return 0;
}

输出结果:

第十一章 字符串和字符串函数_第7张图片

  • 程序清单11.9,fgets3.c:

输出结果:

/* fgets3.c -- 使用 fgets() */ 
#include 
#define STLEN 10

int main(void)
{
    char words[STLEN];
    int i;
    
    puts("Enter strings (empty line to quit):");
    while (fgets(words, STLEN, stdin) != NULL && words[0] != '\n')
    {
        i = 0;
        while (words[i] != '\n' &&words[i] != '\0')
            i++;
        if (words[i] == '\n')
            words[i] = '\0';
        else // 如果 word[i] == '\0',则执行这部分代码 
            while (getchar() != '\n')
                continue;
        puts(words);
    }
    puts("Done");
    
    return 0;
}
第十一章 字符串和字符串函数_第8张图片

  • 程序清单11.10,s_gets.c:

char * s_gets(char * st, int n) // fgets() 函数可能读入换行符 
{ 
    char * ret_val;
    int i;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val) // 即,ret_val != NULL
    {
        while (st[i] != '\n' && st[i] != '\0')
            i++;
        if (st[i] == '\n')
            st[i] = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

  • 程序清单11.11,scan_str.c:

/* scan_str.c -- 使用 scanf() */ 
#include 

int main(void)
{
    char name1[11], name2[11];
    int count;
    
    printf("Please enter 2 names.\n");
    count = scanf("%5s %10s", name1, name2);
    printf("I read the %d names %s and %s.\n", count, name1, name2);
    
    return 0;
} 

输出结果:

第十一章 字符串和字符串函数_第9张图片

  • 程序清单11.12,put_out.c:

/* put_out.c -- 使用 puts() */ 
#include 
#define DEF "I am a #defined string."

int main(void)
{
    char str1[80] = "An array was initialized to me.";
    const char * str2 = "A pointer was initialized to me.";
    
    puts("I'm an argument to puts().");
    puts(DEF);
    puts(str1);
    puts(str2);
    puts(&str1[5]);
    puts(str2 + 4);
    
    return 0;
}

输出结果:

第十一章 字符串和字符串函数_第10张图片

  • 程序清单11.13,put1.c:

/* nono.c -- 千万不要模仿! */ 
#include 

int main(void)
{
    char side_a[] = "Side A";
    char dont[] = { 'W', 'O', 'W', '!' };
    char side_b[] = "Side B";
    
    puts(dont); /* dont 不是一个字符串 */ 
    
    return 0;
}

输出结果:

  • 程序清单11.14,put1.c:

/* put1.c -- 打印字符串,不添加 \n */
#include 

void put1(const char * string) /* 不会改变字符串 */
{
    while (*string != '\0')
        putchar(*string++);
} 

  • 程序清单11.15,put2.c:

/* put2.c -- 打印一个字符串,并统计打印的字符数 */ 
#include 

int put2(const char * string);

int main(void)
{
    int num;
    
    num = put2("pizza");
    printf("%d\n", num);
    
    return 0;
}

int put2(const char * string)
{
    int count = 0;
    
    while (*string)
    {
        putchar(*string++);
        count++;
    }
    putchar('\n');
    
    return count;
}

输出结果:

  • 程序清单11.16,put_put.c:

/* Put_put.c -- 用户自定义输出函数 */ 
#include 

void put1(const char *);
int put2(const char *);

int main(void)
{
    put1("If I'd as much money");
    put1(" as I could spend,\n");
    printf("I count %d characters.\n",
        put2("I never would cry old chairs to mend."));
    
    return 0;
}

void put1(const char * string)
{
    while (*string) /* 与 *string != '\0' 相同 */ 
        putchar(*string++);
}

int put2(const char * string)
{
    int count = 0;
    
    while (*string)
    {
        putchar(*string++);
        count++;
    }
    putchar('\n');
    
    return(count);
}

输出结果:

  • 程序清单11.17,test_fit.c:

/* test_fit.c -- 使用缩短字符串长度的函数 */ 
#include 
#include  /* 内含字符串函数原型 */
 
void fit(char *, unsigned int);

int main(void)
{
    char mesg[] = "Things should be as simple as possible,"
                        " but not simpler.";
    
    puts(mesg);
    fit(mesg, 38);
    puts(mesg);
    puts("Let's look at some more of the string.");
    puts(mesg + 39);
    
    return 0;
}

void fit(char * string, unsigned int size)
{
    if (strlen(string) > size)
        string[size] = '\0';
} 

输出结果:

第十一章 字符串和字符串函数_第11张图片

  • 程序清单11.18,str_cat.c:

/* str_cat.c -- 拼接两个字符串 */ 
#include 
#include  /* 提供 strcat() 函数原型 */ 
#define SIZE 80

char * s_gets(char * st, int n);

int main(void)
{
    char flower[SIZE];
    char addon[] = "s smell like old shoes.";
    
    puts("What is your favorite flower?");
    if (s_gets(flower, SIZE))
    {
        strcat(flower, addon);
        puts(flower);
        puts(addon);
    }
    else
        puts("End of file encountered!");
    puts("bye");
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    int i = 0;
    
    ret_val = fgets(st, n, stdin);
    if(ret_val)
    {
        while (st[i] != '\n' && st[i] != '\0')
            i++;
        if (st[i] == '\n')
            st[i] = '\0';
        else
            while (getchar() != '\n') 
                continue;
    }
    
    return ret_val;
}

输出结果:

第十一章 字符串和字符串函数_第12张图片

  • 程序清单11.19,join_chk.c:

/* join_chk.c -- 拼接两个字符串,检查第 1 个 数组的大小 */ 
#include 
#include 
#define SIZE 30
#define BUGSIZE 13

char * s_gets(char * st, int n);

int main(void)
{
    char flower[SIZE];
    char addon[] = "s smell like old shoes.";
    char bug[BUGSIZE];
    int available;
    
    puts("What is your favorite flower?");
    s_gets(flower, SIZE);
    if ((strlen(addon) + strlen(flower) + 1) <= SIZE)
        strcat(flower, addon);
    puts(flower);
    puts("What is your favorite bug?");
    s_gets(bug, BUGSIZE);
    available = BUGSIZE - strlen(bug) - 1;
    strncat(bug, addon, available);
    puts(bug);
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    int i = 0;
    
    ret_val = fgets(st, n, stdin);
    if(ret_val)
    {
        while (st[i] != '\n' && st[i] != '\0')
            i++;
        if (st[i] == '\n')
            st[i] = '\0';
        else
            while (getchar() != '\n') 
                continue;
    }
    
    return ret_val;
}

输出结果:

第十一章 字符串和字符串函数_第13张图片

  • 程序清单11.20,nogo.c:

/* nogo.c -- 该程序能否正常运行? */ 
#include 
#define ANSWER "Grant"
#define SIZE 40

char * s_gets(char * st, int n);

int main(void)
{
    char try[SIZE];
    
    puts("Who is buried in Grant's tomb?");
    s_gets(try, SIZE);
    while (try != ANSWER)
    {
        puts("No, that's wrong. Try again.");
        s_gets(try, SIZE);
    }
    puts("That's right!");
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    int i = 0;
    
    ret_val = fgets(st, n, stdin);
    if(ret_val)
    {
        while (st[i] != '\n' && st[i] != '\0')
            i++;
        if (st[i] == '\n')
            st[i] = '\0';
        else
            while (getchar() != '\n') 
                continue;
    }
    
    return ret_val;
}

输出结果:

  • 程序清单11.21,compare.c:

/* compare.c -- 该程序可以正常运行 */ 
#include 
#include  // 提供 strcmp() 函数原型 
#define ANSWER "Grant"
#define SIZE 40

char * s_gets(char * st, int n);

int main(void)
{
    char try[SIZE];
    
    puts("Who is buried in Grant's tomb?");
    s_gets(try, SIZE);
    while (strcmp(try, ANSWER) != 0)
    {
        puts("No, that's wrong. Try again.");
        s_gets(try, SIZE);
    }
    puts("That's right!");
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    int i = 0;
    
    ret_val = fgets(st, n, stdin);
    if(ret_val)
    {
        while (st[i] != '\n' && st[i] != '\0')
            i++;
        if (st[i] == '\n')
            st[i] = '\0';
        else
            while (getchar() != '\n') 
                continue;
    }
    
    return ret_val;
}

输出结果:

  • 程序清单11.22,compback.c:

/* compback.c -- strcmp() 的返回值 */ 
#include 
#include 

int main(void)
{
    printf("strcmp(\"A\", \"A\") is %d\n", strcmp("A", "A"));
    printf("strcmp(\"A\", \"B\") is %d\n", strcmp("A", "B"));
    printf("strcmp(\"B\", \"A\") is %d\n", strcmp("B", "A"));
    printf("strcmp(\"C\", \"A\") is %d\n", strcmp("C", "A"));
    printf("strcmp(\"Z\", \"a\") is %d\n", strcmp("Z", "a"));
    printf("strcmp(\"apples\", \"apple\") is %d\n", strcmp("apples", "apple"));
    
    return 0;
}

输出结果:

第十一章 字符串和字符串函数_第14张图片

  • 程序清单11.23,quit_chk.c:

/* quit_chk.c -- 某程序的开始部分 */ 
#include 
#include 
#define SIZE 80
#define LIM 10
#define STOP "quit"

char * s_gets(char * st, int n);

int main(void)
{
    char input[LIM][SIZE];
    int ct = 0;
    
    printf("Enter up to %d lines (type quit to quit):\n", LIM);
    while (ct < LIM && s_gets(input[ct], SIZE) != NULL &&
                strcmp(input[ct], STOP) != 0)
    {
        ct++;
    }
    printf("%d strings entered\n", ct);
    for (int i = 0; i < ct; i++)
        puts(input[i]);
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    int i = 0;
    
    ret_val = fgets(st, n, stdin);
    if(ret_val)
    {
        while (st[i] != '\n' && st[i] != '\0')
            i++;
        if (st[i] == '\n')
            st[i] = '\0';
        else
            while (getchar() != '\n') 
                continue;
    }
    
    return ret_val;
}

输出结果:

第十一章 字符串和字符串函数_第15张图片

  • 程序清单11.24,starsrch.c:

/* starsrch.c -- 使用 strncmp() */ 
#include 
#include 
#define LISTSIZE 6

int main(void)
{
    const char * list[LISTSIZE] = 
    {
        "astronomy", "astounding",
        "astrophysics", "ostracize",
        "asterism", "astrophobia"
    };
    int count = 0;
    int i;
    
    for (i = 0; i < LISTSIZE; i++)
        if (strncmp(list[i], "astro", 5) == 0)
        {
            printf("Found: %s\n", list[i]);
            count++;
        }
    printf("The list contained %d words beginning"
            " with astro.\n", count);
            
    return 0;
}

输出结果:

第十一章 字符串和字符串函数_第16张图片

  • 程序清单11.25,copy1.c:

/* copy1.c -- 演示 strcpy() */ 
#include 
#include  // 提供 strcpy() 函数原型 
#define SIZE 40
#define LIM 5

char * s_gets(char * st, int n);

int main(void)
{
    char qwords[LIM][SIZE];
    char temp[SIZE];
    int i = 0;
    
    printf("Enter %d words beginning with q:\n", LIM);
    while (i < LIM && s_gets(temp, SIZE))
    {
        if (temp[0] != 'q')
            printf("%s doesn't begin with q!\n", temp);
        else
        {
            strcpy(qwords[i], temp);
            i++;
        }
        if (i < LIM)
            printf("Please keep going: ");
    }
    puts("Here are the words accepted:");
    for (i = 0; i < LIM; i++)
        puts(qwords[i]);
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    int i = 0;
    
    ret_val = fgets(st, n, stdin);
    if(ret_val)
    {
        while (st[i] != '\n' && st[i] != '\0')
            i++;
        if (st[i] == '\n')
            st[i] = '\0';
        else
            while (getchar() != '\n') 
                continue;
    }
    
    return ret_val;
}

输出结果:

第十一章 字符串和字符串函数_第17张图片

  • 程序清单11.26,copy2.c:

/* copy2.c -- 使用 strcpy() */ 
#include 
#include 
#define WORDS "beast"
#define SIZE 40

int main(void)
{
    const char * orig = WORDS;
    char copy[SIZE] = "Be the best that you can be.";
    char * ps;
    
    puts(orig);
    puts(copy);
    ps = strcpy(copy + 7, orig); // 将 orig 所指向的字符串拷贝到 copy + 7所在地址,包括'\0' 
    puts(copy);
    puts(ps);
    
    return 0;
} 

输出结果:

第十一章 字符串和字符串函数_第18张图片

  • 程序清单11.27,copy3.c:

/* copy3.c -- 使用 strncpy() */ 
#include 
#include 
#define SIZE 40
#define TARGSIZE 7
#define LIM 5

char * s_gets(char * st, int n);

int main(void)
{
    char qwords[LIM][SIZE];
    char temp[SIZE];
    int i = 0;
    
    printf("Enter %d words beginning with q:\n", LIM);
    while (i < LIM && s_gets(temp, SIZE))
    {
        if (temp[0] != 'q')
            printf("%s doesn't begin with q!\n", temp);
        else
        {
            strncpy(qwords[i], temp, TARGSIZE - 1);
            qwords[i][TARGSIZE - 1] = '\0';
            i++;
        }
    }
    puts("Here are the words accepted:");
    for (i = 0; i < LIM; i++)
        puts(qwords[i]);
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    int i = 0;
    
    ret_val = fgets(st, n, stdin);
    if(ret_val)
    {
        while (st[i] != '\n' && st[i] != '\0')
            i++;
        if (st[i] == '\n')
            st[i] = '\0';
        else
            while (getchar() != '\n') 
                continue;
    }
    
    return ret_val;
}

输出结果:

第十一章 字符串和字符串函数_第19张图片

  • 程序清单11.28,format.c:

/* format.c -- 格式化字符串 */ 
#include 
#define MAX 20

char * s_gets(char * st, int n);

int main(void)
{
    char first[MAX];
    char last[MAX];
    char formal[2 * MAX + 10];
    double prize;
    
    puts("Enter your first name:");
    s_gets(first, MAX);
    puts("Enter your last name:");
    s_gets(last, MAX);
    puts("Enter your prize money:");
    scanf("%lf", &prize);
    sprintf(formal, "%s, %-19s: $%6.2f\n", last, first, prize);
    puts(formal);
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    int i = 0;
    
    ret_val = fgets(st, n, stdin);
    if(ret_val)
    {
        while (st[i] != '\n' && st[i] != '\0')
            i++;
        if (st[i] == '\n')
            st[i] = '\0';
        else
            while (getchar() != '\n') 
                continue;
    }
    
    return ret_val;
}

输出结果:

第十一章 字符串和字符串函数_第20张图片

  • 程序清单11.29,sort_str.c:

/* sort_str.c -- 读入字符串,并排序字符串 */ 
#include 
#include 
#define SIZE 81            /* 限制字符串长度,包括 \0 */ 
#define LIM 20             /* 可读入的最多行数 */ 

void stsrt(char * strings[], int num); // strings 是指针的指针 
char * s_gets(char * st, int n);

int main(void)
{
    char input[LIM][SIZE]; /* 存储输入的数组 */ 
    char * ptstr[LIM];     /* 内含指针变量的数组 */ 
    int ct = 0;            /* 输入计数 */ 
    int k;                 /* 输出计数 */ 
    
    printf("Input up to %d lines, and I will sort them.\n", LIM);
    printf("To stop, press the Enter key at line's start.\n");
    while (ct < LIM && s_gets(input[ct], SIZE) != NULL
            && input[ct][0] != '\0')
    {
        ptstr[ct] = input[ct]; /* 设置指针指向字符串 */ 
        ct++;
    }
    stsrt(ptstr, ct);          /* 字符串排序函数 */ 
    puts("\nHere's the sorted list:\n");
    for (k = 0; k < ct; k++)
        puts(ptstr[k]);        /* 排序后的指针 */ 
    
    return 0;
}

/* 字符串-指针-排序函数 */ 
void stsrt(char * strings[], int num)
{
    char * temp;
    int top, seek;
    
    for (top = 0; top < num - 1; top++)
        for (seek = top + 1; seek < num; seek++)
            if (strcmp(strings[top], strings[seek]) > 0)
            {
                temp = strings[top];
                strings[top] = strings[seek];
                strings[seek] = temp;
            }
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    int i = 0;
    
    ret_val = fgets(st, n, stdin);
    if(ret_val)
    {
        while (st[i] != '\n' && st[i] != '\0')
            i++;
        if (st[i] == '\n')
            st[i] = '\0';
        else
            while (getchar() != '\n') 
                continue;
    }
    
    return ret_val;
}

输出结果:

第十一章 字符串和字符串函数_第21张图片

  • 程序清单11.30,mod_str.c:

/* mod_str.c -- 修改字符串 */ 
#include 
#include 
#include 
#define LIMIT 81

void ToUpper(char *);
int PunctCount(const char *);

int main(void)
{
    char line[LIMIT];
    char * find;
    
    puts("Please enter a line:");
    fgets(line, LIMIT, stdin);
    find = strchr(line, '\n');  // 查找换行符 
    if (find)                   // 如果地址不是 NULL 
        *find = '\0';           // 用空字符替换 
    ToUpper(line);
    puts(line);
    printf("That line has %d punctuation characters.\n", PunctCount(line));
    
    return 0;
}

void ToUpper(char * str)
{
    while (*str)
    {
        *str = toupper(*str);
        str++;
    }
}

int PunctCount(const char * str)
{
    int ct = 0;
    
    while (*str)
    {
        if (ispunct(*str))
            ct++;
        str++;
    }
    
    return ct;
}

输出结果:

第十一章 字符串和字符串函数_第22张图片

  • 程序清单11.31,repeat.c:

/* repeat.c -- 带参数的 main() */ 
#include 

int main(int argc, char * argv[])
{
    int count;
    
    printf("The command line has %d arguments:\n", argc - 1);
    for (count = 0; count < argc; count++)
        printf("%d: %s\n", count, argv[count]);
    printf("\n");
    
    return 0;
}

输出结果:

  • 程序清单11.32,hello.c:

/* hello.c -- 把命令行参数转换为数字 */ 
#include 
#include 

int main(int argc, char * argv [])
{
    int i, times;
    
    if (argc < 2 || (times = atoi(argv[1])) < 1)
        printf("Usage: %s positive-number\n", argv[0]);
    else
        for (i = 0; i < times; i++)
            puts("Hello, good looking!");
    
    return 0;
} 

输出结果:

  • 程序清单11.33,strcnvt.c:

/* strcnvt.c -- 使用 strtol() */ 
#include 
#include 
#define LIM 30

char * s_gets(char * st, int n);

int main(void)
{
    char number[LIM];
    char * end;
    long value;
    
    puts("Enter a number (empty to quit):");
    while (s_gets(number, LIM) && number[0] != '\0')
    {
        value = strtol(number, &end, 10);
        printf("base 10 input, base 10 output: %ld, stopped at %s (%d)\n",
                    value, end, *end);
        value = strtol(number, &end, 16);
        printf("base 16 input, base 10 output: %ld, stopped at %s (%d)\n",
                    value, end, *end);
        puts("Next number:");
    }
    puts("Bye!\n");
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    int i = 0;
    
    ret_val = fgets(st, n, stdin);
    if(ret_val)
    {
        while (st[i] != '\n' && st[i] != '\0')
            i++;
        if (st[i] == '\n')
            st[i] = '\0';
        else
            while (getchar() != '\n') 
                continue;
    }
    
    return ret_val;
}

输出结果:

第十一章 字符串和字符串函数_第23张图片

  • 编程练习

第十一章 字符串和字符串函数_第24张图片
第十一章 字符串和字符串函数_第25张图片

题目1,方法:获取n个字符并存储。示例代码11_1.c:

#include 
#define LEN 5

void getnchar(char *, int);

int main(void)
{
    char str[LEN];
    printf("Please input %d of characters: ", LEN - 1);
    getnchar(str, LEN);
    puts("The characters you input is:");
    puts(str);
    
    return 0;
}

void getnchar(char * ar, int n)
{
    int i = 0;
    
    while (i < n - 1)
        *(ar + i++) = getchar();
    *(ar + i) = '\0';
}

输出结果:

题目2,方法:获取n个字符(包括空格等)。示例代码11_2.c:

#include 
#include 
#define LEN 5

void getnchar(char *, int);

int main(void)
{
    char str[LEN];
    printf("Please input %d of characters: ", LEN - 1);
    getnchar(str, LEN);
    puts("The characters you input is:");
    puts(str);
    
    return 0;
}

void getnchar(char * ar, int n)
{
    int i = 0;
    
    while (i < n - 1)
        if (isspace(*(ar + i++) = getchar()))
            break;    
    *(ar + i) = '\0';
}

输出结果:

题目3、4,方法:保存字符串中第一个单词。示例代码11_3.c:

#include 
#include 
#define LEN 10

char * getword(char *, int);

int main(void)
{
    char str[LEN];
    
    printf("Please enter a words: ");
    while (getword(str, LEN - 1) != NULL)
    {
        printf("The words you input is: ");
        puts(str);
        printf("You can input again: ");
    }
    
    return 0;
}

char * getword(char * st, int num)
{
    int n = 0;
    char ch;
    
    //处理首字符 
    while ((ch = getchar()) != '&' && isspace(ch))
        continue;
    if (ch == '&')
        return NULL;
    else
    {
        *st++ = ch;
        n++;
    }
    //首字符通过验证后处理其他字符 
    while ((ch = getchar()) != '&' && !isspace(ch) && n < num)
    {
        *st++ = ch;
        n++;
    }
    *st = '\0';
    if (ch != '\n') 
        while (getchar() != '\n')
            continue;
        
    return st;
}

输出结果:

题目5,方法:查找指定字符首次出现的地址。示例代码11_5.c:

#include 
#include 
#define LEN 40

char * s_gets(char *, int);
char * search_ch(char *, char);

int main(void)
{
    char str[LEN];
    char ch;
    char * strs;
    
    printf("Please input a string: ");
    while (s_gets(str, LEN) != NULL && *str != '\n')
    {
        printf("Please input a character: ");
        ch = getchar();
        if (ch != '\n')
            while (getchar() != '\n')
                    continue;
        printf("The string you enter is: ");
        puts(str);
        printf("The character you enter is: ");
        putchar(ch);
        putchar('\n');
        strs = search_ch(str, ch);
        if (strs)
        {
            printf("The character first appear at ");
            puts(strs);
        }
        else
            printf("%c is not exist in the string\n", ch);
        printf("You can input a string again: ");
    }
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n'); //不需要处理换行符 
//        if (find)
//            *find = '\0';
//        else
        if (!find)
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

char * search_ch(char * st, char cha)
{
    while (*st != '\0')
    {
        if (*st == cha)
            return st;
        st++;
    }
    return NULL;
}

输出结果:

第十一章 字符串和字符串函数_第26张图片

题目6,方法:判断指定字符是否在字符串中。示例代码11_6.c:

#include 
#include 
#include 
#define LEN 30

char * s_gets(char *, int);
bool search_ch(const char *, char);

int main(void)
{
    char str[LEN];
    char ch;
    bool judge;
    
    printf("Please input a string: ");
    while (s_gets(str, LEN) != NULL && *str != '\0')
    {
        printf("Please input a character: ");
        ch = getchar();
        if (ch != '\n')
            while (getchar() != '\n')
                    continue;
        printf("The string you enter is: ");
        puts(str);
        printf("The character you enter is: ");
        putchar(ch);
        putchar('\n');
        judge = search_ch(str, ch);
        if (judge)
        {
            
            printf("%c is exist in the string\n", ch);
        }
        else
            printf("%c is not exist in the string\n", ch);
        printf("You can input a string again: ");
    }
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

bool search_ch(const char * st, char cha)
{
    while (*st != '\0')
    {
        if (*st == cha)
            return true;
        st++;
    }
    return false;
}

输出结果:

第十一章 字符串和字符串函数_第27张图片

题目7,方法:截取字符串中的前n个字符。示例代码11_7.c:

#include 
#include 
#define LEN 30

char * s_gets(char *, int);
char * mystrncpy(char *, char *, int);
void clear(void);

int main(void)
{
    char s1[LEN];
    char s2[LEN];
    int num;
    int len;
    
    printf("Please input a string: ");
    while (s_gets(s1, LEN) != NULL && *s1 != '\0')
    {
        len = strlen(s1);
        printf("Please input character id you want to copy: ");
        while (scanf("%d", &num) != 1 || num < 1 || num > len)
        {
            printf("Wrong input, try again: ");
            clear();
        }
        clear();
        printf("The array of s2 is:%s\n", mystrncpy(s2, s1, num));
        printf("You can input a string again: ");
    }
    
    return 0;
    
} 

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

char * mystrncpy(char * target, char * source, int n)
{
    int i = 0;
    
    while (*source != '\0' && i < n)
    {
        *(target + i) = *(source + i);
        i++;
    }
    *(target + i) = '\0';
    
    return target;
} 

void clear(void)
{
    while (getchar() != '\n')
        continue;
}

输出结果:

第十一章 字符串和字符串函数_第28张图片

题目8,方法:检测一个字符中是否包含另一个字符。示例代码11_8.c:

#include 
#include 
#define LEN 100

char * s_gets(char *, int);
char * search_str(char *, char *);

int main(void)
{
    char str[LEN];
    char str1[LEN];
    char * strs, * strs1;
    char * ptr;
    
    printf("Please input the first string(no more than %d of characters): ",LEN - 1);
    while ((strs = s_gets(str, LEN)) != NULL && *strs != '\0')
    {
        printf("\nPlease input the second string(no more than the first string): ");
        while ((strs1 = s_gets(str1, LEN)) == NULL || *strs1 == '\0')
        {
            printf("Illegal input, try argin(at least one character): ");
        }
        ptr = search_str(str, str1);
        if (ptr)
            printf("\nThe string \"%s\" first appear at: \"%s\"\n", str1, ptr);
        else
            printf("\nThe string \"%s\" not exist in \"%s\".\n",str1, str);
        printf("\nYou can input a string again(no more than %d of characters): ", LEN - 1);
    }
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

char * search_str(char * st, char * st1)
{
    int i, j;
    int len_st, len_st1; //字符串长度 
    int num; //出现次数
    int num_o;//完整出现次数 
    char * addr[LEN]; //每次出现地址
    char * addr_o[LEN];//完整出现地址
    char ch;//字符变量 
    
    len_st = strlen(st);
    len_st1 = strlen(st1);
    if (len_st < len_st1)
        return NULL;
    for (i = 0, j = 0, num = 0; i < len_st; i++)
    {    
        if (st1[j] == st[i])
            j++;
        else if (*st1 == st[i]) // 如 abaab 中 ab 
            j = 1;
        else
            j = 0;
        if (j == len_st1)
        {
            *(addr + num++) = (st + i) - (len_st1 - 1); //字符串起始位置 
            j = 0; //初始化j的值 
            i = i - len_st1 + 1; //一旦查找成功一次则只移动一个字符 
        }
    }
    for (i = 0, num_o = 0; i < num; i++)
        if (((ch = *(*(addr + i) + len_st1)) ==' ' || ch == '\0') && 
            ((ch = *(*(addr + i) - 1)) ==' ' || *(addr + i) == st))
        {
            *(addr_o + num_o++) = *(addr + i);
        }
    if (num == 0)
        return NULL;
    printf("\n\"%s\" appear in \n\"%s\" \ntotally %d times\n", st1, st, num); 
    for (i = 0; i < num; i++)
        printf("\n%dth time:\n%s\n", i + 1, *(addr + i));
    printf("\n\"%s\" appear in \n\"%s\" \nintegrel totally %d times\n", st1, st, num_o);
    for (i = 0; i < num_o; i++)
        printf("\n%dth time:\n%s\n", i + 1, *(addr_o + i));
        
    return * addr;
}

输出结果:

第十一章 字符串和字符串函数_第29张图片

题目9,方法:将数组反序保存。示例代码11_9.c:

#include 
#include 
#define LEN 10

char * adstr(char *); // 倒序字符串 
char * s_gets(char *, int);

int main(void)
{
    char st[LEN];
    char * strs;
    
    printf("Please input a string(No more than %d of characters): ", LEN - 1);
    while ((strs = s_gets(st, LEN)) != NULL && *strs != '\0')
    {
        adstr(st);
        printf("After advert, the array of st is: ");
        puts(st);
        printf("You can input another string: ");
    }
    
    return 0;
} 

char * adstr(char * str)
{
    int len;
    int i;
    char ptr;
    //int i, j;
    //char * sts[LEN];
    
    len = strlen(str);
    //方法一 
    for (i = 0; i < len / 2; i++)
    {
        ptr = *(str + i);
        *(str + i) = *(str + len - 1 - i);
        *(str + len - 1 - i) = ptr;
    }
    //方法二
//    for (i = len - 1, j = 0; i >= 0 ; i--)
//    {
//        *(sts + j++) = str + i;
//    }
//    for (i = 0; i < j; i++)
//        printf("%c", **(sts + i));
//    putchar('\n');
//        
//    return *sts;
    return str;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

输出结果:

第十一章 字符串和字符串函数_第30张图片

题目10,方法:删除字符串中的空格。示例代码11_10.c:

#include 
#include 
#define LEN 10

void dspace(char *);
char * s_gets(char *, int);

int main(void)
{
    char st[LEN];
    char * strs;
    
    printf("Please input a string(No more than %d of characters): ", LEN - 1);
    while ((strs = s_gets(st, LEN)) != NULL && *strs != '\0')
    {
        dspace(st);
        printf("After delete space, the array of st is: ");
        puts(st);
        printf("You can input another string: ");
    }
    
    return 0;
} 

void dspace(char * st)
{
    char * ptr;
    
    ptr = st;
    while (*st)
    {
        if (*st != ' ')
            *ptr++ = *st++;
        else
            st++;
    }
    *ptr = '\0';
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

输出结果:

第十一章 字符串和字符串函数_第31张图片

题目11,方法:根据选项处理字符串。该项目包含2个头文件和3个源文件。

str_pro.h:

#include 
#include 
#include 
#include 
#include 

void show_menu(void);
char * s_gets(char *, int); //获取字符串 
int get_strings(int, int, char (*)[]); //将最多m个最大长度为n的字符串读入str中 
void pt_strings(int, int, char **, char (*)[]); //将指针的数组指向对应的字符串的地址 
int first_len(char *); //计算字符串中第一个单词长度 
void or_print(int, int, char(*)[]); //打印原始字符串列表 
void as_print(int, char **); //ASCII打印字符串列表
void le_print(int, char **); //长度递增打印字符串列表 
void fi_print(int, char **); //第一个单词递增打印 

str_pro.c:

#include "str_pro.h"
#include "check.h"

void show_menu(void)
{
    printf("****************************************\n");
    printf("Please choose the operation:\n");
    printf("a. Origin                      b. ASCII order\n");
    printf("c. Upgrade                     d. First length\n");
    printf("q. Quit\n\n");    
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

int get_strings(int m, int n, char (*str)[n])
{
    int i;
    char * ptr;
    
    for (i = 0; i < m; i++)
    {
        printf("Now you can input %dth of string(EOF or Enter to quit): ", i + 1); 
        if ((ptr = s_gets(*(str + i), n)) != NULL && *ptr != '\0')
        {
            system("cls");
            continue;
        }    
        else
            break;
    }
    system("cls"); 
    
    return i;
}

void pt_strings(int num, int n, char ** pt, char (*source)[n])
{
    int i;
    
    for (i = 0; i < num; i++)
    {
        *(pt + i) = *(source + i);
    }
}

int first_len(char * st)
{
    int length = 0;
    bool inword = false;
    
    while (*st != '\0')
    {
        if (!isspace(*st) && inword == false)
        {
            inword = true;
            length++;
        }
        if (!isspace(*st) && inword == true)
            length++;
        if (isspace(*st) && inword == true)
            break;
        st++;
    }
    
    return length;
}

void or_print(int num, int n, char(*str)[n])
{
    int i;
    
    for (i = 0; i < num; i++)
    {
        printf("The %dth of string: ", i + 1);
        puts(*(str + i));
    }
    wait(); 
}

void as_print(int num, char ** pt)
{
    int i, j;
    char * temp;
    
    for (i = 0; i < num - 1; i++)
        for (j = i + 1; j < num; j++)
        {
            if (strcmp(*(pt + i), *(pt + j)) > 0)
            {
                temp = *(pt + j);
                *(pt + j) = *(pt + i);
                *(pt + i) = temp;
            }
        }
    for (i = 0; i < num; i++)
    {
        printf("The %dth of string: ", i + 1);
        puts(*(pt + i));
    } 
    wait();
} 

void le_print(int num, char ** pt)
{
    int i, j;
    char *temp;
    
    for (i = 0; i < num - 1; i++)
        for (j = i + 1; j < num; j++)
        {
            if (strlen(*(pt + i)) > strlen(*(pt + j)))
            {
                temp = *(pt + j);
                *(pt + j) = *(pt + i);
                *(pt + i) = temp;
            }
        }
    for (i = 0; i < num; i++)
    {
        printf("The %dth of string: ", i + 1);
        puts(*(pt + i));
    } 
    wait();
}

void fi_print(int num, char ** pt)
{
    int i, j;
    char *temp;
    
    for (i = 0; i < num - 1; i++)
        for (j = i + 1; j < num; j++)
        {
            if (first_len(*(pt + i)) > first_len(*(pt + j)))
            {
                temp = *(pt + j);
                *(pt + j) = *(pt + i);
                *(pt + i) = temp;
            }
        }
    for (i = 0; i < num; i++)
    {
        printf("The %dth of string: ", i + 1);
        puts(*(pt + i));
    } 
    wait();
}

check.h:

#include 
#include 
#include 
#include 
#include 

void wait(void);//暂停打印提示信息 
void consumer(char *, int *);//清空缓冲区并保存清空的字符 
bool character_check(char *, int *); //检测是否有非空字符并清空第一个非空字符及之前的缓冲区 
char choose_check(int); //将输入限制在合法区间并返回输入值

check.c:

#include "check.h"
#include "str_pro.h"

void wait(void)
{
    char ch;
    
    printf("Enter to continue...");
    while ((ch = getchar()) != '\n')
        continue;    
    system("cls");
}

void consumer(char * wrong, int * n)
{
    char cha;
    
    while ((cha = getchar()) != '\n')
        *(wrong + (*n)++) = cha;
}

bool character_check(char * wrong, int * n)
{
    char ch2;
    
    while ((ch2 = getchar()) != '\n') //第一个非空字符为回车,则读走回车 
    {
        *(wrong + (*n)++) = ch2;
        if (ch2 != '\t' && ch2 != ' ') //若第一个非空字符非回车,回车不被读走 
            return true;
    }
    
    return false;
}

char choose_check(int n)
{
    char ch1;
    char notice[n];
    int num = 1;
    int * count = #
    
    show_menu();
    printf("Enter a character to choose: ");
    //防止第一个非空合法字符后出现第二个非空字符,例如assss 
    while (((ch1 = tolower(getchar())) != 'a' && ch1 != 'b' && ch1 != 'c' && ch1 != 'd' && ch1 != 'q') || character_check(notice, count) == true)
    {
        if (ch1 == ' ' || ch1 == '\n' || ch1 == '\t') // 使至少第一个非空字符被ch1获得 
            continue;
        else if (character_check(notice, count) == true) //防止出现 assss 这样的输入,即之前非法,之后合法,以及清空非空白字符缓冲区 
            consumer(notice, count); //输入a2时判断返回false,不执行此步(此时所有字符包括回车均已被读走) 
        system("cls");
        show_menu();
        *notice = ch1;
        printf("%s is illegal, try again: ", notice); 
        memset(notice, 0 ,sizeof(notice)); //初始化字符串数组 
        num = 1; //重置计数 
    }
    
    return ch1;
}

main.c:

#include "check.h"
#include "str_pro.h"
#define WRONG 200
#define ROW 10
#define COL 100

int main(void)
{
    char * ptr[ROW]; //用于指向字符串地址的指针 
    char strings[ROW][COL]; //申请分配10个长度为100个字符的空间 
    char ch; //保存功能选项
    int count; //用于存储输入多少个字符串 
    
    printf("Please input no more than %d of strings(First EOF or enter to quit):\n", ROW);
    //申请空间数不必与操作空间数一致,但应该保证申请空间数大于等于操作数,否则将会越界 
    while ((count = get_strings(ROW, COL,strings)) != 0)
    {
        pt_strings(count, COL, ptr, strings);
        while ((ch = choose_check(WRONG)) != 'q')
        {
            switch (ch)
            {
                case 'a':
                    or_print(count, COL, strings);
                    break;
                case 'b':
                    as_print(count, ptr);
                    break;
                case 'c':
                    le_print(count, ptr); 
                    break;
                case 'd':
                    fi_print(count, ptr);
                    break;
                default:
                    printf("error.\n");
            }
        }
        system("cls");
        printf("Please input no more than %d of strings(First EOF or enter):\n", ROW);
    }
    
    return 0;
}

输出结果:

第十一章 字符串和字符串函数_第32张图片

题目12,方法:报告字符串中相关信息。示例代码11_12.c:

#include 
#include 
#include 

int main(void)
{
    int ch, words, upper, lower, punct, digit;
    words = upper = lower = punct = digit = 0;
    bool inword = false;
    
    printf("Please input some graceful characters: ");
    while ((ch = getchar()) != '&')
    {
        if (!isspace(ch) && inword == false)
        {
            inword = true;
            words++;
        }
        if (isspace(ch) && inword == true)
            inword = false;
        if (isupper(ch))
            upper++;
        else if (islower(ch))
            lower++;
        else if (ispunct(ch))
            punct++;
        else if (isdigit(ch))
            digit++;        
    }
    printf("Words:%3d\n", words);
    printf("Upper:%3d\n", upper);
    printf("Lower:%3d\n", lower);
    printf("Punct:%3d\n", punct);
    printf("Digit:%3d\n", digit);
    
    return 0;
} 

输出结果:

第十一章 字符串和字符串函数_第33张图片

题目13,方法:反序显示命令行参数的字符串。示例代码11_13.c:

#include 

int main(int argc, char * argv[])
{
    int i = 0;
    
    if (argc < 2)
        printf("Usage: %s\n", *argv);
    else
    {
        printf("Words: ");
        for (i = 1; i < argc; i++)
            printf("%s ", *(argv + i));
            putchar('\n');
        printf("Reveted words: ");
        for (i = argc - 1; i > 0; i--)
        printf("%s ", *(argv + i));
    }
    putchar('\n');
    
    return 0;
}

输出结果:

题目14,方法:命令行参数计算幂。示例代码11_14.c:

#include 
#include 

int main(int argc, char * argv[])
{
    int i, exp;
    double num, sum;
    sum = 1.0;
    
    if (argc != 3)
        printf("Usage: %s,Input double number and integer", *argv);
    else
    {
        num = atof(*(argv + 1));
        exp = atoi(*(argv + 2));
        if (exp == 0)
            sum = 0;
        else if (exp > 0)
        {
            for (i = 0; i < exp; i++)
                sum *= num;
        }
        else
        {
            for (i = 0; i < -exp; i++)
                sum *= num;
            sum = 1 / sum;
        }
        printf("Sum = %g\n", sum);
    }
    
    return 0;
}

输出结果:

题目15,方法:判断输入字符串是否纯数字组成。示例代码11_15.c:

#include 
#include 
#include 
#define LEN 20

char * s_gets(char *, int); //获取字符串
int myatoi(char *); //将字符转换为数字

int main(void)
{
    char str[LEN];
    
    printf("Please input a string(EOF to quit): ");
    while (s_gets(str, LEN) != NULL)
    {
        printf("String %s convert to digital is %d\n", str, myatoi(str));
        printf("You can enter another string(EOF to quit): ");
    }
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

int myatoi(char * st)
{
    int num = 0;
    
    while (*st)
    {
        if (!isdigit(*st))
            return 0;
        else
            num = num * 10 + (*st - '0');
        st++;        
    }
    
    return num;
}

输出结果:

题目16,方法:转换字符串并输出。示例代码11_16.c:

#include 
#include 

int main(int argc, char * argv[])
{
    int ch;
    int flag = 1;
    char mode = 'p';
    
    if (argc > 2)
    {
        printf("Usage: %s [-p | -u| -l]\n", *argv);
        flag = 0;
    }
    else if (argc == 2)
    {
        if (**(argv + 1) != '-')
        {
            printf("Usage: %s [-p | -u| -l]\n", *argv);
            flag = 0;
        }
        else
        {
            switch (*(*(argv + 1) + 1))
            {
                case 'p':
                case 'u':
                case 'l':
                    mode = *(*(argv + 1) + 1);
                    break;
                default:
                    printf("Usage: %s [-p | -u| -l]\n", *argv);
                    flag = 0;
            }
        }
    }
    if (flag)
    {
        printf("Please input some characters: ");
        while ((ch = getchar()) != '&' && ch != '\n')
        {
            switch (mode)
            {
                case 'p':
                    putchar(ch);
                    break;
                case 'u':
                    putchar(toupper(ch));
                    break;
                case 'l':
                    putchar(tolower(ch));
                    break;
            }
        }
    }
    
    return 0;    
}

输出结果:

你可能感兴趣的:(#,C,Primer,Plus,c语言)