今天學到了一個新知識——
選擇排序算法
核心思想:(查找和放置)選擇剩余最大值的一個辦法就是比較剩余數組的第一和第二個元素。如果第二個元素大,就交換這兩個數據。現在比較第一個和第三個元素。如果第三個大,就交換這兩個數據。每次交換都把大的元素移到上面。繼續這種方法,直到比較第一個和最后一個元素。完成以后,最大的數就在剩余數組的第一個元素中。此時第一個元素已經排好了序,但是數組中的其他元素還很混亂。
外部循環表明要填充哪一個數組元素,內循環找出該數組元素中要放置的值。(這句話,理解不是很清楚!!!,還是用一個例子來說明吧!)
// 把一個字符串按字母表順序排序
#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; i < 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++;
}
}
總結:總算是斷斷續續做完這一章了,感覺這一章巨難,做了幾天了,每個題都想個個把小時左右!看來不熟練啊!!!要多加練習