プログラミング実習II (2025) 課題
[E8] 第7章 文字列
(E8_1) 「キックオフ C言語」, p. 146, ソースコード9.1 は標準関数 strlen と 自作の関数 str_length を文字列の長さを求めている.
(E8_2) 「キックオフ C言語」, p. 146, ソースコード9.2 は,標準関数 strcpy,自作の関数 str_copy,str_copy2 により,配列の文字列を別の配列にコピーする.
(E8_3) 「キックオフ C言語」, p. 150, ソースコード9.3 は,標準関数 strcat,自作の関数 str_concat,str_concat2 により,配列の文字列を別の配列に連結する.
(E8_4) 「キックオフ C言語」, p. 154 では,文字列を比較する標準関数 strcmp と,自作関数 str_compare が説明されている.
表示例: (a と b の比較) hanshin japan (a と d の比較) hankyu hanshin (b と c の比較) japan japanese (b と e の比較) japan
#include <stdio.h> #include <string.h> void print_str( char s1[], char s2[] ){ // s1 と s2 を strcmp で比較して辞書順に表示 } int main( void ) { char a[] = "hanshin"; char b[] = "japan"; char c[] = "japanese"; char d[] = "hankyu"; char e[] = "japan"; print_str( a, b ); print_str( a, d ); print_str( b, c ); print_str( b, e ); return 0; } |
(E8_5) 以下のプログラムは,キーボードから入力された文字列を表示し,さらにその長さも表示する.キーボードから文字列を受け取る際に,標準関数 fgets および自作の関数 get_line を用いている.
#include <stdio.h> #include <string.h> #define N 256 void get_line(char buff[], int size) // size は最大文字数 { int i, c; for (i = 0; i < size - 1; i++) { c = getchar(); if (c == EOF || c == '\n') break; buff[i] = c; } buff[i] = '\0'; } int main(void) { char str[ N ]; printf("Enter a string:"); fgets( str, sizeof(str), stdin ); // 標準関数 fgets で文字列取得 printf("str = %s\n", str ); // 文字列 str の表示 printf("length = %d\n", (int)strlen( str ) ); // 標準関数 strlen で文字列の長さを得て表示 printf("Enter the same string again:"); get_line( str, N ); // 自作関数 get_line で文字列取得 printf("str = %s\n", str ); // 文字列 str の表示 printf("length = %d\n", (int)strlen( str ) ); // 標準関数 strlen で文字列の長さを得て表示 return 0; } |
(E8_6) 文字列を逆順にして別の配列に格納する関数を作成する.
(表示例: これは回文です) Key in a string>> a Santa at Nasa asaN ta atnaS a
#include <stdio.h> #include <string.h> #define M 128 void get_line( char buff[], int size ) { } void str_reverse( char src[], char dst[] ){ } int main( void ) { char str[ M ] = ""; char dst[ M ] = ""; printf("Enter a string:"); get_line( str, M ); printf("%s \n", str); printf("%s \n", dst); return 0; } |
(E8_7) 教科書 p. 152,[リスト 4.12] では数当てゲームが示されている.本問では,これに類する単語当てゲームを作成したい.
#include <stdio.h> #include <string.h> #define M 128 // キーボードから入力される文字列の長さの上限 // #define T 10 // キーボードから文字列を受け取る回数の上限 void get_line( char buff[], int size ) { } int main( void ) { char str[] = "kwansei"; // 正解の文字列 char input[ M ] = ""; // キーボードから入力される文字列 printf("Enter a word >>>"); get_line( input, M ); // キーボードから i+1 番目の文字列入力 return 0; } |
表示例: (入力が gakuin のとき) "もっと後ろの単語を入力して." (入力が univ のとき) "もっと前の単語を入力して." (入力が kwata のとき) "もっと前の単語を入力して." (入力が kwansea のとき) "もっと後ろの単語を入力して." (入力が kwansei のとき) "正解" 入力が10回に達しても正解しないとき "不正解"
表示例(ヒントを追加した場合): (入力が gakuin のとき) "もっと後ろの単語を入力して.1文字もあっていません." (入力が univ のとき) "もっと前の単語を入力して.1文字もあっていません." (入力が kwata のとき) "もっと前の単語を入力して.最初の3文字は合っています" (入力が kwansea のとき) "もっと後ろの単語を入力して.最初の6文字は合っています" (入力が kwansei のとき) "正解" 入力の履歴: gakuin univ kwata kwansea kwansei
(E8_8) 自作関数 get_line() 関数を用いて文字列の長さと,その中に含まれる大文字,小文字,数字,その他(の記号やスペースなど),それぞれの個数を求めたい.
数値例(スペースの入れ方により「その他」の数値は変わります): ・ "Japanese team as No. 1" → 長さ 22,大文字 2,小文字 14,数字 1, その他 5 ・ "May 30 (Fri), 2025" → 長さ 18,大文字 2,小文字 4,数字 6, その他 6 ・ "if( 65 <= str[i] && str[i] <= 90 )" → 長さ 34,大文字 0,小文字 10,数字 4, その他 20 ・ "if( 'a' <= str[i] && str[i] <= 'z' )" → 長さ 36,大文字 0,小文字 12,数字 0, その他 24
#include <stdio.h> #include <string.h> #define M 128 // キーボードから入力される文字列の長さの上限 void get_line( char buff[], int size ) { } int main( void ) { int len; // 文字列の長さ int upper = 0; // 大文字の個数 int lower = 0; // 小文字の個数 int numbers = 0; // 数字の個数 int others = 0; // その他の個数 char str[ M ] = ""; // キーボードから入力される文字列 printf("Enter a word >>>"); get_line( str, M ); // キーボードから文字列入力 printf("length = %d \n", len ); printf("uppercase = %d \n", upper ); printf("lowercase = %d \n", lower ); printf("numbers = %d \n", numbers ); printf("others = %d \n", others ); return 0; } |
(E8_9*) 次の手順に沿ってプログラムを作成せよ.設問(1)〜(3)がすべてできない場合でも,部分点を与える可能性があるため,
解けた問題まで提出するとよい(その場合,どの問題まで解いたかを考察欄に明記し,
その問題のプログラムを提出せよ).
(1) 下のように初期化した文字列 sentence と, キーボードから受け取った文字列 str に対し, sentence が str で始まっているかどうか (str が sentence の先頭から一致するかどうか)を判定して, その結果を表示するプログラム(設問(2)以降の都合で,ファイル名は (課題番号)_1.c とする)を作成せよ. sentence の方が str より長いと仮定してよい.
char sentence[] = "This is a pen. That is an apple."; |
(2) 同様に初期化した文字列 sentence と, キーボードから受け取った文字列 str に対し, sentence 中に str が出現するかどうかを判定して,その結果を表示するプログラム(ファイル名は (課題番号)_2.c とする)を作成せよ. sentence の方が strより長いと仮定してよい.
(3) 下のように初期化された文字列 sentence と, キーボードから受け取った文字列 str に対し, str が sentence 内に出現するかどうかを判定するプログラム(ファイル名は (課題番号)_3.c とする)を作成せよ. ただし,次の条件を満たすようにせよ.
char sentence[] = "Kwansei Gakuin University has eleven schools: \ theology, humanities, sociology, law & politics, economics, \ business administration, human welfare studies, international studies, \ education, science & technology, and policy studies. \ One of the characteristics of each school is the freshmen seminar \ organized with a small group of students. This embodies the policy of \ the small group education at university. Another practice is the \ integrated courses, which involve students taking courses outside \ their own majors. The Freshmen seminar aims for face-to-face \ communication between students and professors and the integrated \ courses aim to give students a multidimensional set of viewpoints. "; |
※ 上記の sentence の初期化コードの行末の \ は「次の行への継続」を表すので,このまま使用すればよい.
プログラム中にこれをコピーする際に, 2 行目の先頭の theology, 3 行目の先頭の business … の前にスペースや
タブを入れないこと. (文字数が狂って下の動作確認の結果が一致しなくなる.)
※「文字列の大文字と小文字を区別しない比較」は,2つの文字列中の大文字を
全て小文字に変換し, それから比較を行うのが一方法.
この場合,大文字を小文字に変換する関数 str_lcopy を作成することが考えられる.
次を確認せよ