BeautifulMan

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  16 随笔 :: 0 文章 :: 0 评论 :: 0 Trackbacks
今天学到了一个新知识——选择排序算法
核心思想:(查找和放置)选择剩余最大值的一个办法就是比较剩余数组的第一和第二个元素。如果第二个元素大,就交换这两个数据。现在比较第一个和第三个元素。如果第三个大,就交换这两个数据。每次交换都把大的元素移到上面。继续这种方法,直到比较第一个和最后一个元素。完成以后,最大的数就在剩余数组的第一个元素中。此时第一个元素已经排好了序,但是数组中的其他元素还很混乱。
外部循环表明要填充哪一个数组元素,内循环找出该数组元素中要放置的值。(这句话,理解不是很清楚!!!,还是用一个例子来说明吧!)
// 把一个字符串按字母表顺序排序
#include <stdio.h>
#include <string.h>
#define SIZE 81
#define LIM 20
#define HALT " "
// 字符串排序函数
void stsrt(char *strings[], int num);
int main(void)
{
    char input[LIM][SIZE];
    char *ptstr[LIM];
    int ct = 0;
    int k;

    printf("Input up to %d lines, and I will sort them.\n", LIM);
    printf("To stop, press the Enter key at a line's start.\n");
    while(ct < LIM && gets(input[ct]) != NULL && input[ct][0] != '\0')
    {
        ptstr[ct] = input[ct];
        ct++;
    }
    stsrt(ptstr, ct);
    puts("\nHere's the sorted list: \n");
    for(k = 0; k < ct; k++)
        puts(ptstr[k]);

    return 0;
}
void stsrt(char *strings[], int num)
{
    char *temp;
    int top, seek;

    for(top = 0; top < num - 1; top++)
        for(seek = top + 1; seek < num; seekas++)
            if(strcmp(strings[top], strings[seek]) > 0)
            {
                temp = strings[top];
                strings[top] = strings[seek];
                strings[seek] = temp;
            }
}
复习题
1、下面这个字符串的声明错在哪里?
int main(void)
{
char name[] = {'F', 'e', 's', 's'};

}
答:
如果想得到一个字符串,就应该在初始化中包含一个'\0'。当然,一种语法可以自动添加空字符:
char name[] = "Fess";
2、下面这个程序会打印出什么?
#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   注意:不是e you,ptr指针已经指向note[1]元素
3、下面这个程序会打印出什么?
#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、下面这个程序会打印出什么?
#include <stdio.h>
#include <string.h>
int main(void)
{
    char goldwyn[40] = "art of it all ";
    char samuel[40] = "I read p";
    char *quote = "the way through.";

    strcat(goldwyn, quote);
    strcat(samuel, goldwyn);
    puts(samuel);
    return 0;
}
答:
I read part of it all the way through.
5、这个练习涉及到了字符串、循环、指针和指针增量的使用。首先,假设已经定义了下面的函数:
#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的指针,也就是说,char *类型
c.
第一个H的地址
d.
*--pc是把指针减1并使用那里的值。--*pc取出pc指向的值然后把那个值减1
e.
Ho Ho Ho!!oH oH o(注意:在!和!之间有一个空字符,但是它不产生任何打印效果)
f.
while(*pc)检查pc是否指向一个空字符(也就是说字符串的结尾)。这个表达式使用指针所指向位置的值。
while(pc - str)检查pc是否与str指向同一个地址(字符串的开始)。这个表达式使用指针本身的值。
g.
在第一个while循环之后,pc指向空字符。在进入第二个循环后令它指向空字符之前的存储区,也就是说str指向的位置之前的位置,把那个字节解释为一个字符并进行打印。然后指针再退回到前面的字节处。永远都不会满足终止条件(pc == str),所以这个过程会一直继续下去。
h.
必须在调用程序中对pr()进行声明:char *pr(char *);
6、假定有下列声明:
char sign = '$';
sign的存储需要多少字节?"$"呢?
答:字符变量占用一个字节,所以sign占用一个字节。但是字符常量是被存储在一个int中的,也就是说'$'通常会使用2个或4个字节;但是实际上只使用int的一个字节来存储'$'的编码。字符串"$"使用两个字节,一个用来保存'$',一个用来保存'\0'。
7、下面的程序会打印出什么?
#include <stdio.h>
#include <string.h>
#define M1 "How are ya, sweetie?"
char M2[40] = "Beat the clock.";
char * M3 = "chat";
int main(void)
{
    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. (注意:M2的指向没有改变,M2 + 1怎么没有改变指针指向呢?)
Beat
chat
hat
at
t
t
at
How are ya, sweetie?
8、下面程序会打印出什么?
#include <stdio.h>
int main(void)
{
    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、strlen()函数需要一个指向字符串的指针作为参数,并返回字符串的长度。自己编写这个函数。
int strlen(char *str)
{
    int count;

    for(count = 0; *str != '\0'; str++)
        count++;
    return count;
}

int strlen(char *str)
{
    int count;

    while(*str++)
        count++;
    return count;
}
10、设计一个函数。其参数为一个字符串指针,并且返回一个指针,该指针指向字符串中所指位置后(包括该位置)的第一个空格字符。如果找不到空格字符,就返回空指针。
char *pstr(char *ps)
{
    while(*ps != ' ' && *ps != '\0')
        ps++; // 在第一个空格或空字符处停止
    if(*ps == '\0')
        return NULL;
    else
        return ps;
}
或下面这张方案:(它防止函数修改字符串,但是允许使用返回值来改变字符串。表达式(char *)ps被称为“使用类型指派取消const”)
char *pstr(const char *ps)
{
    while(*ps != ' ' && *ps != '\0')
        ps++; // 在第一个空格或空字符处停止
    if(*ps == '\0')
        return NULL;
    else
        return (char *)ps;
}
11、用ctype.h中的函数重写程序清单11.17中的程序,使得不管用户选择的是大写还是小写,程序都可以识别正确答案。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define ANSWER "GRANT"
#define MAX 40
void ToUpper(char *tr);
int main(void)
{
    char try[MAX];

    puts("Who is buried in Grant's tomb?");
    gets(try);
    ToUpper(try);
    while(strcmp(try, ANSWER) != 0)
    {
        puts("No,that's wrong.Try again.");
        gets(try);
        ToUpper(try);(不要忘记了!)
    }
    puts("That's right!");
    return 0;
}
void ToUpper(char *tr)
{
    while(*tr)
    {
        *tr = toupper(*tr);
        tr++;
    }
}
编程练习(这一章编程练习感觉够难的了!!!要哭的节奏!!!)
1、
#include <stdio.h>
#include <string.h>
#define MAX 40
char *get_string(char *str, int n);
int main(void)
{
    char str[MAX];
    int i;

    puts("Please enter a n characters: ");
    get_string(str, 5);
    for(i = 0; i < 5; i++)
        putchar(str[i]);
    return 0;
}
char *get_string(char *str, int n)
{
    int i = 0;
    while(i < n && (*str++ = getchar()) != '\0')
        i++;
    return str;
}
我觉得第一次做的比较麻烦,第二次更新之后:
#include <stdio.h>
void read(char *, int);

int main(void)
{
    char characters[11];

    puts("请输入一些字符:");
    read(characters, 11);
    puts(characters);
    return 0;
}
void read(char * str, int n)
{
    char ch;
    int i = 0;
    while((ch = getchar()) != EOF && i < n - 1)
    {
        *(str + i) = ch;
        i++;
    }
    *(str + n - 1) = '\0';
}
2、(还存在一个问题!!!)
#include <stdio.h>
#include <string.h>
#define MAX 5 // 我有一个疑惑,为什么MAX一定得是要输入的最大字符数呢?为何不能更大,比如说预定为40等
char *get_string(char *str, int n);
int main(void)
{
    char str[MAX];
    int i;

    puts("Please enter a n characters: ");
    get_string(str, 5);
    for(i = 0; i < 5; i++)
        putchar(str[i]);
    return 0;
}
char *get_string(char *str, int n)
{
    int i = 0;
    char c = getchar();

    while(i < n && c != ' ' && c != '\t' && c != '\n')
    {
        *(str + i) = c;
        i++;
        c = getchar();
    }
    return str;
}
经过第3题的练习,突然明白过来,原来是for循环的循环范围太大,会输入我们不要的乱七八糟的东西,干脆直接把字符数组给整成字符串,这样可以通过字符串长度来控制循环范围!!!
修改后:
#include <stdio.h>
#include <string.h>
#define MAX 40 // 我有一个疑惑,为什么MAX一定得是要输入的最大字符数呢?为何不能更大,比如说预定为40等
char *get_string(char *str, int n);
int main(void)
{
    char str[MAX];
    int i;

    puts("Please enter a n characters: ");
    get_string(str, 5);
    for(i = 0; < strlen(str); i++)
        putchar(str[i]);
    return 0;
}
char *get_string(char *str, int n)
{
    int i = 0;
    char c = getchar();

    while(i < n && c != ' ' && c != '\t' && c != '\n')
    {
        *(str + i) = c;
        i++;
        c = getchar();
    }
    *(str + i) = '\0';
    return str;
}
可以通过传进来的数组地址直接修改原数组嘛!何必这么麻烦呢!再一次修改如下:
#include <stdio.h>
void read(char *, int);

int main(void)
{
    char characters[11];

    puts("请输入一些字符:");
    read(characters, 11);
    puts(characters);
    return 0;
}
void read(char * str, int n)
{
    char ch;
    int i = 0;
    ch = getchar();
    while(i < n - 1 && ch != ' ' && ch != '\t' && ch != '\n')
    {
        *(str + i) = ch;
        i++;
        ch = getchar();
    }
    *(str + n - 1) = '\0';
}

3、
#include <stdio.h>
#include <string.h>
#define MAX 40
char *get_word(char *str);
int main(void)
{
    char str[MAX];
    int i;

    puts("Please enter some characters: ");
    get_word(str);
    for(i = 0; str[i] != '\0'; i++)
        putchar(str[i]);
    return 0;
}
char *get_word(char *str)
{
    scanf("%s", str);
    while(getchar() != '\n')
        continue;
    return str;
}
或者(更细一点)
#include <stdio.h>
#include <string.h>
#define MAX 40
char *get_word(char *str);
int main(void)
{
    char str[MAX];
    int i;

    puts("Please enter some characters: ");
    get_word(str);
    printf("The first word in this sentence is:");
    for(i = 0; i < strlen(str); i++)
        putchar(str[i]);
    return 0;
}
char *get_word(char *str)
{
    char c;
    int i = 0;
    c = getchar();
    // 丢掉该行之前多余的空格、制表符和换行符
    while(c == ' ' || c == '\n' || c == '\t')
    {
        putchar(c);
        c = getchar();
    }
    // 读取输入行里的第一个单词到数组
    while(c != ' ' && c != '\n' && c != '\t')
    {
        *(str + i) = c;
        i++;
        c = getchar();
    }
    // 读取之后,丢掉该行中其他的字符
    while(getchar() != '\n')
        continue;
    *(str + i) = '\0'; // 最后一个字符为空字符,这样返回的就是一个指向字符串的指针
    return str;
}
根本就必要做的这么麻烦,再次更新如下:
#include <stdio.h>
#include <ctype.h>
void read(char *);

int main(void)
{
    char characters[11];

    puts("请输入一些字符:");
    read(characters);
    puts(characters);
    return 0;
}
void read(char * str)
{
    char ch;

    while(isspace(ch = getchar()))
        continue;
    while(!isspace(ch))
    {
        *str++ = ch;
        ch = getchar();
    }
    *(str + 1) = '\0';
}

4、
#include <stdio.h>
#include <string.h>
char *get_strinx(char *str, int c);
int main(void)
{
    char str[40];
    char *ps;

    char start = 'a';
    while(start != 'q')
    {
        puts("Please enter a string:");
        gets(str);
        puts("Enter the specified character:");
        start = getchar();
        ps = get_strinx(str, start);
        if(ps == NULL)
            puts("You're not finding the character you want to find");
        else
            printf("The character you want to find is: %c\n", *ps);
        while(getchar() != '\n')
            continue;
    }
    return 0;
}
char *get_strinx(char *str, int c)
{
    while(*str != c && *str != '\0')
        str++;
    if(*str == '\0')
        return NULL;
    else
        return str;
}
我觉得下面写的函数会更简洁点,并且所用循环更规范一点:
#include <stdio.h>
#include <ctype.h>
char * StrChr(char * s, int c);

int main(void)
{
    char characters[81];
    int ch;
    char * ptr;

    puts("请您输入一个字符串: ");
    while(gets(characters) != NULL && characters[0] != '\0')
    {
        puts("请您输入在该字符串中要查找的字符:");
        ch = getchar();
        ptr = StrChr(characters, ch);
        if(ptr != NULL)
        {
            puts("您所要找到的字符串为:");
            puts(ptr);
        }
        else
            puts("没有找到您所说的字符串");
        puts("请您输入一个字符串: ");
        while(getchar() != '\n')
            continue;
    }

    return 0;
}
char * StrChr(char * s, int c)
{
    char * ps = NULL;

    while(*s)
    {
        if(*s == c)
            ps = s;
        s++;
    }
    return ps;
}

5、(类似编程练习4)
#include <stdio.h>
#include <string.h>
char *is_within(char *str, int c);
int main(void)
{
    char str[40];

    char start = 'a';
    while(start != 'q')
    {
        puts("Please enter a string:");
        gets(str);
        puts("Enter the specified character:");
        start = getchar();
        if(is_within(str, start))
            printf("Character %c in the string.\n", *(is_within(str, start)));
        else
            printf("Character %c not in the string.\n", start);
        while(getchar() != '\n')
            continue;
    }
    return 0;
}
char *is_within(char *str, int c)
{
    while(*str != c && *str != '\0')
        str++;
    if(*str == '\0')
        return NULL;
    else
        return str;
}
类似编程练习4,第二次修改如下:
#include <stdio.h>
#include <ctype.h>
int is_within(char * s, int c);

int main(void)
{
    char characters[81];
    int ch, result;

    puts("请您输入一个字符串: ");
    while(gets(characters) != NULL && characters[0] != '\0')
    {
        puts("请您输入在该字符串中要查找的字符:");
        ch = getchar();
        result = is_within(characters, ch);
        if(result != 0)
            puts("找到了您所说的字符");
        else
            puts("没有找到您所说的字符");
        puts("请您输入一个字符串: ");
        while(getchar() != '\n')
            continue;
    }

    return 0;
}
int is_within(char * s, int c)
{
    int re = 0;

    while(*s)
    {
        if(*s == c)
            re = 1;
        s++;
    }
    return re;
}

6、
#include <stdio.h>
#include <string.h>
char *stringcopy(char *s1, char *s2, int n);
int main(void)
{
    char s1[40];
    char s2[20];
    int num;

    puts("Please enter a string:");
    gets(s2);
    puts("Please enter the number of characters to copy:");
    while(scanf("%d", &num) == 1)
    {
        stringcopy(s1, s2, num);  // 函数已修改字符串s1,勿需在返回一个指向字符串的指针,s1 = stringcopy(s1, s2, num);是错误的,因为类型不相容 
        puts("s1 string output:");
        puts(s1);
        while(getchar() != '\n')
            continue;
        puts("Please enter a string:");
        gets(s2);
        puts("Please enter the number of characters to copy:");
    }
    return 0;
}
char *stringcopy(char *s1, char *s2, int n)
{
    int i;
    if(strlen(s2) >= n)
    {
        for(i = 0; i < n; i++)
            *(s1 + i) = *(s2 + i);
        *(s1 + n) = '\0';
    }
    else
    {
        for(i = 0; i < strlen(s2); i++)
            *(s1 + i) = *(s2 + i);
        *(s1 + i) = '\0';
    }
    return s1;
}
如果真要返回一个指向字符串的指针,如下:
#include <stdio.h>
#include <string.h>
char *stringcopy(char *s1, char *s2, int n);
int main(void)
{
    char s1[40];
    char s2[20];
    char *result;
    int num;

    puts("Please enter a string:");
    gets(s2);
    puts("Please enter the number of characters to copy:");
    while(scanf("%d", &num) == 1)
    {
        result = stringcopy(s1, s2, num);
        puts("s1 string output:");
        puts(result);
        while(getchar() != '\n')
            continue;
        puts("Please enter a string:");
        gets(s2);
        puts("Please enter the number of characters to copy:");
    }
    return 0;
}
char *stringcopy(char *s1, char *s2, int n)
{
    int i;
    if(strlen(s2) >= n)
    {
        for(i = 0; i < n; i++)
            *(s1 + i) = *(s2 + i);
        *(s1 + n) = '\0';
    }
    else
    {
        for(i = 0; i < strlen(s2); i++)
            *(s1 + i) = *(s2 + i);
        *(s1 + i) = '\0';
    }
    return s1;
}
实现思想都差不多,这是第3次修改:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char * StrNcpy(char * s1, const char * s2, int n);

int main(void)
{
    char characters[81], strings[31];
    int count;

    puts("请您输入一个字符串: ");
    while(gets(characters) != NULL && characters[0] != '\0')
    {
        puts("请您要复制给characters字符数组的字符数:");
        scanf("%d", &count);
        StrNcpy(strings, characters, count);
        puts("所得到的字符串为:");
        puts(strings);
        puts("请您输入一个字符串: ");
        while(getchar() != '\n')
            continue;
    }

    return 0;
}
char * StrNcpy(char * s1, const char * s2, int n)
{
    int i = 0;

    if(strlen(s2) >= n)
        while(i < n)
        {
            *(s1 + i) = *(s2 + i);
            i++;
        }
    else
    {
        while(*s2)
            *(s1++) = *(s2++);
        *s1 = '\0';
    }
    return s1;
}

7、
#include <stdio.h>
#include <string.h>
char *string_in(char *s1, char *s2);
int main(void)
{
    char s1[40];
    char s2[20];

    puts("Please enter a string:");
    gets(s1);
    puts("Please enter another string:");
    gets(s2);
    while(string_in(s1, s2) == NULL)
    {
        puts("Please enter another string:");
        gets(s2);
    }
    if(string_in(s1, s2))
        printf("The starting character of the string being included is: %c\n", *string_in(s1, s2));
    else
        puts("Can not find the string contained.");
    return 0;
}
char *string_in(char *s1, char *s2)
{
    int i, j, z = 0;
    char *ps;

    for(i = 0; i < strlen(s1); i++)
    {
        for(j = 0; j < strlen(s2); j++)
        {
            if(*(s1 + i) == *(s2 + j))
                ps = s1 + i;
                break;
        }
    }
    while(ps[z] == s2[z] && s2[z] != '\0')
    {
        z++;
    }
    if(z == strlen(s2))
        return ps;
    else
        return NULL;
}
写的太麻烦了,第二次更新如下:
#include <stdio.h>
#include <string.h>
char * string_in(char * s1, char * s2);

int main(void)
{
    char characters[81], strings[31];
    char * str;

    puts("请您输入一个字符串: ");
    while(gets(characters) != NULL && characters[0] != '\0')
    {
        puts("再请您输入一个字符串:");
        gets(strings);
        str = string_in(characters, strings);
        if(str != NULL)
            printf("字符串%s在字符串%s中的地址是:%c\n", strings, characters, *str);
        else
            puts("没有找到指定的字符串");
        puts("请您输入一个字符串: ");
    }

    return 0;
}
char * string_in(char * s1, char * s2)
{
    char * ps = NULL;

    while(*s1)
    {
        if(*s1 == *s2)
        {
            for(int i = 0; i < strlen(s2); i++)
                if(*(s1 + i) != *(s2 + i))
                    return ps;
            ps = s1;
        }
        s1++;
    }
    return ps;
}

8、
#include <stdio.h>
#include <string.h>
char *reverse(char *str);
int main(void)
{
    char s1[40];

    char c = 'y';
    while(c != 'q')
    {
        puts("Please enter a string:");
        gets(s1);
        puts("After the reversal of the string is:");
        puts(reverse(s1));  // 还是改变的原数组
        puts("Continue testing please enter y, quit please enter q");
        c = getchar();
        while(getchar() != '\n')
            continue;
    }
    return 0;
}
char *reverse(char *str)
{
    int i;
    int l = strlen(str);
    char ps[l];

    for(i = 0; i < l; i++)
        *(ps + i) = *(str + l - 1 - i);
    for(i = 0; i < l; i++)
        str[i] = ps[i];
    return str;
}
核心思路是一样的,只不过所用循环可能更规范:
#include <stdio.h>
#include <string.h>
void string_verse(char * s1);

int main(void)
{
    char strings[31];

    puts("请您输入一个字符串: ");
    while(gets(strings) != NULL && strings[0] != '\0')
    {
        string_verse(strings);
        printf("反序之后字符串为:%s\n", strings);
        puts("请您输入一个字符串: ");
    }

    return 0;
}
void string_verse(char * s1)
{
    int length = strlen(s1);
    char temp[31];

    for(int i = 0; i < length; i++)
        temp[i] = s1[length - 1 - i];
    for(int i = 0; i < length; i++)
        s1[i] = temp[i];
}

9、(彻底搞蒙了,还是借鉴CSDN----vs9841前辈的做法才做出来)
#include <stdio.h>
#include <string.h>
char *delete_space(char *str);
int main(void)
{
    char s1[40];

    char c = 'y';
    while(c != 'q')
    {
        puts("Please enter a string:");
        gets(s1);
        puts("After deleting the string is:");
        puts(delete_space(s1));  // 还是改变的原数组
        puts("Continue testing please enter y, quit please enter q");
        c = getchar();
        while(getchar() != '\n')
            continue;
    }
    return 0;
}
char *delete_space(char *str)
{
    char temp[40];
    int len = strlen(str), i, ct = 0;

    for(i = 0; i <= len; i++)
        temp[i] = str[i];
    for(i = 0; i <= len; i++)
    {
        if(temp[i] != ' ')
        {
            str[ct] = temp[i];
            ct++;
        }
    }
    return str;
}
第二次更新如下:
#include <stdio.h>
#include <string.h>
void delete_space(char * s1);

int main(void)
{
    char strings[31];

    puts("请您输入一个字符串: ");
    while(gets(strings) != NULL && strings[0] != '\0')
    {
        delete_space(strings);
        printf("删除空格之后字符串为:%s\n", strings);
        puts("请您输入一个字符串: ");
    }

    return 0;
}
void delete_space(char * s1)
{
    char temp[31];

    int length = strlen(s1);

    for(int i = 0; i <= length; i++)
        temp[i] = s1[i];
    for(int i = 0, j = 0; i <= length; i++)
    {
        if(temp[i] != ' ')
        {
            s1[j] = temp[i];
            j++;
        }
    }
}

10、(做大半天了,才总算做出来!!!)
#include <stdio.h>
#include <string.h>
#define SIZE 101
#define LIM 10
void menu(void);
int get_choice(void);
// 输出初始字符串列表
void inputstr(char *strings[], int num);
// 按ASCII顺序输出字符串
void sort(char *strings[], int num);
// 按长度递增顺序输出字符串
void sort_length(char *strings[], int num);
// 按字符串中第一个单词的长度输出字符串
void sort_word(char *strings[], int num);
int main(void)
{
    char input[LIM][SIZE];
    char *str1[LIM];
    char *str2[LIM];
    char *str3[LIM];
    char *str4[LIM];
    int choice;
    int count = 0;

    printf("Input up to %d lines, and I will sort them.\n", LIM);
    printf("To stop, press the Ctrl+Z(EOF) key at a line's start.\n");
    while(count <= LIM && gets(input[count]) != NULL)
    {
        str1[count] = input[count];
        str2[count] = input[count];
        str3[count] = input[count];
        str4[count] = input[count];
        count++;
    }
    while((choice = get_choice()) != 5)
    {
        switch(choice)
        {
            case 1: inputstr(str1, count);
                    break;
            case 2: sort(str2, count);
                    inputstr(str2, count);
                    break;
            case 3: sort_length(str3, count);
                    inputstr(str3, count);
                    break;
            case 4: sort_word(str4, count);
                    inputstr(str4, count);
                    break;
            default:
                printf("%d is not between 1 and 5\nPlease enter an ", choice);
                printf("integer value, such as 1, 2, 3, 4, or 5: \n");
                continue;
        }
    }
    printf("Bye!\n");
    return 0;
}
int get_choice(void)
{
    int choice;
    char ch;

    printf("**********************************************************************\n");
    printf("1) Output initial string list\n");
    printf("2) Output string by ASCII\n");
    printf("3) Sequence output string by length\n");
    printf("4) Output string by the length of the first word in the string\n");
    printf("5) quit\n");
    printf("**********************************************************************\n");
    printf("Please enter your choice: \n");
    while(scanf("%d", &choice) != 1)
    {
        while((ch = getchar()) != '\n')
            putchar(ch);
        printf(" is not an integer.\nPlease enter an ");
        printf("integer value, such as 1, 2, or 3: \n");
    }
    return choice;
}
// 输出初始字符串列表
void inputstr(char *strings[], int num)
{
    int i;

    for(i= 0; i < num; i++)
        puts(strings[i]);
}
// 按ASCII顺序输出字符串
void sort(char *strings[], int num)
{
    char *temp;
    int top, seek;

    for(top = 0; top < num - 1; top++)
        for(seek = top + 1; seek < num; seek++)
            if(strcmp(strings[top], strings[seek]) > 0)
            {
                temp = strings[top];
                strings[top] = strings[seek];
                strings[seek] = temp;
            }
}
// 按长度递增顺序输出字符串
void sort_length(char *strings[], int num)
{
    char *temp;
    int top, seek;

    for(top = 0; top < num - 1; top++)
        for(seek = top + 1; seek < num; seek++)
            if(strlen(strings[top]) > strlen(strings[seek]))
            {
                temp = strings[top];
                strings[top] = strings[seek];
                strings[seek] = temp;
            }
}
// 按字符串中第一个单词的长度输出字符串
void sort_word(char *strings[], int num)
{
    int first_word[num];
    int i, j, ct;
    char *temp;
    int top, seek;
    // 找出字符串中第一个单词,并计算出它的长度
    for(i = 0; i < num; i++)
    {
        for(j = 0; j < strlen(strings[i]); j++)
            if(strings[i][j] != ' ')
            {
                ct = j;
                while(strings[i][j] != ' ' && strings[i][j] != '\0')
                    j++;
                first_word[i] = j - ct;
                break;
            }

    }
    for(top = 0; top < num - 1; top++)
        for(seek = top + 1; seek < num; seek++)
            if(first_word[top] > first_word[seek])
            {
                temp = strings[top];
                strings[top] = strings[seek];
                strings[seek] = temp;
            }
}
主要就是按字符串中第一个单词的长度输出字符串这个功能实现比较麻烦一点,其他还好,经过第二次悉心改进之后,程序代码如下:
#include <stdio.h>
#include <string.h>
#define LIM 10
#define SIZE 101
int getChoice(void);
// 输出初始字符串列表
void output(char *str[], int num);
// 按ASCII顺序输出字符串
void sortByASCII(char *str[], int num);
// 按长度递增顺序输出字符串
void sortByLength(char *str[], int num);
// 找到指定字符串中的第一个单词
int getFirstWord(char *str);
// 按字符串中第一个单词的长度输出字符串
void sortByWordLen(char *str[], int num);

int main(void)
{
    char strings[LIM][SIZE];
    char *ptstr[LIM];
    char *ptstr1[LIM];
    char *ptstr2[LIM];
    char *ptstr3[LIM];
    int ct = 0;
    int choice;

    printf("请输入%d个字符串(在一行的开始键入[Enter]结束循环)\n", LIM);
    while(ct < LIM && gets(strings[ct]) != NULL && strings[ct][0] != '\0')
    {
        ptstr[ct] = strings[ct];
        ptstr1[ct] = strings[ct];
        ptstr2[ct] = strings[ct];
        ptstr3[ct] = strings[ct];
        ct++;
    }
    while((choice = getChoice()) != 5)
    {
        switch(choice)
        {
            case 1: output(ptstr, ct);
                    break;
            case 2: sortByASCII(ptstr1, ct);
                    output(ptstr1, ct);
                    break;
            case 3: sortByLength(ptstr2, ct);
                    output(ptstr2, ct);
                    break;
            case 4: sortByWordLen(ptstr3, ct);
                    output(ptstr3, ct);
                    break;
        }
    }
    printf("Bye!\n");

    return 0;
}
int getChoice(void)
{
    int choice;

    printf("************************************************\n");
    printf("1) 输出初始字符串列表           2) 按ASCII顺序输出字符串\n");
    printf("3) 按长度递增顺序输出字符串     4) 按字符串中第一个单词的长度输出字符串\n");
    printf("5) 退出\n");
    printf("************************************************\n");
    printf("请输入您的选择:");
    while(scanf("%d", &choice) != 1 || (choice < 1 || choice > 5))
    {
        while(getchar() != '\n')
            continue;
        printf("您输入的不是1~5这5个数字,请您重新输入:");
    }
    return choice;
}
void output(char *str[], int num)
{
    for(int i = 0; i < num; i++)
        puts(str[i]);
}
void sortByASCII(char *str[], int num)
{
    char *temp;

    for(int i = 0; i < num - 1; i++)
        for(int j = i + 1; j < num; j++)
            if(strcmp(str[i], str[j]) > 0)
            {
                temp = str[i];
                str[i] = str[j];
                str[j] = temp;
            }
}
void sortByLength(char *str[], int num)
{
    char *temp;

    for(int i = 0; i < num - 1; i++)
        for(int j = i + 1; j < num; j++)
            if(strlen(str[i]) > strlen(str[j]))
            {
                temp = str[i];
                str[i] = str[j];
                str[j] = temp;
            }
}
int getFirstWord(char *str)
{
    int ct = 0;

    while(*str)
    {
        while(*str != ' ')
        {
            ct++;
            str++;
            if(*str == ' ' || *str == '\0')
                return ct;
        }
        str++;
    }
    return ct;
}
void sortByWordLen(char *str[], int num)
{
    char *temp;

    for(int i = 0; i < num - 1; i++)
        for(int j = i + 1; j < num; j++)
            if(getFirstWord(str[i]) > getFirstWord(str[j]))
            {
                temp = str[i];
                str[i] = str[j];
                str[j] = temp;
            }
}
运行效果图如下:


11、
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
#define SIZE 101
int main(void)
{
    char input[SIZE];

    bool inword = false;  // 如果c在一个单词中,则inword等于true
    int i = 0;
    int word = 0; // 统计单词数
    int punct = 0; // 统计标点符号数
    int lower = 0; // 统计小写字母数
    int upper = 0; // 统计大写字母数
    int digit = 0; // 统计数字字符数

    printf("Please enter a test statement.\n");
    printf("To stop, press the Ctrl+Z(EOF) key at a line's start.\n");
    while(gets(input) != NULL)
    {
        for(i = 0; i < strlen(input); i++)
        {
            if(ispunct(input[i]))
                punct++;
            if(isupper(input[i]))
                upper++;
            if(islower(input[i]))
                lower++;
            if(isdigit(input[i]))
                digit++;
            if(!isspace(input[i]) && !ispunct(input[i]) && input[i] != '\0' && !inword)
            {
                inword = true;
                word++;
            }
            if((isspace(input[i]) || ispunct(input[i])) && inword)
                inword = false;
        }
        printf("Statistical results are as follows:\n");
        printf("Number of words: %d\n", word);
        printf("Capital letters: %d\n", upper);
        printf("Lowercase letters: %d\n", lower);
        printf("Punctuation number: %d\n", punct);
        printf("Number of characters: %d\n", digit);
    }
    return 0;
}
可以把统计单词函数模块化出来,经第二次修改如下:
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
// 统计单词数的函数
int count_word(char * str);

int main(void)
{
    int upper = 0;
    int lower = 0;
    int punct = 0;
    int digit = 0;
    char strings[101];
    char * str = strings;

    puts("请输入一个字符串:");
    gets(strings);
    while(*str)
    {
        if(isupper(*str))
            upper++;
        if(islower(*str))
            lower++;
        if(ispunct(*str))
            punct++;
        if(isdigit(*str))
            digit++;
        str++;
    }
    printf("经统计之后\n");
    printf("单词数是:%d\n", count_word(strings));
    printf("大写字母数是:%d\n", upper);
    printf("小写字母数是:%d\n", lower);
    printf("标点符号数是:%d\n", punct);
    printf("数字字符数是:%d\n", digit);

    return 0;
}
int count_word(char * str)
{
    bool inword = false;
    int n_words = 0;

    while(*str)
    {
        if(!isspace(*str) && !inword)
        {
            inword = true;
            n_words++;
        }
        if(isspace(*str) && inword)
            inword = false;
        str++;
    }
    return n_words;
}

12、(终于题目开始由难变易了!!!)(此题非常简单,故没有必要更新!!!)
#include <stdio.h>
int main(int argc, char *argv[])
{
    int count;

    printf("The command line has %d arguments: \n", argc - 1);
    for(count = argc - 1; count >= 1; count--)
        printf("%s ", argv[count]);
    printf("\n");
    return 0;
}
13、
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[])
{
    double num = atof(argv[1]);
    int p = atoi(argv[2]);
    double result;
    result = pow(num, p);

    printf("%d power of %.2f is: %.2f\n", p, num, result);
    return 0;
}
还要判断一下参数的个数,经第二次修改如下:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char *argv[])
{
    if(argc < 3)
        printf("Usage: %s positive-double-number\n", argv[0]);
    else
    {
        double xpow = atof(argv[1]);
        int p = atoi(argv[2]);
        printf("%.2f的%d次幂为:%.2f\n", xpow, p, pow(xpow, p));
    }

    return 0;
}

14、(真是做的要吐血,很多人做的都不是很对,借鉴30岁学编程——http://xiongyi85.blog.51cto.com博客作者的做法,感谢!!!)
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
int my_atoi(char *);
int main(int argc, char *argv[])
{
    printf("The string %s is converted to an integer: %d\n", argv[1], my_atoi(argv[1]));
    return 0;
}
int my_atoi(char * pstr)
{
    int sign = 1;
    int num = 0;

    // 字符串不能为空
    if(pstr == NULL)
        return 0;
    // 去掉字符串前面的空格
    while(isspace(*pstr))
        pstr++;
    // 判断首位是否有符号,若为负号,sign等于-1;若为正号,sign不变,并且跳过符号位
    if(*pstr == '-')
        sign = -1;
    if(*pstr == '-' || *pstr == '+')
        pstr++;
    // 转换直到遇到非数字结束
    while(isdigit(*pstr))
    {
        num = num * 10 + (*pstr - '0');
        pstr++;
    }
    // 增加符号位
    num *= sign;
    return num;
}
15、
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
    char ch;

    printf("Please enter a string: \n");
    if(argc == 2)
        switch(argv[1][1])
        {
            case 'p':
                while((ch = getchar()) != EOF)
                    putchar(ch);
                break;
            case 'u':
                while((ch = getchar()) != EOF)
                    putchar(toupper(ch));
                break;
            case 'l':
                while((ch = getchar()) != EOF)
                    putchar(tolower(ch));
                break;
        }
    return 0;
}
经第二次更新,代码如下所示:
#include <stdio.h>
#include <ctype.h>
// 将字符串全部转换为大写
void toUpper(char * s);
// 将字符串全部转换为小写
void toLower(char * s);

int main(int argc, char *argv[])
{
    char ch;

    if(argc < 3)
        printf("Usage: %s positive-string-char\n", argv[0]);
    else
    {
        ch = argv[2][0];
        switch(ch)
        {
            case 'p': puts(argv[1]);
                      break;
            case 'u': toUpper(argv[1]);
                      puts(argv[1]);
                      break;
            case 'l': toLower(argv[1]);
                      puts(argv[1]);
                      break;
        }
    }
    return 0;
}
void toUpper(char * s)
{
    while(*s)
    {
        *s = toupper(*s);
        s++;
    }
}
void toLower(char * s)
{
    while(*s)
    {
        *s = tolower(*s);
        s++;
    }
}
总结:总算是断断续续做完这一章了,感觉这一章巨难,做了几天了,每个题都想个个把小时左右!看来不熟练啊!!!要多加练习
posted on 2015-11-30 09:47 李阿昀 阅读(789) 评论(0)  编辑  收藏 所属分类: C Primer Plus 复习题与编程练习

只有注册用户登录后才能发表评论。


网站导航: