IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]20160217.CCPP体系详解(0027天)

    yincheng01发表于 2016-03-15 00:38:11
    love 0

    程序片段(01):TestCmd.c
    内容概要:管道_字符串

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    //01.管道:Windows应用程序与DOS系统之间的通信桥梁
    //  1.用于进程之间的通信(两个进程:窗体进程+cmd进程)
    //  2.窗体进程发送指令到cmd进程进行执行;
    //      然后将cmd进程执行之后的结果反馈到当前窗体进程
    //注:C语言将所有的设备都可以当做文件进行处理!(很重要)
    int exeShell(char * cmd, char * result)
    {//通过管道让cmd进程执行窗体进程向cmd进程发送的指令,并通过管道返回指令执行结果到窗体进程
        FILE * pf = _popen(cmd, "r");//以读取的模式打开一个管道,用管道的另一端执行一个cmd指令并反馈执行结果
        //1.打开进程之间通信的管道,进程管道用于进程之间的信息传递,可以向进程管道的另外一端(cmd进程)发送一个指令
        //      等待该指令的执行结果反馈,然后再做对指令执行结果的信息处理(窗体进程)
        //2.在Windows系统当中,操作各种设备的时候,都可以将各种设备当做文件系统进行处理(设备概念-->文件概念)
        //      C语言的文件概念模拟设备要点!(操作文件就等同于操作设备)-->需要_popen();函数进行文件模拟!
        if (NULL == pf)
        {
            printf("窗体进程和cmd进程之间的通信管道创建失败! \n");
            return 0;
        }
        while (!feof(pf))//到达文件结尾返回1,没有到达文件结尾返回0
        {
            char str[256] = { 0 };//信息读取字符缓冲区
            if (fgets(str, 256, pf))//fgets();函数的返回值就是通过管道进行进程通信所读取到的字符个数
            {//进行进程通信信息的拼接:通过strcat函数不断的进行拼接动作,每次拼接都是采取替换字符串标识'\0'的方式进行拼接
                strcat(result, str);//拼接字符串信息,构成完整信息体(逐步读取文件,构建完整文件体)
            }
        }
        _pclose(pf);//关闭进程之间的通信管道,避免过度占用资源
        return 1;
    }
    
    int main01(void)
    {
        char str[1024];
        gets(str);//获取键盘录入的字符串,并存储到参数所指定的字符串当中特点:只以回车作为录入结束标识符!
        puts(str);
    
        system("pause");
    }
    
    int main02(void)
    {
        char result[1024 * 8] = { 0 };//8M尺寸的字符串缓冲区
        if (exeShell("tasklist", result))
        {//如果执行脚本成功,就输出脚本的执行结果信息
            printf("%s \n", result);
        }
    
        //判断某个进程是否正在操作系统之上运行
        //char * p = strstr(result, "QQ.exe");
        //if (NULL != p)
        //{
        //  printf("QQ正在执行当中! \n");
        //}
        //else
        //{
        //  printf("QQ未在执行当中! \n");
        //}
    
        int i = 0;
        //统计QQ进程的执行个数,找到返回地址,未找到返回NULL
        for (char * p = strstr(result, "QQ.exe"); NULL != p; strstr(p + 6, "QQ.exe"))
        {
            ++i;
            printf("QQ运行了%d个! \n", i);
        }
    
        system("pause");
    }
    
    int main03(void)
    {
        char cmd[128] = { 0 };
        char result[1024 * 8] = { 0 };
        //gets(cmd);//只以\n作为录入状态结束标识符!
        scanf("%[^\n]", cmd);//%[^\n]正则表达式+scanf();函数-->只以\n作为扫描结束标识符
        puts(cmd);
        if (0 != exeShell(cmd, result))
        {
            printf("%s \n", result);
        }
    
        system("pause");
    }
    //1.tree Directory:用于将某个目录以树状形式进行显示,以及用于扫描某个地址(搜索文件的最佳方式!)-->避免使用递归遍历!
    //2.netstat -a:用于显示所有的TCP/UDP协议信息,用于显示网络链接状态,本地客户端与服务器之间的联系
    //3.ftp:都可以用命令行进行操作,这个操作的特点就是可以用于进行WiFi密码的破解,因为匹配密码的时候都会通过命令行发送一系列密码字典,我们可以采用密码字典进行密码的破解
    //4.管道的特点:进程之间的通信桥梁,Windows操作设备都是将设备看做为文件系统进行的操作;管道既可以用于操作文件也可以用于操作系统设备
    //5.strstr();的读取特点,会从首地址不断的进行数据的比对,只要检索到一个就停止检索状态
    //6.scanf();和gets();的不同点:scanf();不会处理空格,Tab键盘,gets();会进行空格的处理读取

    程序片段(02):PrintF.c
    内容概要:PrintF可变参数

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>//可变参数使用头文件
    
    //01.可变参数的使用特点:
    //  1.包含可变参数头文件:
    //      #include <stdarg.h>
    //  2.可变参数列表描述符:
    //      ...-->代表可变参数列表
    //  3.可变参数列表的特点:
    //      类型可以不一致,个数可以不确定
    //  4.几大标识符的使用:
    //      va_list:可变列表
    //      va_start:初始化列表
    //      va_arg:列表获取
    //      va_end:结束读取
    void myPrintf(char * pStr, ...)//...代表可变参数列表,类型可以不一致,个数也可以不一致
    {
        va_list vl;//可变参数列表起点
        va_start(vl, pStr);//通过pStr指向字符串的指针来初始化可变列表
        char flag;
        while (*pStr)//*pStar<=>*pStr!=NULL
        {//循环遍历每一个字符(字符指针特点)
            flag = *pStr;//取出字符
            if ('%' != flag)
            {
                putchar(flag);//打印字符
                ++pStr;
            }
            else
            {
                ++pStr;//跳过格式控制符前缀:%c->%s->%d->%f->%%(标识前缀'%')
                flag = *pStr;
                switch (flag)
                {
                case 'c':
                {
                    char chr = va_arg(vl, char);//按照指定类型从可变列表当中进行数据解析
                    printf("%c", chr);
                break;
                }
                case 's':
                {
                    char *str = va_arg(vl, char *);
                    printf("%s", str);
                    break;
                }
                case 'd':
                {
                    int num = va_arg(vl, int);
                    printf("%d", num);//printf();函数的底层实现就依赖于putchar();这个函数进行的实现
                    break;//将一个整数转化成为字符串,并且按照字符串的显示方式最简单方式就是调用printf();函数实现
                }
                case 'f':
                {
                    double db = va_arg(vl, double);
                    printf("%lf", db);
                    break;
                }
                case '%':
                {
                    putchar('%');
                    break;
                }
                default:
                    break;
                }
                ++pStr;
            }
        }
        va_end(vl);//结束可变参数列表的数据读取操作
    }
    
    int main01(void)
    {
        myPrintf("1234abc \n");
        myPrintf("1234abc%d \n", 10);
        myPrintf("1234abc%d%s \n", 10, "tytyuytu");
        myPrintf("1234abc%d%s%c \n", 10, "tytyuytu", 'A');
        myPrintf("1234abc%d%s%c%% \n", 10, "tytyuytu", 'A');
        myPrintf("1234abc%d%s%c%%%f \n", 10, "tytyuytu", 'A', 1234.78);
    
        system("pause");
    }

    程序片段(03):01.StrCpyStrCat.c+02.StrChr.c+03.StrSet.c
    内容概要:Str函数学习与实现

    ///01.StrCpyStrCat.c
    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    //01.strcpy();和strcat();区别:
    //  strcpy();从目标字符串的首地址开始拷贝
    //  strcat();从目标字符串的末尾字符串结束标识符'\0'开始拷贝
    void myStrCpy(char * dest, const char * src)
    {//无法正确的记录目标首地址+目标地址默认有结束标识符!
        if ('\0' == *src)
        {//递归的标准形式
            return;
        }
        *dest = *src;//按照指针变量方式进行内存拷贝(一个指针映射一块儿内存)
        myStrCpy(++dest, ++src);//指针变量当中的指针往前递进
    }
    
    //02.递归传参的几种方式:
    //  1.全局变量
    //  2.静态变量
    //  3.函数传参
    //  4.函数返回
    char * myStrCpyWithReturn(char * dest, const char * src, char * destS)
    {//采用函数传参的方式进行所需内存首地址的保存传递
        if ('\0' == *src)
        {//递归结束条件+健壮性判断
            return destS;
        }
        *dest = *src;
        myStrCpyWithReturn(++dest, ++src, destS);
    }
    
    //03.三种修改数据方式所需传递的内容:
    //  1.普通变量:(1种)
    //      修改普通变量的数据,需要传递普通变量的地址
    //  2.指针变量:(2种)
    //      修改指针变量所指向的数据,传递指针变量本身
    //      修改指针变量所存储的指向,传递指针变量的地址
    void myStrCpyWithPoint(char * dest, const char * src)
    {
        dest = (char *)malloc(100);//内存不一致,跨内存修改无效!
        while (*dest++ = *src++);
        //过程详解:
        //  1.运算符优先级:递变运算符的优先级高于取值运算符的优先级
        //      *dest++=*src++<=>*(dest++)=*(src++);
        //  2.后递变运算符的运算特点,先赋值再进行运算(这个先后指的是整体表达式)
        //      *(desc++)=*(src++);<=>
        //      *desc=*src;
        //      ++src;
        //      ++desc
    }
    
    void myStrCpyWithPointPlus(char ** dest, const char * src)
    {
        *dest = (char *)malloc(100);//跨函数修改指针变量所存储的指针
        char * tmpDest = *dest;//指针类型,需要匹配-->防止修改了指针变量本身所存储的内存首地址
        while (*tmpDest++ = *src++);
    }
    
    char * myStrCat(char * dest, const char * src)
    {
        while ('\0' != *dest)
        {
            ++dest;
        }
        while (*dest++ = *src++);
    }
    
    int main01(void)
    {
        char str1[10] = "task";
        char str2[10] = "list";
        strcat(str1, str2);
        //printf("%s \n", str1);
    
        char str[50] = { 0 };
        //myStrCpy(str, str1);
        //printf("%s \n", str);
    
        //printf("%s \n", myStrCpyWithReturn(str, str1, str));
    
        char * str3 = NULL;
        myStrCpyWithPointPlus(&str3, str1);
        printf("%s \n", str3);
    
        system("pause");
    }
    ///02.StrChr.c
    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char * myStrChr(const char * str, const char c)
    {
        //for (int i = 0; i < strlen(str); ++i)
        //{//索引法
        //  if (c == *(str + i))
        //  {
        //      return str + i;
        //  }
        //}
        for (const char * p = str; '\0' != *p; ++p)
        {//指针法
            if (c == *p)
            {
                return p;
            }
        }
    }
    
    char * myStrChrRecursion(const char * str, const char c)
    {//递归法
        if ('\0' == *str)
        {
            return NULL;
        }
        if (c == *str)
        {
            return str;
        }
        myStrChrRecursion(++str, c);
    }
    
    int main02(void)
    {
        char * p = myStrChrRecursion("calc", 'c');
        if (NULL == p)
        {
            printf("can't find!!! \n");
        }
        else
        {
            printf("can find %p, %c!!! \n", p, *p);
        }
    
        system("pause");
    }
    ///03.StrSet.c
    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    //01.strset函数详解:
    //  函数名:strset
    //  功能:将一个字符串当中的所有字符都设置为指定字符
    //  用法:char * strset(char * str, char c);
    void * myStrSet(char * str, char c)
    {
        //for (int i = 0; i < strlen(str); ++i)
        //{//索引法
        //  *(str + i) = c;
        //}
        //for (char * p = str; '\0' != *p; ++p)
        //{//指针法
        //  *p = c;
        //}
    }
    
    void * myStrSetRecursion(char * str, char c)
    {//递归法
        if ('\0' == *str)
        {
            return;
        }
        *str = c;
        myStrSetRecursion(++str, c);
    }
    
    int main03(void)
    {
        char * p = (char[10]) { 0 };
        strcpy(p, "123456");
        printf("%s \n", p);
        myStrSetRecursion(p, 'a');
        printf("%s \n", p);
    
        system("pause");
    }                                                                                                                                  

    程序片段(04):宽字符.c
    内容概要:宽字符实现

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <locale.h>
    
    int myWcsLen(wchar_t * wstr)
    {
        int i = 0;
        while (L'\0' != *wstr)
        {
            ++i;
            ++wstr;
        }
        return i;
    }                   
    
    //01.宽字符问题处理流程:
    //  1.设置本地化:
    //      setlocale(生效范围, "语言-国籍");
    //  2.宽字符使用:
    //      wchar_t+wcslen+wprintf(L"%ls", 宽字符指针);
    int main01(void)
    {
        setlocale(LC_ALL, "zh-CN");//设置本地化
        wchar_t wstr[10] = L"我是男神爱女神!\n";
        wprintf(L"%ls", wstr);//宽字符格式输出字符串L"%ls"
    
        system("pause");
    }
    
    int main02(void)
    {
        setlocale(LC_ALL, "zh-CN");                     
        wchar_t wstr[12] = L"a我是男神爱女神12 ";
        //strlen-->wcslen
        //int length = wcslen(wstr);
        int length = myWcsLen(wstr);
        printf("%d \n", length);
    
        system("pause");
    }
    
    int main03(void)
    {
        setlocale(LC_ALL, "zh-CN");
        wchar_t wch = L'我';
        putwchar(wch);
    
        system("pause");
    }
    
    wchar_t * myWcsCpy(wchar_t * dest, const wchar_t * src)
    {
        if (NULL == dest || NULL == src)
        {
            return NULL;
        }
        wchar_t * tmpDest = dest;
        while (*tmpDest++ = *src++);
        return dest;
    }
    
    int main04(void)
    {
        setlocale(LC_ALL, "zh-CN");
        wchar_t * p = (wchar_t[100]) { 0 };//栈上分配一个数组
        wchar_t wstr[10] = L"我是男神爱女神";
        myWcsCpy(p, wstr);
        wprintf(L"%ls", p);
    
        system("pause");
    }

    程序片段(05):01.StrCmpi.c+02.StrNICmp.c
    内容概要:StrCmpi

    ///01.StrCmpi.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void turnUpperToLower(char * pChr)
    {
        if ('A' <= *pChr && *pChr <= 'Z')
            *pChr += 32;
    }
    
    int myStrCmpI(char * str1, char * str2)
    {
        char chr1 = *str1;
        char chr2 = *str2;
        turnUpperToLower(&chr1);
        turnUpperToLower(&chr2);
        while (chr1 == chr2 && '\0' != *str1)
        {
            ++str1;
            ++str2;
            turnUpperToLower(&chr1);
            turnUpperToLower(&chr2);
        }
        if ('\0' == *str1 && '\0' == *str2)
        {
            return 0;
        }
        else
        {
            if (0 < chr1 - chr2)
            {
                return 1;
            }
            else
            {
                return -1;
            }
        }
    }
    
    //01.根据排序数组决定:
    //  需要待排序数组元素的地址
    int comp(void * p1, void * p2)
    {
        char ** pStr1 = (char **)p1;
        char ** pStr2 = (char **)p2;
        return myStrCmpI(*pStr1, *pStr2);
    }
    
    //02.strcmpi:
    //  1.忽略大小写
    //  2.比较全字符
    int main01(void)
    {
        //strcmpi
    
        //char str1[10] = "calc";
        //char str2[10] = "Calc";
        //printf("%d \n", _strcmpi(str1, str2));
    
        char * strs[5] = { "calc", "ali", "A3", "Bt", "BH" };
        qsort(strs, 5, 4, comp);
        for (int i = 0; i < 5; ++i)
        {
            printf("%s \n", *(strs + i));
        }
    
        system("pause");
    }
    ///02.StrNICmp.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    //01.大写转小写:
    //  大写+32<=>小写
    //02.C语言static:
    //  限定作用域
    static void turnUpperToLower(char * pchr)
    {
        if ('A' <= *pchr && *pchr <= 'Z')
            *pchr += 32;
    }
    
    int myStrNICmp(const char * str1,const char * str2, unsigned int maxCount)
    {
        char * bakStr = (char *)str1;
        char chr1 = *str1;
        char chr2 = *str2;
        turnUpperToLower(&chr1);
        turnUpperToLower(&chr2);
        int i = 0;
        while (chr1 == chr2 && '\0' != (*str1) && i < maxCount)
        {//注意顺序
            ++str1;
            ++str2;
            ++i;
            chr1 = *str1;
            chr2 = *str2;
            turnUpperToLower(&chr1);
            turnUpperToLower(&chr2);
        }
        if (maxCount == i)
        {
            return 0;
        }
        else
        {
            int length = strlen(bakStr);
            if (maxCount <= length)
            {//最大个数和有效长度
                if (chr1 - chr2 > 0)
                {
                    return 1;
                }
                else
                {
                    return -1;
                }
            }
            else
            {//有效长度范围之外!
                if ('\0' == *str1 && '\0' == *str2)
                {
                    return 1;
                }
                else
                {
                    if (chr1 - chr2 > 0)
                    {
                        return 1;
                    }
                    else
                    {
                        return -1;
                    }
                }
            }         
        }
    }
    
    //03.strnicmp:
    //  1.忽略大小写
    //  2.比较前N项
    int main02(void)
    {
        //strnicmp;
    
        //char str1[20] = "wangfangshandong";
        //char str2[20] = "wangfangshandong";
        //printf("%d \n", _strnicmp(str1, str2, 8));
        //printf("%d \n", myStrNICmp(str1, str2, 8));
    
        char str1[24] = "A2341231A";
        str1[6] = 'A';
        char str2[24] = "a2341231a";
        printf("%d \n", myStrNICmp(str1, str2, 8));
    
        system("pause");
    }


沪ICP备19023445号-2号
友情链接