目录
一、复习题
1. 下面字符串的声明有什么问题?
cpp
int main(void)
{
char name[] = {'F', 'e', 's', 's'};
...
}
答:字符串是以空字符('\0')结尾的一系列字符,上述代码声明的是一个字符数组,并不是字符串。
2. 下面的程序会打印什么?
c
#include <stdio.h>
int main(void)
{
char note[] = "See you at the snack bar.";
char *ptr;
ptr = note;
puts(ptr);
puts(++ptr);
note[7] = '\0';
puts(note);
puts(++ptr);
return 0;
}
答:结果如下:
See you at the snack bar.
ee you at the snack bar.
See you
e you
3. 下面的程序会打印什么?
c
#include <stdio.h>
#include <string.h>
int main(void)
{
char food[] = "Yummy";
char *ptr;
ptr = food + strlen(food);
while (--ptr >= food)
puts(ptr);
return 0;
}
答:结果如下:
y
my
mmy
ummy
Yummy
4. 下面的程序会打印什么内容?
c
#include <stdio.h>
#include <string.h>
int main()
{
char goldwyn[40] = "art of it all";
char samuel[40] = "I read p";
const char *quote = "the way through.";
strcat(goldwyn, quote);
strcat(samuel, goldwyn);
puts(samuel);
return 0;
}
答:该程序先把字符串 quote 拼接在字符串 goldwyn 后面,再把字符串 goldwyn 拼接在字符串 samuel 后面,(注意数组是否能容纳)。结果如下:
I read part of it all the way through.
5. 下面的练习涉及字符串、循环、指针和递增指针。首先,假设定义了下面的函数。
c
#include <stdio.h>
char *pr(char *str)
{
char *pc;
pc = str;
while (*pc)
putchar(*pc++)
do
{
putchar(*--pc);
} while (pc - str);
return (pc);
}
考虑下面的函数调用:
x = pr("Ho Ho Ho!");
a. 将打印什么?
b. x 是什么类型?
c. x 的值是什么?
d. 表达式 *--pc 是什么意思?与 --*pc 有何不同?
e. 如果用 *pc-- 替换 *--pc,会打印什么?
f. 两个 while 循环用来测试什么?
g. 如果 pr() 函数的参数是空字符串,会怎么样?
h. 必须在主调函数中做什么,才能让 pr() 函数正常运行?
答:
a. 将打印如下内容:
Ho Ho Ho!!oH oH oH
b. char*,即字符指针
c. 字符串 "Ho Ho Ho!" 的首地址
d. 表达式 *--pc 先对指针 pc 减 1,然后解引用;而 --*pc 先对指针 pc 解引用,然后对解引用后的值减 1
e. 少打印一个 'H',即打印结果为:Ho Ho Ho!!oH oH o
f. 第 1 个 while 循环用来测试是否到达字符串末尾的空字符('\0'),第 2 个 while 循环用来测试是否到达该字符串的首字符
g. 由于 *pc 为空字符('\0'),所以不会进入第 1 个 while 循环,而第二个 while 循环先对 pc 递减,则表达式 pc - str 永远为负,该循环一直进行。
h. 主调函数需要声明该函数 char* pr(char str); ,且主调函数需要声明指针变量 x,即 char* x 。
6. 假设有如下声明:
c
char sign = '$';
sign 占用多少字节的内存?'' 占用多少字节的内存?"" 占用多少字节的内存?
答:sign 是 char 变量,占 1 个字节的内存。'' 是 char 字面值常量,占 1 个字节内存,而 "" 是字符串字面值,末尾还有空字符('\0'),占 2 个字节内存。
7. 下面的程序会打印什么?
c
#include <stdio.h>
#include <string.h>
#define M1 "How are ya, sweetie? "
char M2[40] = "Beat the clock.";
char *M3 = "chat";
int main()
{
char words[80];
printf(M1);
puts(M1);
puts(M2);
puts(M2 + 1);
strcpy(words, M2);
strcat(words, " Win a toy.");
puts(words);
words[4] = '\0';
puts(words);
while (*M3)
puts(M3++);
puts(--M3);
puts(--M3);
M3 = M1;
puts(M3);
return 0;
}
答:输出结果如下:
How are ya, sweetie? How are ya, sweetie?
Beat the clock.
eat the clock.
Beat the clock. Win a toy.
Win
chat
hat
at
t
t
at
How are ya, sweetie?
8. 下面的程序会打印什么?
c
#include <stdio.h>
int main()
{
char str1[] = "gawsie";
char str2[] = "bletonism";
char *ps;
int i = 0;
for (ps = str1; *ps != '\0'; ps++)
{
if (*ps == 'a' || *ps == 'e')
putchar(*ps);
else
(*ps)--;
putchar(*ps);
}
putchar('\n');
while (str2[i] != '\0')
{
printf("%c", i % 3 ? str2[i] : '*');
++i;
}
return 0;
}
答:结果如下:
faavrhee
*le*on*sm
9. 本章定义的 s_gets() 函数,用指针表示法代替数组表示法便可减少一个变量 i。请改写该函数
答:
程序设计分析: 指针表示法需要让该指针往后走,直到遇到换行符或者空字符。
代码如下:
c
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 变量进行计数,直到查找到该字符串末尾的空字符(空字符不计入)。该函数返回类型为 int,接受一个 char 类型的指针
代码如下:
c
int my_strlen(char* s)
{
int n = 0;
while (*s++)
++n;
return n;
}
11. 对于本章定义的 s_gets() 函数,可以用 strchr() 函数代替其中的 while 循环来查找替换换行符。请改写该函数。
答:
程序设计分析: 使用 strchr() 函数,需要包含头文件 string.h
代码如下:
c
// 头文件
#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)
*find = '\0';
else
while (getchar() != '\n')
continue;
}
return ret_val;
}
12. 设计一个函数,接受一个指向字符串的指针,返回指向该字符串中第一个空格字符的指针,如果未找到空格字符,则返回空指针。
答:
程序设计分析: 使用循环逐个字符查找,若遇到空格则停止返回,若遇到空字符,则返回空指针。
代码如下:
c
char* find_blank(char* s)
{
while (*s && *s != ' ')
++s;
// 判断
if (*s)
return s;
else
return null;
}
13. 重写程序清单 11.21,使用 ctype.h 头文件中的函数,需求无论用户选择大写还是小写,该程序都能正确识别答案。
答:
程序设计分析: 设计一个函数,该函数接受一个字符串,然后把该字符串的字母都编程大写。然后再输入答案之后,执行该函数。
代码如下:
c
// 头文件
#include <stdio.h>
#include <string.h>
// 常量声明
#define ANSWER "Grant"
#define SIZE 40
// 函数声明
char * s_gets(char * st, int n);
void upper(char* str);
int main()
{
char try[SIZE];
puts("Who is buried in Grant's tomb?");
s_gets(try, SIZE);
upper(try);
while (strcmp(try, ANSWER) != 0)
{
puts("No, that's wrong. Try again.");
s_gets(try, SIZE);
upper(try);
}
puts("That's right);
return 0;
}
// 函数定义
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)
*find = '\0';
else
while (getchar() != '\n')
continue;
}
return ret_val;
}
void upper(char* str)
{
while (*str)
{
*str = toupper(*str);
++str;
}
}
二、编程练习
1. 设计并测试一个函数,从输入中获取 n 个字符(包括空白、制表符、换行符),把结果存储在一个数组里,它的地址被传递作为一个参数。
答:
程序设计分析: 该函数的返回类型为 void,接受一个字符指针和 int 值作为参数。
代码如下:
c
#include <stdio.h>
// 常量声明
#define SIZE 100
// 函数声明
void get_n_char(char* arr, int n);
int main()
{
// 所需变量
char arr[100] = { 0 };
int n = 0;
// 输入
printf("请输入带输入的字符数量:");
scanf("%d", &n);
get_n_char(arr, n);
return 0;
}
// 函数定义
void get_n_char(char* arr, int n)
{
int i = 0;
do
{
arr[i] = getchar();
} while (arr[i] != EOF && ++i < n);
}
2. 修改编程练习 1 的函数,在 n 个字符后停止,或在督导第 1 个空白、制表符或换行符时停止,那个先遇到哪个停止。不能只使用 scanf()。
答:
程序设计分析: 读取字符后检查是否为空白,若为空白则使用 break 跳出循环。
代码如下:
c
#include <stdio.h>
#include <ctype.h>
// 常量声明
#define SIZE 100
// 函数声明
void get_n_char(char* arr, int n);
int main()
{
// 所需变量
char arr[100] = { 0 };
int n = 0;
// 输入
printf("请输入带输入的字符数量:");
scanf("%d", &n);
get_n_char(arr, n);
return 0;
}
// 函数定义
void get_n_char(char* arr, int n)
{
int i = 0;
do
{
arr[i] = getchar();
// 是空白就跳出循环
if (isspace(arr[i]))
break;
} while (arr[i] != EOF && ++i < n);
}
3. 设计并测试一个函数,从一行输入中把一个单词读入一个数组中,并丢弃输入行中的其余字符。该函数应该跳过第 1 个非空白字符前面的所有空白。将一个单词定义为没有空白、制表符或换行符的字符序列。
答:
程序设计分析: 该函数检验两次空白,第 1 次检验直到单词开头,第 2 次检验直到单词末尾。
代码如下:
c
#include <stdio.h>
#include <ctype.h>
// 常量声明
#define SIZE 100
// 函数声明
char* get_word(char* arr);
int main()
{
// 所需变量
char arr[SIZE] = { 0 };
// 输入一个单词
get_word(arr);
// 输出验证
puts(arr);
return 0;
}
// 函数定义
char* get_word(char* arr)
{
char temp[SIZE] = { 0 };
char* p = temp;
// 读取一行输入
fgets(temp, SIZE, stdin);
// 删除前面的空白
while (isspace(*p) && *p)
++p;
// 读取单词
while (!isspace(*p) && *p)
*arr++ = *p++;
return arr;
}
4. 设计并测试一个函数,它类似于编程练习 3 的描述,只不过它通过第 2 个参数指明可以读取的最大字符数。
答:
程序设计分析: 只不过在上一题的代码中添加一个输入字符限制的条件罢了。函数声明、函数调用和函数定义做相关修改。
代码如下:
c
#include <stdio.h>
#include <ctype.h>
// 常量声明
#define SIZE 100
#define LIT 5
// 函数声明
char* get_word(char* arr, int n);
int main()
{
// 所需变量
char arr[SIZE] = { 0 };
// 输入一个单词
get_word(arr, LIT);
// 输出验证
puts(arr);
return 0;
}
// 函数定义
char* get_word(char* arr, int n)
{
char temp[SIZE] = { 0 };
char* p = temp;
int i = 0;
// 读取一行输入
fgets(temp, SIZE, stdin);
// 删除前面的空白
while (isspace(*p) && *p)
++p;
// 读取单词
while (!isspace(*p) && *p)
{
*arr++ = *p++;
// 检测是否超出限制
if (++i >= n)
break;
}
return arr;
}
5. 设计并测试一个函数,搜索第 1 个函数形参指定的字符串,在其中查找第 2 个函数形参指定的字符首次出现的位置。如果成功,则返回该字符的指针,如果在字符串中未找到指定字符,则返回空指针(该函数的功能与 strchar() 函数相同)。在一个完整的程序中测试该函数,使用一个循环给函数输入值。
答:
程序设计分析: 该函数返回类型为 char*,接受一个 char* 值和 char 值。在该函数中使用循环遍历字符串,查找目标字符首次出现的位置。
代码如下:
c
#include <stdio.h>
// 常量声明
#define SIZE 40
// 函数声明
char* find_char(char* str, char ch);
int main()
{
// 所需变量
char temp[SIZE] = { 0 };
char ch = 'c';
// 输入
printf("请输入一段字符:");
while (fgets(temp, SIZE, stdin) && temp[0] != '\n')
{
char* position = find_char(temp, ch);
if (position)
printf("%c 字符首次出现的地址为:%p\n", ch, position);
else
printf("未找到字符 %c\n", ch);
// 下一个
printf("请输入下一段字符:");
}
return 0;
}
// 函数定义
char* find_char(char* str, char ch)
{
while (*str)
{
if (*str == ch)
return str;
else
++str;
}
return NULL;
}
6. 编写一个名为 is_within() 的函数,该函数以一个字符和一个指向字符串的指针作为两个函数的形参。如果指定的字符在字符串中,该函数返回一个非零值(即为真);否则,返回 0(即为加)。在一个完整的函数中测试该函数,使用一个循环给函数提供输入值。
答:
程序设计分析: 该题目和上一题几乎完全一样,只不过返回值用 0 或非 0 值代替了。
代码如下:
c
#include <stdio.h>
// 常量声明
#define SIZE 40
// 函数声明
int is_within(char ch, char* str);
int main()
{
// 所需变量
char temp[SIZE] = { 0 };
char ch = 'c';
// 输入
printf("请输入一段字符:");
while (fgets(temp, SIZE, stdin) && temp[0] != '\n')
{
if (is_within(ch, temp))
printf("该字符串中包含字符 %c\n", ch);
else
printf("该字符串中没有字符 %c\n", ch);
// 下一个
printf("请输入下一段字符:");
}
return 0;
}
// 函数定义
int is_within(char ch, char* str)
{
while (*str)
{
if (*str == ch)
return 1;
else
++str;
}
return 0;
}
7. strncpy(s1, s2, n) 函数把 s2 中的 n 个字符复制至 s1 中,截断 s2,或者根据需要在末尾添加空字符。如果 s2 的长度是 n 或者大于 n,目标字符串不能以空字符结尾。该函数返回 s1.自己编写一个这样的函数,使用一个循环给函数提供输入值。
答:
程序设计分析: 该函数需要对源字符串的长度和限制拷贝的长度进行比较,来判断是否需要在末尾添加换行符。
代码如下:
c
#include <stdio.h>
// 常量声明
#define SIZE 100
// 函数声明
char* my_strncpy(char* t, char* s, int n);
int main()
{
// 所需变量
char source[SIZE] = { 0 };
char target[SIZE] = { 0 };
int n = 0;
do
{
printf("请输入要拷贝的字符串:");
fgets(source, SIZE, stdin);
// 输入空行退出循环
if (source[0] == '\n')
break;
printf("请输入需要拷贝的字符数:");
scanf("%d", &n);
// 清理换行符
while (getchar() != '\n')
continue;
// 拷贝输出
my_strncpy(target, source, n);
puts(target);
} while (1);
return 0;
}
// 函数定义
char* my_strncpy(char* t, char* s, int n)
{
char* ret = t;
int i = 0;
while (s[i] && i < n)
{
t[i] = s[i];
++i;
}
if (i < n)
t[i] = '\0';
return ret;
}
**8. 编写一个名为 string_in() 的函数,该函数以两个指向字符串的指针作为参数。如果第 2 个字符串包含第 1 个字符串,该函数将返回第 1 个字符串开始的地址。例如,string_in("hats", "at") 将返回 hats 中 a 的地址。否则,返回空指针。在一个完整的程序中测试该函数,使用一个循环给该函数提供值。
**
答:
程序设计分析: 使用 string.h 头文件中的 strchar() 函数,找到目标字符串的首字符,然后使用 strcnmp() 函数进行比较。若不是,则往后继续如此。
代码如下:
c
#include <stdio.h>
#include <string.h>
// 常量声明
#define SIZE 40
// 函数声明
char* string_in(char* s, char* t);
int main()
{
// 所需变量
char source[SIZE] = { 0 };
char target[SIZE] = { 0 };
char* p = NULL;
// 输入
do
{
printf("输入源字符串:");
fgets(source, SIZE, stdin);
// 如果输入空行结束循环
if (source[0] == '\n')
break;
printf("输入需要找的字符串:");
scanf("%s", target);
// 清理换行符
while (getchar() != '\n')
continue;
// 查找
p = string_in(source, target);
if (p)
printf("地址:%p\n", p);
else
printf("没有\n");
} while (1);
return 0;
}
// 函数定义
char* string_in(char* s, char* t)
{
int len = strlen(t);
while (s = strchr(s, *t))
{
if (!strncmp(s, t, len))
return s;
else
++s;
}
return NULL;
}
9. 编写一个函数把字符串的内容用其反序字符串代替。在一个完整的程序中测试该函数,使用一个循环给函数提供输入值。
答:
程序设计分析: 该函数实现字符串的逆序,使用 strlen() 函数,找到字符串的末尾,然后与开头一个一个对调。
代码如下:
c
#include <stdio.h>
#include <string.h>
// 常量声明
#define SIZE 100
// 函数声明
void reverse_str(char* str);
int main()
{
// 所需变量
char str[SIZE] = { 0 };
// 输入
do
{
printf("请输入字符串: ");
fgets(str, SIZE, stdin);
// 空行结束循环
if (str[0] == '\n')
break;
// 把字符串 str 中的换行符删掉
int len = strlen(str);
if (str[len - 1] == '\n')
str[len - 1] = '\0';
reverse_str(str);
printf("逆序后的结果: ");
fputs(str, stdout);
putchar('\n');
} while (1);
return 0;
}
// 函数定义
void reverse_str(char* str)
{
char* begin = str;
char* end = str + strlen(str) - 1;
char temp = 0;
while (begin < end)
{
temp = *begin;
*begin = *end;
*end = temp;
// 下一对字符
++begin;
--end;
}
}
10. 编写一个函数,该函数以一个字符串作为参数,并可以删除字符串中的空格。在一个程序中测试该函数,使用循环读取输入行,直到用户输入一个空行。该程序应该应用该函数读取每个输入的字符串,并显示处理后的结果。
答:
程序设计分析: 该函数返回 int 值,若读取空行返回 0,否则返回 1。使用循环遍历该字符串,找到空格并删除,然后把后面的字符往前面移动。
代码如下:
c
#include <stdio.h>
// 常量声明
#define SIZE 100
// 函数声明
int delete_bs(char* str);
int main()
{
// 所需变量
char str[SIZE] = { 0 };
// 进入循环
while (delete_bs(str))
{
// 输出
printf("删除空格后的:");
fputs(str, stdout);
}
return 0;
}
// 函数定义
int delete_bs(char* str)
{
// 输入
printf("请输入字符串:");
fgets(str, SIZE, stdin);
// 判断是否为空行
if (str[0] == '\n')
return 0;
// 删除空格
while (*str)
{
// 如果是空格,就把后面的字符往前面挪
if (*str == ' ')
{
char* p = str + 1;
char* b = str;
while (*p && *p == ' ')
++p;
// 如果到末尾
if (*p == '\0')
*str = '\0';
// 挪移
while (*p)
{
*b++ = *p++;
}
*b = *p;
}
// 下一个字符
++str;
}
return 1;
}
11. 编写一个程序,读入 10 个字符串或者在读到 EOF 时停止。该程序为用户提供一个有 5 个选项的菜单,5 个选项分别是打印原始字符串列表,以 ASCII 码中的顺序打印字符串,按长度递增顺序打印字符串,按字符串中第一个单词的长度打印字符串,退出。菜单可以循环显示,除非用户选择"退出"选项。当然,该程序要能真正实现菜单中各选项的功能。
答:
程序设计分析: 上述前四个选项各设计为一个函数,然后还有一个打印原字符串函数和菜单函数。(作者的代码有许多冗余的部分,可以试着拆成一个函数,缩减代码的行数)
代码如下:
c
#include <stdio.h>
#include <ctype.h>
#include <string.h>
// 常量声明
#define NUM 10
#define SIZE 100
// 函数声明
void menu();
void print_origin(char str[][SIZE], int n);
void print_ascii(char str[][SIZE], int n);
void print_length(char str[][SIZE], int n);
void print_first_word(char str[][SIZE], int n);
void swap(char** s1, char** s2);
int first_word(char* str);
int main()
{
// 所需变量
int i = 0, select = 0;
char str[NUM][SIZE] = { 0 };
// 输入
printf("Please input 10 strings seperate by enter.\n");
for (i = 0; i < NUM; ++i)
{
fgets(str[i], SIZE, stdin);
}
// 进入循环
do
{
// 显示菜单
menu();
// 选择
scanf("%d", &select);
switch (select)
{
case 1 :
print_origin(str, NUM);
break;
case 2 :
print_ascii(str, NUM);
break;
case 3 :
print_length(str, NUM);
break;
case 4 :
print_first_word(str, NUM);
break;
default :
printf("Input error, retry.\n");
}
} while (select != 5);
return 0;
}
// 函数定义
void menu()
{
printf("*******************************************************\n");
printf("1)print_origin 2)print_ascii\n");
printf("3)print_length 4)print_first_word\n");
printf("5)quit\n");
printf("*******************************************************\n");
}
void print_origin(char str[][SIZE], int n)
{
int i;
for (i = 0; i < n; ++i)
fputs(str[i], stdout);
}
void print_ascii(char str[][SIZE], int n)
{
char* pstr[NUM] = { 0 };
int i;
for (i = 0; i < NUM; ++i)
pstr[i] = str[i];
// 排序
for (i = 0; i < NUM - 1; ++i)
{
int j;
for (j = 0; j < NUM - 1 - i; ++j)
{
if (strcmp(pstr[j], pstr[j + 1]) > 0)
{
swap(&pstr[j], &pstr[j + 1]);
}
}
}
// 输出
printf("Length:\n");
for (i = 0; i < NUM; ++i)
fputs(pstr[i], stdout);
}
void print_length(char str[][SIZE], int n)
{
char* pstr[NUM] = { 0 };
int i;
for (i = 0; i < NUM; ++i)
pstr[i] = str[i];
// 排序
for (i = 0; i < NUM - 1; ++i)
{
int j;
for (j = 0; j < NUM - 1 - i; ++j)
{
if (strlen(pstr[j]) > strlen(pstr[j + 1]))
{
swap(&pstr[j], &pstr[j + 1]);
}
}
}
// 输出
printf("Length:\n");
for (i = 0; i < NUM; ++i)
fputs(pstr[i], stdout);
}
void print_first_word(char str[][SIZE], int n)
{
char* pstr[NUM] = { 0 };
int i;
for (i = 0; i < NUM; ++i)
pstr[i] = str[i];
// 排序
for (i = 0; i < NUM - 1; ++i)
{
int j;
for (j = 0; j < NUM - 1 - i; ++j)
{
if (first_word(pstr[j]) > first_word(pstr[j + 1]))
{
swap(&pstr[j], &pstr[j + 1]);
}
}
}
// 输出
printf("Length:\n");
for (i = 0; i < NUM; ++i)
fputs(pstr[i], stdout);
}
void swap(char** s1, char** s2)
{
char* temp = *s1;
*s1 = *s2;
*s2 = temp;
}
int first_word(char* str)
{
int len = 0;
// 删除前面的空白
while (*str && isspace(*str))
++str;
// 计算长度
while (*str && !isspace(*str))
{
++len;
++str;
}
return len;
}
12. 编写一个程序,读取输入,直到读到 EOF,报告读入的单词数、大写字母数、小写字母数、标点符号数和数字字符数。使用 ctype.h 头文件中的函数。
答:
程序设计分析: 需要额外使用变量来判断是否为一个单词。
代码如下:
c
#include <stdio.h>
#include <ctype.h>
int main()
{
// 所需变量
int ch = 0;
int is_word = 0;
int words = 0, u_words = 0, l_words = 0, puncts = 0, digits = 0;
// 输入
while ((ch = getchar()) != EOF)
{
// 单个字符判断
if (isdigit(ch))
++digits;
else if (isupper(ch))
++u_words;
else if (islower(ch))
++l_words;
else if (ispunct(ch))
++puncts;
// 判断是否为一个单词
if (isspace(ch) && is_word)
{
++words;
is_word = 0;
}
if (!isspace(ch) && !is_word)
is_word = 1;
}
// 输出
printf("单词数:%d\n", words);
printf("大写字母数:%d\n", u_words);
printf("小写字母数:%d\n", l_words);
printf("标点符号数:%d\n", puncts);
printf("数字字符数:%d\n", digits);
return 0;
}
13. 编写一个程序,反序显示命令行参数中的单词。例如,命令行参数是 see you later,该程序打印 later you see。
答:
程序设计分析: 该反序只是把命令行的参数倒过来打印。
代码如下:
c
#include <stdio.h>
int main(int argc, char* argv[])
{
if (argc < 2)
printf("Error! not enough parameter to display!\n");
else
{
for (int i = argc; i > 1; --i)
{
printf("%s ", argv[i - 1]);
}
putchar('\n');
}
}
14. 编写一个通过命令行参数运行的程序,用来计算幂。第 1 个命令行参数是浮点数,可作为幂的底数,第 2 个参数是整数,可作为幂的指数。
答:
程序设计分析: 该程序和普通的幂函数计算一样,只是使用了命令行参数。
代码如下:
c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
if (argc != 3)
{
printf("Error argument. Please retry.\n");
return 0;
}
float f = atof(argv[1]);
int n = atoi(argv[2]);
float result = 1;
// 计算幂
int i;
for (i = 0; i < n; ++i)
{
result *= f;
}
// 输出
printf("该幂为:%.1lf\n", result);
return 0;
}
15. 使用字符分类函数实现 atoi() 函数。如果输入的字符串不是纯数字,该函数返回 0。
答:
程序设计分析: 该函数接受一个字符串,把该字符串转换为数字,若包含非数字则返回 0。
代码如下:
c
#include <stdio.h>
#include <ctype.h>
// 函数声明
int myatoi(char* str);
int main()
{
char temp[50] = { 0 };
printf("请输入一串数字:");
scanf("%s", temp);
printf("该数字为:%d\n", myatoi(temp));
return 0;
}
// 函数定义
int myatoi(char* str)
{
int result = 0;
while (*str)
{
if (isdigit(*str))
result = result * 10 + (*str - '0');
else
return 0;
// 下一个字符
++str;
}
return result;
}
16. 编写一个程序,用于读取输入,直至读到文件结尾,然后把字符串打印出来。该程序识别和实现下面的命令行参数:
答:
程序设计分析: 把上述操作三个操作分别定义成 3 个函数,然后根据命令行参数进行判断。
代码如下:
c
#include <stdio.h>
#include <ctype.h>
// 常量声明
#define SIZE 256
// 函数声明
void print(char* str);
void print_upper(char* str);
void print_lower(char* str);
int main(int argc, char* argv[])
{
char str[SIZE] = { 0 };
char ch = 0;
if (argc < 2)
ch = 'p';
else
ch = argv[1][1]; // 忽略 - 号
// 输入
printf("Enter a string to convert:");
fgets(str, SIZE, stdin);
switch (ch)
{
case 'P':
case 'p' :
print(str);
break;
case 'u' :
case 'U':
print_upper(str);
break;
case 'L' :
case 'l' :
print_lower(str);
break;
}
return 0;
}
// 函数定义
void print(char* str)
{
printf("Original:\n");
fputs(str, stdout);
}
void print_upper(char* str)
{
char* p = str;
while (*p)
{
*p = toupper(*p);
++p;
}
printf("Upper:\n");
fputs(str, stdout);
}
void print_lower(char* str)
{
char* p = str;
while (*p)
{
*p = tolower(*p);
++p;
}
printf("Lower:\n");
fputs(str, stdout);
}