C primer plus (第六版)第十一章 编程练习第8题

题目:

8.编写⼀个名为string_in()的函数,接受两个指向字符串的指针作为参数。如果第2个字符串包含在第1个字符串中,该函数将返回第1个字符串开始的地址。例如,string_in("hats", "at")将返回hats中a的地址。否则,该函数返回空指针。在⼀个完整的程序中测试该函数,使⽤⼀个循环给函数提供输⼊值。

思路:

  1. 原书编程练习答案提供的思路是用strncmp()函数,比较2个字符串,从而得出第二个字符串是否包含在第一个字符串中。

  2. 另一个思路是逐个字符进行比较,如果第一个字符相同,再比较第二个字符,以此类推。

  3. 题目要求是在一个完整的程序中测试,使⽤⼀个循环给函数提供输⼊值,与之前题目类似,用while()循环+输入提示提示用户进行循环输入并调用函数测试,直到输入的是空行退出。

程序1(逐个字符比较+AI编写的对应函数):

cpp 复制代码
// 8.编写⼀个名为string_in()的函数,接受两个指向字符串的指针作为参数。
// 如果第2个字符串包含在第1个字符串中,该函数将返回第1个字符串开始的地址。例
// 如,string_in("hats", "at")将返回hats中a的地址。否则,该函数返回空指
// 针。在⼀个完整的程序中测试该函数,使⽤⼀个循环给函数提供输⼊值.
//思路:
// step1:调用字符串输入函数输入字符串1;
// step2:调用字符串输入函数输入字符串2;
// step3:调用字符串搜索函数在字符串1中看能否找到字符串2的字符,找到返回第一个
//        字符的地址,未找到返回NULL;
// step4:循环step1 ~ step3,直到用户按照提示输入回车退出;

#include <stdio.h>
#include <string.h>
#define MAXLEN 50
char * s_gets(char * st, int n);
char * string_in(char * str1, char * str2);

int main()
{
    char str1[MAXLEN];
    char str2[MAXLEN];
    char * check_result;

    puts("Please entry string 1(enter to quit):");
    
    while ( s_gets(str1, MAXLEN) && str1[0] != '\0')  
    {
        puts("Please entry string 2 to check if the string in str1");
        s_gets(str2, MAXLEN);
        // puts(str1);
        // puts(str2);
        check_result = string_in(str1, str2);
        if ( check_result != NULL)
        {
            puts("Find string 2 in string 1.");
            puts(check_result);
        }
        else
            puts("Error.");
        puts("Please entry string 1(enter to quit):");
    }
    puts("Done.");
    return 0;
}

char * string_in(char * str1, char * str2)
{
    if ( str2[0] == '\0' )
        return str1;
    

    for (int i = 0; str1[i] != '\0'; i++) 
    {
    // 找到第一个匹配的字符
    if (str1[i] == str2[0]) 
    {
        int j, k;
        // 检查后续字符是否都匹配
        for (j = i, k = 0; str2[k] != '\0' && str1[j] == str2[k]; j++, k++) {
            // 继续匹配下一个字符
        }
        // 如果子串全部匹配完成,返回起始地址
        if (str2[k] == '\0') {
            return &str1[i];
        }
    }
    }
    return NULL;
}

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;
}

程序2(AI编写的完整程序):

cpp 复制代码
#include <stdio.h>
#define MAX_STR_LEN 100

// 函数声明:检查str2是否包含在str1中,返回起始地址或NULL
char *string_in(const char *str1, const char *str2);
// 辅助函数:安全读取字符串
char *safe_gets(char *str, int n);

int main(void) {
    char str1[MAX_STR_LEN];
    char str2[MAX_STR_LEN];
    char *result;
    char continue_flag;

    printf("=== 字符串包含检查程序 ===\n");
    do {
        // 输入第一个字符串
        printf("\n请输入第一个字符串(作为主串): ");
        safe_gets(str1, MAX_STR_LEN);

        // 输入第二个字符串
        printf("请输入第二个字符串(作为子串): ");
        safe_gets(str2, MAX_STR_LEN);

        // 检查子串是否包含在主串中
        result = string_in(str1, str2);

        // 输出结果
        if (result != NULL) {
            printf("子串 \"%s\" 包含在主串 \"%s\" 中\n", str2, str1);
            printf("起始位置: %s\n", result);
            printf("起始地址: %p\n", (void *)result);
        } else {
            printf("子串 \"%s\" 不包含在主串 \"%s\" 中\n", str2, str1);
        }

        // 询问是否继续
        printf("\n是否继续测试?(y/n): ");
        scanf("%c", &continue_flag);
        // 清除输入缓冲区
        while (getchar() != '\n') continue;

    } while (continue_flag == 'y' || continue_flag == 'Y');

    printf("\n程序结束!\n");
    return 0;
}

// 函数实现:检查str2是否包含在str1中
char *string_in(const char *str1, const char *str2) {
    // 如果子串为空,返回主串的起始地址
    if (str2[0] == '\0') {
        return (char *)str1;
    }

    // 遍历主串
    for (int i = 0; str1[i] != '\0'; i++) {
        // 找到第一个匹配的字符
        if (str1[i] == str2[0]) {
            int j, k;
            // 检查后续字符是否都匹配
            for (j = i, k = 0; str2[k] != '\0' && str1[j] == str2[k]; j++, k++) {
                // 继续匹配下一个字符
            }
            // 如果子串全部匹配完成,返回起始地址
            if (str2[k] == '\0') {
                return (char *)&str1[i];
            }
        }
    }

    // 未找到匹配的子串
    return NULL;
}

// 安全读取字符串,处理换行符
char *safe_gets(char *str, int n) {
    char *result = fgets(str, n, stdin);
    if (result) {
        // 查找换行符并替换为字符串结束符
        int i = 0;
        while (str[i] != '\n' && str[i] != '\0') {
            i++;
        }
        if (str[i] == '\n') {
            str[i] = '\0';
        } else {
            // 清除输入缓冲区中剩余的字符
            while (getchar() != '\n') {
                continue;
            }
        }
    }
    return result;
}

程序3(原书编程练习答案):

cpp 复制代码
#include <stdio.h>
#define LEN 20
char * string_in(const char * s1, const char * s2);
int main()
{
    char orig[LEN] = "transportation";
    char * find;

    puts(orig);
    find = string_in(orig, "port");
    if(find)
        puts(find);
    else
        puts("Not found");
    find = string_in(orig, "part");
    if(find)
        puts(find);
    else
        puts("Not found");

    return 0;
}

#include <string.h>
char * string_in(const char * s1, const char * s2)
{
    int L2 = strlen(s2);
    int tries;          //maximum numbers of comparisons
    int nomatch = 1;    // set to 0 if match is found

    tries = strlen(s1) + 1 - L2;
    if (tries > 0)
        while (( nomatch = strncmp (s1, s2, L2)) && tries--)
            s1++;
        if (nomatch)
            return NULL;
        else
            return (char *) s1;     // cast const 
}
相关推荐
天將明°3 小时前
错误追踪技术指南:让Bug无处可逃的追踪网
c语言·单片机·嵌入式硬件
-Aerolite-8 小时前
【C/C++】C/C++状态机实现方法
c语言·c++
小莞尔12 小时前
【51单片机】【protues仿真】基于51单片机恒温箱系统
c语言·开发语言·单片机·嵌入式硬件·51单片机
润 下14 小时前
C语言——函数(超详细分析)
c语言·开发语言·笔记·算法
eSoftJourney16 小时前
C 语言核心关键字与数据结构:volatile、struct、union 详解
c语言·数据结构
小年糕是糕手17 小时前
【C语言】C语言预处理详解,从基础到进阶的全面讲解
linux·c语言·开发语言·数据结构·c++·windows·microsoft
高山有多高18 小时前
从 0 到 1 保姆级实现C语言双向链表
c语言·开发语言·数据结构·c++·算法·visual studio
Lucis__18 小时前
C++相关概念与语法基础——C基础上的改进与优化
c语言·开发语言·c++
没有医保李先生20 小时前
CAN协议入门
c语言·单片机