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;
}
存在的问题:
- 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;
}
- 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;
}
单元化字符串
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;
}
```