目录
5.下面的练习涉及字符串、循环、指针和递增指针。首先,假设定义了下面的函数:
9.本章定义的s_gets()函数,用指针表示法代替数组表示法便可减少一个变量i。请改写该函数。
10.strlen()函数接受一个指向字符串的指针作为参数,并返回该字符串的长度。请编写一个这样的函数。
11.本章定义的s_gets()函数,可以用strchr()函数代替其中的while循环来查找换行符。请改写该函数。
12.设计一个函数,接受一个指向字符串的指针,返回指向该字符串第1个空格字符的指针,或如果未找到空格字符,则返回空指针。
13.重写程序清单11.21,使用ctype.h头文件中的函数,以便无论用户选择大写还是小写,该程序都能正确识别答案。
1.设计并测试一个函数,从输入中获取n个字符(包括空白、制表符、换行符),把结果储存在一个数组里,它的地址被传递作为一个参数。
2.修改编程练习1的函数,在n个字符后停止,或在读到第1个空白、制表符或换行符时停止,哪个先遇到哪个停止。不能只使用scanf()。
3.设计并测试一个函数,从一行输入中把一个单词读入一个数组中,并丢弃输入行中的其余字符。该函数应该跳过第1个非空白字符前面的所有空白。将一个单词定义为没有空白、制表符或换行符的字符序列。
4.设计并测试一个函数,它类似编程练习3的描述,只不过它接受第2个参数指明可读取的最大字符数。
9.编写一个函数,把字符串中的内容用其反序字符串代替。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。
10.编写一个函数接受一个字符串作为参数,并删除字符串中的空格。在一个程序中测试该函数,使用循环读取输入行,直到用户输入一行空行。该程序应该应用该函数读取每个输入的字符串,并显示处理后的字符串。
12.编写一个程序,读取输入,直至读到 EOF,报告读入的单词数、大写字母数、小写字母数、标点符号数和数字字符数。使用ctype.h头文件中的函数。
13.编写一个程序,反序显示命令行参数的单词。例如,命令行参数是see you later,该程序应打印later you see。
14.编写一个通过命令行运行的程序计算幂。第1个命令行参数是double类型的数,作为幂的底数,第2个参数是整数,作为幂的指数。
15.使用字符分类函数实现atoi()函数。如果输入的字符串不是纯数字,该函数返回0。
16.编写一个程序读取输入,直至读到文件结尾,然后把字符串打印出来。该程序识别和实现下面的命令行参数:
复习题
1.下面字符串的声明有什么问题?
如果要得到一个字符串,初始化列表中应该包含空字符“\0”;也可以用另种语法自动添加字符:char name[]="Fess"。
2.下面的程序会打印什么?
See you at the snack bar.ee you at the snack bar.See youe you //上一次++ptr已经移动到note[1],所以从这开始递增到\0处
3.下面的程序会打印什么?
ymymmyummyYummy循环每次从递减指针指向的位置输出到末尾位置
4.下面的程序会打印什么?
I read part of it all the way through
5.下面的练习涉及字符串、循环、指针和递增指针。首先,假设定义了下面的函数:
a.Ho Ho Ho!!oH oH oHb.char *(指向char的指针)c.第一个H的地址d.*--pc的意思是把指针递减1,并使用储存在该位置上的值。--*pc的意思是解引用pc指向的值,然后把该值减1(例如,H变成G)。e. Ho Ho Ho!!oH oH o;注意, 在两个!之间有一个空字符,但是通常该字符不会产生任何打印的效果。f.while (*pc)检查 pc 是否指向一个空字符(即,是否指向字符串的末尾)。while 的测试条件中使用储存在指针指向位置上的值。while (pc - str) 检查 pc 是否与 str 指向相同的位置(即,字符串的开头)。 while的测试条件中使用储存在指针指向位置上的值。g.进入第1个while循环后,pc指向空字符。进入第2个while循环后,它指向空字符前面的存储区(即,str 所指向位置前面的位置)。把该字节解释成一个字符,并打印这个字符。然后指针退回到前面的字节处。永远都不会满足结束条件(pc == str),所以这个过程会一直持续下去。h. 必须在主调程序中声明 pr() : char * pr(char *);
6.假设有如下声明:
字符变量占用一个字节,所以 sign 占 1 字节。但是字符常量储存为 int 类型,意思是'$' 通常占用 2 或 4 字节。但是实际上只使用 int 的 1 字节储存 '$' 的编码。字符串"$" 使用 2 字节:一个字节储存 '$' 的编码,一个字节储存的 '\0' 编码。
7.下面的程序会打印出什么?
How are ya,sweetie?How are ya,sweetie?Beat the clock.eat the clock.Beat the clock. Win a toy.BeatchathatatttatHow are ya,sweetie?
8.下面的程序会打印出什么?
faavrhee*le*on*sm
9.本章定义的s_gets()函数,用指针表示法代替数组表示法便可减少一个变量i。请改写该函数。
#include <stdio.h> // 提供fgets()和getchar()的原型
char * s_gets(char * st, int n)
{
char * ret_val;
ret_val = fgets(st, n, stdin);
if (ret_val)
{
while (*st != '\n' && *st != '\0')
st++;
if (*st == '\n')
*st = '\0';
else
while (getchar() != '\n')
continue;
}
return ret_val;
}
10.strlen()函数接受一个指向字符串的指针作为参数,并返回该字符串的长度。请编写一个这样的函数。
int strlen(char* st)
{
int length = 0;
while (*st != '\0')
{
st++;
length++;
}
return length;
}
11.本章定义的s_gets()函数,可以用strchr()函数代替其中的while循环来查找换行符。请改写该函数。
#include <stdio.h> // 提供fgets()和getchar()的原型
#include<string.h>
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!=NULL)//也可以写成if(find)
find = '\0';
else
while (getchar() != '\n')
continue;
}
return ret_val;
}
12.设计一个函数,接受一个指向字符串的指针,返回指向该字符串第1个空格字符的指针,或如果未找到空格字符,则返回空指针。
#include <stdio.h> // 提供fgets()和getchar()的原型
char* space(char* st)
{
while (*st != ' ' && *st != '\0')
st++;
if (*st == '\0')
return NULL;
else
return st;
}
13.重写程序清单11.21,使用ctype.h头文件中的函数,以便无论用户选择大写还是小写,该程序都能正确识别答案。
# pragma warning (disable:4996)
#include <stdio.h>
#include <string.h> // strcmp()函数的原型在该头文件中
#include<ctype.h>
#define ANSWER "GRANT"
#define SIZE 40
void ToUpper(char* str);
char* s_gets(char* st, int n);
int main(void)
{
char choice[SIZE];
puts("Who is buried in Grant's tomb?");
s_gets(choice, SIZE);
ToUpper(choice);
while (strcmp(choice, ANSWER) != 0)
{
puts("No, that's wrong. Try again.");
s_gets(choice, SIZE);
ToUpper(choice);
}
puts("That's right!");
return 0;
}
char* s_gets(char* st, int n)
{
char* ret_val;
int i = 0;
ret_val = fgets(st, n, stdin);
if (ret_val)
{
while (st[i] != '\n' && st[i] != '\0')
i++;
if (st[i] == '\n')
st[i] = '\0';
else
while (getchar() != '\n')
continue;
}
return ret_val;
}
void ToUpper(char* str)
{
while (*str != '\0')
{
*str = toupper(*str);
str++;
}
}
toupper():把小写字母转成大写字母
编程练习
1.设计并测试一个函数,从输入中获取n个字符(包括空白、制表符、换行符),把结果储存在一个数组里,它的地址被传递作为一个参数。
#include <stdio.h>
#include <ctype.h> // 用于isspace()函数
// 函数声明
void read_n_chars(char* buffer, int n);
int main() {
int n;
char arr[100];
printf("请输入要读取的字符数量: ");
scanf_s("%d", &n);
getchar(); // 消耗掉输入缓冲区中的换行符
read_n_chars(arr, n);
// 手动添加null终止符
arr[n] = '\0';
printf("读取的字符串: %s\n", arr);
return 0;
}
// 函数定义:从标准输入读取n个字符到buffer中
void read_n_chars(char* buffer, int n) {
for (int i = 0; i < n; i++) {
buffer[i] = getchar();
}
}
2.修改编程练习1的函数,在n个字符后停止,或在读到第1个空白、制表符或换行符时停止,哪个先遇到哪个停止。不能只使用scanf()。
#include <stdio.h>
#include <ctype.h> // 用于 isspace() 函数
// 函数声明
void read_n_chars(char* buffer, int n);
int main() {
int n;
char arr[100];
printf("请输入要读取的字符数量: ");
char input[20];
fgets(input, sizeof(input), stdin); // 读取用户输入的字符数量
sscanf_s(input, "%d", &n); // 将字符串转换为整数
read_n_chars(arr, n);
printf("读取的字符串: %s\n", arr);
return 0;
}
// 函数定义:从标准输入读取 n 个字符到 buffer 中,或在遇到空白、制表符、换行符时停止
void read_n_chars(char* buffer, int n) {
int i = 0;
char c;
while (i < n) {
c = getchar();
// 如果遇到空白、制表符或换行符,停止读取
if (isspace(c)) {
break;
}
buffer[i] = c;
i++;
}
// 在字符串末尾添加 null 终止符
buffer[i] = '\0';
}
3.设计并测试一个函数,从一行输入中把一个单词读入一个数组中,并丢弃输入行中的其余字符。该函数应该跳过第1个非空白字符前面的所有空白。将一个单词定义为没有空白、制表符或换行符的字符序列。
#include <stdio.h>
#include <ctype.h> // 用于 isspace() 函数
// 函数声明
void read_word(char* word);
int main() {
char word[100]; // 用于存储读取的单词
printf("请输入一行文本: ");
read_word(word);
printf("读取的单词是: %s\n", word);
return 0;
}
// 函数定义:从一行输入中读取一个单词并存储到数组中
void read_word(char* word) {
int i = 0;
char c;
// 跳过第一个非空白字符前面的所有空白
while ((c = getchar()) != EOF && isspace(c)) {
// 继续跳过空白字符
}
// 读取单词,直到遇到空白字符或输入结束
while (c != EOF && !isspace(c)) {
word[i] = c;
i++;
c = getchar();
}
// 在单词末尾添加 null 终止符
word[i] = '\0';
// 丢弃输入行中的其余字符
while (c != EOF && c != '\n') {
c = getchar();
}
}
4.设计并测试一个函数,它类似编程练习3的描述,只不过它接受第2个参数指明可读取的最大字符数。
#include <stdio.h>
#include <ctype.h> // 用于 isspace() 函数
// 函数声明
void read_word(char* word, int max_len);
int main() {
char word[100]; // 用于存储读取的单词
int max_len;
printf("请输入要读取的最大字符数: ");
scanf_s("%d", &max_len);
getchar(); // 消耗掉输入缓冲区中的换行符
printf("请输入一行文本: ");
read_word(word, max_len);
printf("读取的单词是: %s\n", word);
return 0;
}
// 函数定义:从一行输入中读取一个单词并存储到数组中,最多读取 max_len 个字符
void read_word(char* word, int max_len) {
int i = 0;
char c;
// 跳过第一个非空白字符前面的所有空白
while ((c = getchar()) != EOF && isspace(c)) {
// 继续跳过空白字符
}
// 读取单词,直到遇到空白字符、输入结束或达到最大字符数
while (c != EOF && !isspace(c) && i < max_len) {
word[i] = c;
i++;
c = getchar();
}
// 在单词末尾添加 null 终止符
word[i] = '\0';
// 丢弃输入行中的其余字符
while (c != EOF && c != '\n') {
c = getchar();
}
}
5.设计并测试一个函数,搜索第1个函数形参指定的字符串,在其中查找第2个函数形参指定的字符首次出现的位置。如果成功,该函数返指向该字符的指针,如果在字符串中未找到指定字符,则返回空指针(该函数的功能与 strchr()函数相同)。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。
#include <stdio.h>
#include<string.h>
// 函数声明
char* find_char(const char* str, char ch);
int main() {
char str[100];
char ch;
char* result;
while (1) {
// 获取用户输入的字符串
printf("请输入一个字符串(输入空行退出): ");
if (fgets(str, sizeof(str), stdin) == NULL || str[0] == '\n') {
break; // 如果输入为空行,退出循环
}
// 去除输入字符串末尾的换行符
str[strcspn(str, "\n")] = '\0';
// 获取用户输入的字符
printf("请输入要查找的字符: ");
ch = getchar();
while (getchar() != '\n'); // 清除输入缓冲区中的剩余字符
// 调用函数查找字符
result = find_char(str, ch);
// 输出结果
if (result != NULL) {
printf("字符 '%c' 在字符串中的位置: %d\n", ch, result - str);
}
else {
printf("字符 '%c' 未在字符串中找到。\n", ch);
}
}
printf("程序结束。\n");
return 0;
}
// 函数定义:在字符串中查找字符首次出现的位置
char* find_char(const char* str, char ch) {
while (*str != '\0') {
if (*str == ch) {
return (char*)str; // 返回指向该字符的指针
}
str++;
}
return NULL; // 未找到字符,返回空指针
}
6.编写一个名为is_within()的函数,接受一个字符和一个指向字符串的指针作为两个函数形参。如果指定字符在字符串中,该函数返回一个非零值(即为真)。否则,返回0(即为假)。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。
#include <stdio.h>
#include<string.h>
// 函数声明
int is_within(char ch, const char* str);
int main() {
char str[100];
char ch;
while (1) {
// 获取用户输入的字符串
printf("请输入一个字符串(输入空行退出): ");
if (fgets(str, sizeof(str), stdin) == NULL || str[0] == '\n') {
break; // 如果输入为空行,退出循环
}
// 去除输入字符串末尾的换行符
str[strcspn(str, "\n")] = '\0';
// 获取用户输入的字符
printf("请输入要查找的字符: ");
ch = getchar();
while (getchar() != '\n'); // 清除输入缓冲区中的剩余字符
// 调用函数检查字符是否在字符串中
if (is_within(ch, str)) {
printf("字符 '%c' 在字符串中。\n", ch);
}
else {
printf("字符 '%c' 不在字符串中。\n", ch);
}
}
printf("程序结束。\n");
return 0;
}
// 函数定义:检查字符是否在字符串中
int is_within(char ch, const char* str) {
while (*str != '\0') {
if (*str == ch) {
return 1; // 找到字符,返回真
}
str++;
}
return 0; // 未找到字符,返回假
}
7.strncpy(s1, s2, n)函数把s2中的n个字符拷贝至s1中,截断s2,或者有必要的话在末尾添加空字符。如果s2的长度是n或多于n,目标字符串不能以空字符结尾。该函数返回s1。自己编写一个这样的函数,名为mystrncpy()。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。
#include <stdio.h>
#include<string.h>
// 函数声明
char* mystrncpy(char* s1, const char* s2, int n);
int main() {
char s1[100]; // 目标字符串
char s2[100]; // 源字符串
int n;
while (1) {
// 获取用户输入的源字符串
printf("请输入源字符串(输入空行退出): ");
if (fgets(s2, sizeof(s2), stdin) == NULL || s2[0] == '\n') {
break; // 如果输入为空行,退出循环
}
// 去除输入字符串末尾的换行符
s2[strcspn(s2, "\n")] = '\0';
// 获取用户输入的拷贝字符数
printf("请输入要拷贝的字符数: ");
scanf_s("%d", &n);
while (getchar() != '\n'); // 清除输入缓冲区中的剩余字符
// 调用函数拷贝字符串
mystrncpy(s1, s2, n);
// 输出结果
printf("拷贝后的目标字符串: \"%s\"\n", s1);
}
printf("程序结束。\n");
return 0;
}
// 函数定义:将 s2 中的 n 个字符拷贝到 s1 中
char* mystrncpy(char* s1, const char* s2, int n) {
int i;
// 拷贝字符
for (i = 0; i < n && s2[i] != '\0'; i++) {
s1[i] = s2[i];
}
s1[i] = '\0';
return s1; // 返回目标字符串
}
8.编写一个名为string_in()的函数,接受两个指向字符串的指针作为参数。如果第2个字符串中包含第1个字符串,该函数将返回第1个字符串开始的地址。例如,string_in("hats", "at")将返回hats中a的地址。否则,该函数返回空指针。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。
#include <stdio.h>
#include <string.h>
// 函数声明
const char* string_in(const char* str1, const char* str2);
int main() {
char str1[100]; // 第一个字符串
char str2[100]; // 第二个字符串
while (1) {
// 获取用户输入的第一个字符串
printf("请输入第一个字符串(输入空行退出): ");
if (fgets(str1, sizeof(str1), stdin) == NULL || str1[0] == '\n') {
break; // 如果输入为空行,退出循环
}
// 去除输入字符串末尾的换行符
str1[strcspn(str1, "\n")] = '\0';
// 获取用户输入的第二个字符串
printf("请输入第二个字符串: ");
if (fgets(str2, sizeof(str2), stdin) == NULL || str2[0] == '\n') {
break; // 如果输入为空行,退出循环
}
// 去除输入字符串末尾的换行符
str2[strcspn(str2, "\n")] = '\0';
// 调用函数检查第一个字符串是否在第二个字符串中
const char* result = string_in(str1, str2);
// 输出结果
if (result != NULL) {
printf("'%s' 在 '%s' 中找到,起始位置为: %ld\n", str1, str2, result - str2);
}
else {
printf("'%s' 不在 '%s' 中。\n", str1, str2);
}
}
printf("程序结束。\n");
return 0;
}
// 函数定义:检查第一个字符串是否在第二个字符串中
const char* string_in(const char* str1, const char* str2) {
if (*str1 == '\0') {
return str2; // 如果第一个字符串为空,返回第二个字符串的起始地址
}
while (*str2 != '\0') {
const char* p1 = str1;
const char* p2 = str2;
// 检查是否匹配
while (*p1 != '\0' && *p2 != '\0' && *p1 == *p2) {
p1++;
p2++;
}
// 如果第一个字符串完全匹配,返回起始地址
if (*p1 == '\0') {
return str2;
}
str2++; // 继续检查下一个字符
}
return NULL; // 未找到,返回空指针
}
9.编写一个函数,把字符串中的内容用其反序字符串代替。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。
#include <stdio.h>
#include <string.h> // 用于 strlen 函数
// 函数声明
void reverse_string(char* str);
int main() {
char str[100]; // 用于存储用户输入的字符串
while (1) {
// 获取用户输入的字符串
printf("请输入一个字符串(输入空行退出): ");
if (fgets(str, sizeof(str), stdin) == NULL || str[0] == '\n') {
break; // 如果输入为空行,退出循环
}
// 去除输入字符串末尾的换行符
str[strcspn(str, "\n")] = '\0';
// 调用函数反转字符串
reverse_string(str);
// 输出结果
printf("反序后的字符串: %s\n", str);
}
printf("程序结束。\n");
return 0;
}
// 函数定义:反转字符串
void reverse_string(char* str) {
int length = strlen(str); // 获取字符串长度
int i, j;
// 使用双指针法反转字符串
for (i = 0, j = length - 1; i < j; i++, j--) {
// 交换字符
char temp = str[i];
str[i] = str[j];
str[j] = temp;
}
}
10.编写一个函数接受一个字符串作为参数,并删除字符串中的空格。在一个程序中测试该函数,使用循环读取输入行,直到用户输入一行空行。该程序应该应用该函数读取每个输入的字符串,并显示处理后的字符串。
#include <stdio.h>
#include<string.h>
// 函数声明
void remove_spaces(char* str);
int main() {
char str[100]; // 用于存储用户输入的字符串
while (1) {
// 获取用户输入的字符串
printf("请输入一个字符串(输入空行退出): ");
if (fgets(str, sizeof(str), stdin) == NULL || str[0] == '\n') {
break; // 如果输入为空行,退出循环
}
// 去除输入字符串末尾的换行符
str[strcspn(str, "\n")] = '\0';
// 调用函数删除空格
remove_spaces(str);
// 输出结果
printf("删除空格后的字符串: %s\n", str);
}
printf("程序结束。\n");
return 0;
}
// 函数定义:删除字符串中的空格
void remove_spaces(char* str) {
int i = 0; // 用于遍历原始字符串
int j = 0; // 用于构建新字符串
while (str[i] != '\0') {
if (str[i] != ' ') { // 如果当前字符不是空格
str[j] = str[i]; // 将字符复制到新位置
j++;
}
i++;
}
// 在新字符串末尾添加 null 终止符
str[j] = '\0';
}
11.编写一个函数,读入10个字符串或者读到EOF时停止。该程序为用户提供一个有5个选项的菜单:打印源字符串列表、以ASCII中的顺序打印字符串、按长度递增顺序打印字符串、按字符串中第1个单词的长度打印字符串、退出。菜单可以循环显示,除非用户选择退出选项。当然,该程序要能真正完成菜单中各选项的功能。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX_STRINGS 10
#define MAX_LENGTH 100
// 函数声明
void print_source_strings(char strings[MAX_STRINGS][MAX_LENGTH], int count);
void print_ascii_order(char strings[MAX_STRINGS][MAX_LENGTH], int count);
void print_length_order(char strings[MAX_STRINGS][MAX_LENGTH], int count);
int first_word_length(const char* str);
void print_first_word_length_order(char strings[MAX_STRINGS][MAX_LENGTH], int count);
int main() {
char strings[MAX_STRINGS][MAX_LENGTH]; // 存储字符串的数组
int count = 0; // 实际读取的字符串数量
// 读取字符串
printf("请输入最多 %d 个字符串(按 Ctrl+D 或 Ctrl+Z 结束输入):\n", MAX_STRINGS);
while (count < MAX_STRINGS && fgets(strings[count], MAX_LENGTH, stdin) != NULL) {
// 去除输入字符串末尾的换行符
strings[count][strcspn(strings[count], "\n")] = '\0';
count++;
}
// 菜单循环
int choice;
do {
printf("\n请选择一个选项:\n");
printf("1. 打印源字符串列表\n");
printf("2. 按 ASCII 顺序打印字符串\n");
printf("3. 按长度递增顺序打印字符串\n");
printf("4. 按第一个单词的长度打印字符串\n");
printf("5. 退出\n");
printf("请输入选项 (1-5): ");
scanf_s("%d", &choice);
// 根据用户选择执行操作
switch (choice) {
case 1:
print_source_strings(strings, count);
break;
case 2:
print_ascii_order(strings, count);
break;
case 3:
print_length_order(strings, count);
break;
case 4:
print_first_word_length_order(strings, count);
break;
case 5:
printf("退出程序。\n");
break;
default:
printf("无效选项,请重新选择。\n");
}
} while (choice != 5);
return 0;
}
// 函数定义:打印源字符串列表
void print_source_strings(char strings[MAX_STRINGS][MAX_LENGTH], int count) {
printf("源字符串列表:\n");
for (int i = 0; i < count; i++) {
printf("%s\n", strings[i]);
}
}
// 函数定义:按 ASCII 顺序打印字符串
void print_ascii_order(char strings[MAX_STRINGS][MAX_LENGTH], int count) {
char temp[MAX_LENGTH];
// 使用冒泡排序按 ASCII 顺序排序
for (int i = 0; i < count - 1; i++) {
for (int j = i + 1; j < count; j++) {
if (strcmp(strings[i], strings[j]) > 0) {
strcpy_s(temp, strings[i]);
strcpy_s(strings[i], strings[j]);
strcpy_s(strings[j], temp);
}
}
}
printf("按 ASCII 顺序打印字符串:\n");
for (int i = 0; i < count; i++) {
printf("%s\n", strings[i]);
}
}
// 函数定义:按长度递增顺序打印字符串
void print_length_order(char strings[MAX_STRINGS][MAX_LENGTH], int count) {
char temp[MAX_LENGTH];
// 使用冒泡排序按长度递增顺序排序
for (int i = 0; i < count - 1; i++) {
for (int j = i + 1; j < count; j++) {
if (strlen(strings[i]) > strlen(strings[j])) {
strcpy_s(temp, strings[i]);
strcpy_s(strings[i], strings[j]);
strcpy_s(strings[j], temp);
}
}
}
printf("按长度递增顺序打印字符串:\n");
for (int i = 0; i < count; i++) {
printf("%s\n", strings[i]);
}
}
// 函数定义:计算字符串中第一个单词的长度
int first_word_length(const char* str) {
int length = 0;
while (*str != '\0' && !isspace(*str)) {
length++;
str++;
}
return length;
}
// 函数定义:按第一个单词的长度打印字符串
void print_first_word_length_order(char strings[MAX_STRINGS][MAX_LENGTH], int count) {
char temp[MAX_LENGTH];
// 使用冒泡排序按第一个单词的长度排序
for (int i = 0; i < count - 1; i++) {
for (int j = i + 1; j < count; j++) {
if (first_word_length(strings[i]) > first_word_length(strings[j])) {
strcpy_s(temp, strings[i]);
strcpy_s(strings[i], strings[j]);
strcpy_s(strings[j], temp);
}
}
}
printf("按第一个单词的长度打印字符串:\n");
for (int i = 0; i < count; i++) {
printf("%s\n", strings[i]);
}
}
12.编写一个程序,读取输入,直至读到 EOF,报告读入的单词数、大写字母数、小写字母数、标点符号数和数字字符数。使用ctype.h头文件中的函数。
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
int main() {
int word_count = 0;
int upper_count = 0;
int lower_count = 0;
int punct_count = 0;
int digit_count = 0;
bool in_word = false;
int c;
while ((c = getchar()) != EOF) {
if (isspace(c)) {
in_word = false;
} else if (!in_word) {
in_word = true;
word_count++;
}
if (isupper(c)) {
upper_count++;
} else if (islower(c)) {
lower_count++;
} else if (ispunct(c)) {
punct_count++;
} else if (isdigit(c)) {
digit_count++;
}
}
printf("Words: %d\n", word_count);
printf("Uppercase letters: %d\n", upper_count);
printf("Lowercase letters: %d\n", lower_count);
printf("Punctuation marks: %d\n", punct_count);
printf("Digits: %d\n", digit_count);
return 0;
}
13.编写一个程序,反序显示命令行参数的单词。例如,命令行参数是see you later,该程序应打印later you see。
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[]) {
// argc至少为1,因为argv[0]是程序本身的名称
if (argc <= 1) {
printf("No arguments provided.\n");
return 1; // 返回非零值表示程序异常退出
}
// 从最后一个参数开始打印,直到第一个参数(不包括程序名)
for (int i = argc - 1; i > 0; i--) {
printf("%s ", argv[i]);
}
// 打印第一个参数(不包括程序名),后面不加空格
printf("%s\n", argv[1]);
return 0; // 返回0表示程序正常退出
}
14.编写一个通过命令行运行的程序计算幂。第1个命令行参数是double类型的数,作为幂的底数,第2个参数是整数,作为幂的指数。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[]) {
// 验证命令行参数的数量
if (argc != 3) {
fprintf(stderr, "Usage: %s <base> <exponent>\n", argv[0]);
return 1; // 非零返回值表示程序异常退出
}
// 将第一个命令行参数(底数)转换为double类型
double base;
char *endptr;
base = strtod(argv[1], &endptr);
// 检查转换是否成功
if (*endptr != '\0') {
fprintf(stderr, "Error: Invalid base (not a number).\n");
return 1;
}
// 将第二个命令行参数(指数)转换为整数类型
int exponent;
exponent = atoi(argv[2]);
// 计算幂并输出结果
double result = pow(base, exponent);
printf("%g^%d = %g\n", base, exponent, result);
return 0; // 零返回值表示程序正常退出
}
15.使用字符分类函数实现atoi()函数。如果输入的字符串不是纯数字,该函数返回0。
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
int my_atoi(const char *str) {
// 跳过前导空格
while (isspace(*str)) {
str++;
}
// 处理空字符串或非数字字符的情况
if (*str == '\0' || !isdigit(*str) && *str != '-' && *str != '+') {
return 0;
}
// 处理符号
int sign = 1;
if (*str == '-' || *str == '+') {
sign = (*str == '-') ? -1 : 1;
str++;
}
// 转换数字并检查结果是否溢出
int result = 0;
while (isdigit(*str)) {
int digit = *str - '0';
// 检查整数溢出
if (result > (INT_MAX - digit) / 10) {
return (sign == 1) ? INT_MAX : INT_MIN;
}
result = result * 10 + digit;
str++;
}
return sign * result;
}
int main() {
// 测试用例
printf("%d\n", my_atoi(" -42")); // 输出: -42
printf("%d\n", my_atoi("4193 with words")); // 输出: 4193
printf("%d\n", my_atoi("words and 987")); // 输出: 0
printf("%d\n", my_atoi("-91283472332")); // 输出: INT_MIN (通常是 -2147483648)
printf("%d\n", my_atoi("0")); // 输出: 0
return 0;
}
16.编写一个程序读取输入,直至读到文件结尾,然后把字符串打印出来。该程序识别和实现下面的命令行参数:
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#include <string.h>
int main(int argc, char *argv[]) {
bool print_original = true; // 默认按原样输出
bool to_upper = false; // 不转换为大写
bool to_lower = false; // 不转换为小写
// 解析命令行参数
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-p") == 0) {
print_original = true;
to_upper = false;
to_lower = false;
} else if (strcmp(argv[i], "-u") == 0) {
print_original = false;
to_upper = true;
to_lower = false;
} else if (strcmp(argv[i], "-l") == 0) {
print_original = false;
to_upper = false;
to_lower = true;
} else {
fprintf(stderr, "Unknown option: %s\n", argv[i]);
return 1; // 返回非零值表示程序异常退出
}
}
int c; // 用于存储从输入中读取的单个字符
while ((c = getchar()) != EOF) { // 持续读取输入直至EOF
if (print_original) {
putchar(c); // 按原样输出
} else if (to_upper) {
putchar(toupper(c)); // 转换为大写后输出
} else if (to_lower) {
putchar(tolower(c)); // 转换为小写后输出
}
}
return 0; // 返回零表示程序正常退出
}
不求甚解,没必要处处都要理解,影响学习进度,往后学习,回头看,不懂的自然会被解决。
语言的学习尽快啃完。