第六章字符串和文本的应用

6.1 什么是字符串

下面的程序说明了空字符\0是如何运作的

为什么极客学院里的字符串根本就听不懂呢??

字符串常量是放在一对双引号中的一串字符或符号
\0 代码值为0的特殊字符是空字符
字符串的长度永远比字符串中的字符数多1
NULL表示不引用任何内容的内存地址,空字符是字符串的终止符

//program 6.1 Displaying a string
#include <stdio.h>

int main (void)
{
   printf("The character \0 is  used to terminate a string.");
   return 0;
}

试试看:确定字符串的长度

这个例子将初始化两个字符串然后确定每个字符串有多少个字符,不包含空字符:

//program 6.2 lengths of strings
#include <stdio.h>
#include <string.h>

int main(void)
{
   char str1[] ="To be or not to be";
   char str2[] =",that is the question";
   unsigned int count =0;
   while  (str1[count]  != '\0')
       ++count;

   printf("the length of the string \"%s\" is %d characters.\n",str1, count);

   count = 0;
   while (str2[count] != '\0')
       ++count;

   printf("The length of the string \"%s\" is %d     characters.\n",str2,count);
   return 0;
}

声明一些变量
声明两个char类型的数组,每个数组都初始化为一个字符串4

试试看:字符串数组

“电脑做你告诉他们做的事,而不是你想让他们做的事。”,
“当你把一些东西放在记忆里,记得你放在哪里。”,
“永远不要测试一个你不知道该怎么处理的条件。”,

确定二维数组中的字符串个数和每个字符串的长度

//program 6.3 Arrays of strings
#include <stdio.h >
#include<string.h>

int main(void)
{
    char  str[][] = {
                "computers do what you tell them to do ,not what you want them to do.",
                "When you put something in memory,remember where you put it.",
                "Never test for a condition you don't know what to do with.",
                          }
    unsigned int count = 0;
    unsigned int strCount =sizeof(str[0]);

    printf("There are %u strings.\n", strCount);

    for(unsigned int i=0 ; i< strCount ; ++)
    {
       count = 0;
       while (str[i][count])
           ++count;

       printf("The string:\n       \"%s\"\n contains %u characters.\n",str[i],count);
     }
     return 0;
}

试试看:连接字符串

这个示例把四个字符串合并为一个字符串

//program 6.4 Joining strings
#define _STDC_WANT_LIB_EXT1_1
#include< stdio.h>
#include<stdlib.h>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
int main(void)
{
   char preamble[] = " The joke is:\n\n";
   char str[][40] = {
                             "my dog has \n't got any nose.\n",
                          "how does your dog smell then?\n",
                          "my dog smells horrible.\n",
                             };

  unsigned int strCount = sizeof(str)/sizeof(str[0]);

 unsigned int length =0;
 for(unsigned int i =0; i < strCount ;++i)
    length += strnlen_s(str[i],sizeof(str[i]));

char joke[length + strnlen_s(preamble, sizefo(preamble)) +1];

  if(strncpy_s(joke,sizef(joke), preamble, sizeof(preamble)))
  {
     printf("Error copying preamble to joke.\n");
     return 1;
   }
 for (unsigned int i =0 ; i < strCount ; ++i)
 {
    if(strncat_s(joke,sizeof(joke), str[i],sizeof(str[i])))
    {
       printf("Error copying string str[%u].", i);
       return 2;
    }
  }
  printf("%s", joke);
  return 0;
}
Paste_Image.png

存在的问题:

  • strnlen_s strncapy_s strncat_s 都是未定义的标识符?
    那么如何定义标识符呢?
  • 如果出现重定义,多次初始化时是因为.c文件不支持将变量定义在for循环里面,把定义提到外面就可以了
  • 在VC6.C文件下没有long long 类型
  • 错误:函数调用在常量表达式中必须具有常量值,表达式必须含有常量值?如何更改这个错误?

试试看:比较字符串
这个例子比较两个从键盘输入的词,还介绍了键盘输入函数scanf()的一个可选的、更安全的替代函数,它在stdio.h中声明

//program 6.5 Comparing  strings
#define _STDC_WANT_LIB_EXT1_1
#include<stdio.h>
#include<string.h>

int main(void)
{
   char word1[MAX_LENGTH]
   char word2[MAX_LENGTH]

   printf("Type in the first word (maximun  %d characters): ",MAX_LENGTH -1);
   int retval = scanf_s("%s",word1,sizeof(word1));
   if(EOF == retval)
   {
       printf("Error reading the word.\n");
       return 1;
    }
    printf("Type in the second word(maximum %d characters):
",MAX_LENGTH -1);
   retval = scanf_s("%s", word2, sizeof(word2));
   if(EOF ==retval)
   {
      printf("Error reading the word.\n");
      return 2;
    }
    if(strcmp(word1,word2) == 0)
       printf(" you have entered identical words");
    else
       printf("%s precedes %s\n",(strcmp(word1,word2) <0)? word1  : wors2,(strcmp(word1,word2) <0) ? word2 : word1);
    return 0;
}

试试看:搜索字符串

//program 6.6 demonstration of seeking and finding
#include <stdio.h>
#include<stdlib.h>
#include<string.h>

int main(void)
{
    char str[] = "This string contians the holy grail.";
    char str2[] = " the holy grail";
    char str3[] ="the holy geil";

    if(strstr(str1,str2))
       printf("\n"%s\" was found in \"%s"\n",str2,str1)
    else
       printf("\n"%s\" was not found .",str2);
    if(!strstr(str1,str3))
       printf("\n"%s\" was not found.\n",str3);
    else
       printf("\nwe shouldn't get to here!");
    return 0;
}

试试看:单元化字符串

把存在的问题进行解决?但又不知道问什么?
read multiple line of prose from the keyboard

#define _STDC_WANT_LIB_EXT1_ 1
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

int main(void)
{
    char delimiters[] = " \".,;:!?)(";
    char buf[100];
    char str[1000];

    str[0] = '\0';
    size_t str_len = sizeof(str); //数组占用的字节数

    
    printf("Enter some prose that is less than %zd characters.\n"
           "Terminate input by entering an empty line:\n",str_len);
    
    //  从键盘读取多行字符
    while(true)
    {
        if(!gets(buf))
        {
            printf("Error reading string.\n");
            return 1;
        }
        if(!strlen(buf))
            break;
        
        if(strcat(str,buf))
        {
            printf("Maximum permitted input length exceeded.\n");
            return 1;
        }
    }
    printf("The words in the prose that you entered are: \n");
    
    unsigned int word_count = 0;
    char* pWord = strtok(str,  delimiters);
    if(pWord)
    {
        do
        {
            printf("%-18s",pWord);
            if(++word_count % 5 == 0)
                printf("\n");
            pWord = strtok(NULL,  delimiters);
        }while(pWord);
        printf("\n%u words found.\n", word_count);
    }
    else
        printf(" No words founf.\n");
    return 0;
}

//这个程序从输入的文本中提取所有的单词

//program 6.7 Find all the words
#define _STDC_WANT_LIB_EXT1__1
#include<stdio.h>
#include<stdbool.h>  //布尔值
#include<string>  //字符串函数
 
int main(void)
{
   char delimiters[] =" \".,;"!?)(";//定义界定符
   char buf[100];   //声明一维字符串数组
   char  str[1000];
   char* ptr =NULL;  //声明指针
   str[0] = ' \0 ';
   size_t  str_len = sizeof(str);  // 数组占用字节数
   size_t  str_len = sizeof(buf);  //  可以删除
   printf("Enter some prose that is less than %zd characters.\n"
            "Terminate  input by entering an empty  line:\n",
str_len);
  while(true)
  {
      if(!gets_s(buf, buf_len))  //可以删除第二个参数
      {
         printf("Error reading string.\n");
         return 1;
      }
    if(!strnlen_s(buf, buf_len))  //可以删除第二个参数
       break;

    if(!strcat_s(str, str_len, buf))  // 可以删除第二个参数
    {
        printf("Maximum permitted  input length exceeded.\n");
        return 1;
    }
}
printf("The word in  the permitted input lengeh exceeded.\n");
return 1;
}
}

试试看:读取换行

//program 6.7 Reading newline characters
#define _STDC_WANT_LIB_EXT1_1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(void)
{  
   char  delimiters[] =" \n\".,;:!?)(";

   printf("Enter some  prose that is less than %zd characters.\n"
            "Terminate input by entering an empty line:\n", str_len);
   while(true)
   {
        if(!fgets(buf, buf_len, stdin))
         {
             printf("Error reading string.\n");
             return 1;
         }
         if(buf[0] == '\n')
            break;

         if(strcat_s(str.str_len, buf))
         {
             printf("Maximum permittted  input length exceeded.");
            return  1;
         }
     }
     return 0;
}
Paste_Image.png
  • str_len buf buf_len都是未定义的标识符
    如何声明未定义的标识符?

试试看:使用字符分类函数

//program 6.8 Testing characters in a string
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <ctype.h>
#define BUF_SIZE 100

int main(void)
{
   char buf[BUF_SIZE];   声明一维字符数组
   int nLetters = 0;  变量声明及初始化
   int nDigits = 0;
   int nPunct = 0;

   printf("Enter an interesting string of less than %d characters:\n", BUF_SIZE);
  if(!gets_s(buf, sizeof(buf))) 输入函数读取一行字符串
  {
     printf("Error reading string.\n");
     return 1;
  }
    size_t i = 0;
   while(buf[i]) 变量也是表达式
   {
      if(isalpha(buf[i]))
      ++nLetters;
      else if(isdigit(buf[i]))
      ++nDigits;
      else if(ispunct(buf[i])
      ++nPunct;
      ++i;
    }
      printf("\nYour string contained %d letters, %d digits and %d punctuation charcacters.\n",nLetters, nDigits, nPunct);
      return 0;
}

试试看:转换字符
使用函数toupper() 和函数strstr()可以确定一个字符串是否出现在另一个字符串中

//program 6.9 Finding occurrences of one string in another
#define _STDC_WANT_LIB_EXT1_ 1
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define TEXT_LEN 100
#define SUBSTR_LEN 40

int main(void)
{
   char text[TEXT_LEN];
   char substring[SUBSTR_LEN];
   
   printf("Enter the string to be searched(less than %d characters):\n",TEXT_LEN);
   gets_s(text,  TEXT_LEN);

printf("\nEnter the string sought (less than %d characters);\n",SUBSTR_LEN);
gets_s(substring,SUBSTR_LEN);

printf("\nFirst string entered:\n%s\n", text);
printf("Second string entered:\n%d\n", substring);

for(int i =0; (text[i] = (char)toupper(text[i])) != '\0' ; ++i);
for(int i =0; (substring[i] = (char)toupper(substring[i])) != '\n'; ++i);

printf("The second string %s found in the first.\n",((strstr(text, substring) == NULL) ? "was not" : "was"));
return 0;
}
Paste_Image.png

单元化字符串
strtok()函数

//从输入的文本中提取所有的单词
//Find all the word
#define _STDC_WANT_EXT1_LIB_1
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

int main()
{
    char delimiters[] = " \",.:;!?)(";
    char buf[100];//用于存储一行输入
    char str[1000];//保存要单元化的完整散文
    char* ptr = NULL;//保存一个字符串的地址
    str[0] = '\0';
    size_t str_len = sizeof(str);
    size_t buf_len = sizeof(buf);

    //Read multiple lines of prose from the keyboard
    while (true)
    {
        if (!gets_s(buf, buf_len))//读取输入的一行
        {
            printf("Error reading string.\n");//
            return 1;
        }
        if (!strnlen_s(buf, buf_len))//遇见空行结束输入
            break;
        if (strcat_s(str, str_len, buf))//连接到str
        {
            printf("Maximum permitted input length exceeded.\n");
            return 1;
        }
    }
    printf("The words int the prose that you entered are:\n",str);

    //find and list all the words in the prose
    unsigned int word_count = 0;
    char * pWord = strtok_s(str,delimiters, &ptr);//返回char*类型的指针,指向标记的的第一个字符
    if (pWord)
    {
        do
        {
            printf("%-18s", pWord);//搜索函数后面的界定符,然后用\0替代,结束标记
            if (++word_count % 5 == 0)
                printf("\n");
            pWord = strtok_s(NULL, delimiters, &ptr);//没有找到标记的话就返回NULL,结束循环
        } while (pWord);
            printf("\n%u words found.\n", word_count);
    }
    else
        printf("no words found.\n");
    return 0;
}
```

> 
从键盘上读取任意长度的一段文本,确定该文本中每个单词的出现频率。
该段文本的长度不完全是任意的


```
#define _STDC_WANT_LIB_EXT1_ 1
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

#define TEXT_LEN 10000
#define BUF_SIZE 100
#define MAX_WORDS 500
#define WORD_LEN 12

int main()
{
    char delimiters[] = " \",.:;!?)(";
    char text[TEXT_LEN] = "";
    char buf[BUF_SIZE];
    char words[MAX_WORDS][WORD_LEN];
    int nword[MAX_WORDS] = { 0 };
    int word_count = 0;

    printf("Enter text on an arbitrary number of lines.");
    printf("\nEnter an empty line to end input:\n");

    //从键盘上读取多行字符
    while(true)
    {
        fgets(buf, BUF_SIZE, stdin);//从键盘上读取一行
        if (buf[0] == '\n')//遇到换行符退出循环
            break;
        if (strcat_s(text, TEXT_LEN, buf))
        {
            printf("Maximum capacity for text exceeded.Terminating program.\n");
            return 1;
        }
    }

        //Find the first word
    size_t len = TEXT_LEN;
    char *ptr = NULL;
    char* pWord = strtok_s(text, delimiters, &ptr); //返回一个指针,指向标记的第一个字符

    if (!pWord)
    {
        printf("No words found.Ending program.\n");
        return 1;
    }

        //Find the rest of the word

    bool new_word = true;

    while(true)
    {
        pWord = strtok_s(NULL, delimiters, &ptr);//继续查找标记符,

        if (!pWord)
        break;

        //Check for existing word
        for (int i = 0; i < word_count; ++i)
        {
            if (strcmp(words[i], pWord) == 0)//新旧单词对比
            {
                ++nword[i];//重复的次数加一
                new_word = false;
            }
        }
        if (new_word)
        {
            strcpy_s(words[word_count], WORD_LEN, pWord);
            ++nword[word_count++];
        }
        else
            new_word = true;
        if (word_count > MAX_WORDS - 1)
        {
            printf("Capacity to store words exceeded.\n");
            return 1;
        }
    }

    //list the words
    for (int i = 0; i < word_count; ++i)//容易犯的错误是总是在for()的后面多加分号
    {
        printf(" %-13s  %3d", words[i], nword[i]);
        if ((i + 1) % 4 == 0)
            printf("\n");
    }
    printf("\n");
    return 0;
}

```
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容