20160217.CCPP体系详解(0027天)

程序片段(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");
}

posted on 2016-03-15 00:38  三少爷的剑123  阅读(307)  评论(0编辑  收藏  举报

导航