cp-12. 文字列
C プログラミング入門
URL: https://www.kkaneko.jp/pro/adp/index.html
1
金子邦彦
C言語における文字列の基本的な扱い方、文字配列としての文字
列操作と標準ライブラリ関数の活用
学習内容の構成
1. 文字列の基礎:文字の配列として文字列を宣言・入出力する
方法、文字列末尾の特別な文字(¥0)の役割
2. ライブラリ関数strlen(長さ取得)、strcpy(コピー)、
strcat(連結)、strcmp(比較)、strstr(検索)の使用法
3. 文字列とメモリ:文字列のメモリアドレス、配列名が先頭ア
ドレスを表す仕組み
4. 関数への受け渡し:文字列を引数として関数に渡す方法
char*によるポインタ渡し)
5. 文字列の配列:二次元配列による複数文字列の管理(曜日表
示の例)
前提:C言語の配列、関数、入出力の基礎知識
意義:文字データ処理の基本技術の習得、実用的なプログラム
作成能力の獲得
2
文字列とは
数字,文字,記号の列
文字列データを扱うための最も簡単な方法は
文字の配列を使う方法である.
3
目標
文字列を扱うような簡単な関数を理解し,自分
で書けるようになる
4
例題1.文字列と長さの表示
文字列を読み込んで,長さを表示するプログ
ラムを作る.
例) "Computer" の長さは
"高度プログラミング演習" の長さは
22
ここでの文字列は,半角の「空白文字」を含まな
いものとする
半角文字は1,全角文字は2として数える
5
#include <stdio.h>
#include <string.h>
#pragma warning(disable:4996)
int main()
{
char x[100];
int len;
printf("string=");
scanf("%s", x);
len = strlen(x);
printf("strlen(%s) = %d¥n", x, len);
return 0;
}
文字列を格納するための配列の宣言
(char」とあるのは「文字」という意味
文字列データの読み込み
%s」は文字列の意味.「x」は,配列
の先頭要素のメモリアドレスの意味
文字列の長さを求める
文字列データと長さの表示.
%s」は文字列の意味
6
文字列と長さの表示
string=Computer
strlen(Computer) = 8
実行結果の例(1)
string=高度プログラミング演習
strlen(高度プログラミング演習) = 22
実行結果の例(2)
7
プログラム実行順
printf("string=");
scanf("%s", x);
len = strlen(x);
printf("strlen(%s) = %d¥n", x, len);
return 0;
メッセージ「string=」を表示
(出力文)
文字列データを読み込み
(入力文)
文字列の長さを計算
文字列及びその長さを表
(出力文)
終わり
8
プログラムとデータ
メモリ
scanf("%s", x);
文字列データを
読み込み
x[0]
x[1]
x[2]
x[3]
x[4]
len = strlen(x);
文字列の長さを計算
x[5]
x[6]
x[7]
C
o
m
p
u
t
e
r
¥0x[8]
「文字列の末尾」を
表す特別な文字
scanf の実行で,自
動的にセットされる)
printf("strlen(%s) = %d¥n", x, len);
文字列の長さを計算
9
文字列の宣言
文字列データを扱うための最も簡単な方法は,
文字の配列を使う方法である.
配列には,名前サイズがある
配列を使うために,配列の使用をコンピュータに
伝えること(宣言)が必要
char x[100];
文字
データ
名前
x
配列のサイズ
は100
10
文字列用の配列のサイズ
配列の添字は0から(サイズー1)
例) char x[100]; と宣言したら,
サイズは100,添字は0から99
実際に使えるのは,0から(サイ
ズー2)まで
例) char x[100]; と宣言したら,
実際に使えるのは,0から98まで
(最大99文字まで入る)
「文字列の末尾」を表す特別な文字を
入れるのに,1つ使われる
添字
99
11
文字列の入力文
書式」と読み込むべき変数名を書く
文字列の場合,変数名の前には「」を付けない
scanf("%s", x);
書式 読み込むべき変数名
12
文字列の出力文
書式」と表示すべき変数名を書く
printf("strlen(%s) = %d¥n", x, len);
書式
表示すべき変数名
13
課題1.文字列の逆転
半角文字からなる文字列を読み込んで,逆転
した文字列をつなげて,回文を作り,それを
表示するプログラムを作りなさい.
例)読み込んだ文字列
回文
ここでの文字列は,半角の「空白文字」を含まな
いものとする
「文字列の末尾」を
表す特別な文字
scanf の実行で,自
動的にセットされる
C o m p u t e r ¥0
C o m p u t e r r e t u p m o C ¥0
14
課題1のヒント
添字を付けて,文字単位での読み書きを行う.
例) 1文字目に,5文字目の文字をコピー
x[0]=x[4];
回文を作るときに,文字列の末尾(¥0)をセッ
トすることを忘れない
例) 要素 x[10] 「文字列の末尾」
をセット
x[10]='¥0';
15
例題2.文字列のコピー
文字列を読み込んで,文字列のコピーを行う
プログラムを作る
16
例題2.文字列のコピー
#include <stdio.h>
#include <string.h>
#pragma warning(disable:4996)
int main()
{
char s1[80], s2[80];
printf("s1=");
scanf("%s", s1);
strcpy(s2, s1);
printf("s1=%s, s2=%s¥n",s1,s2);
return 0;
}
17
文字列のコピー
s1=test
s1=test, s2=test
実行結果の例(1)
s1=あいうえお
s1=あいうえ, s2=あいうえお
実行結果の例(2)
18
例題3.文字列の連結
2つの文字列を読み込んで,文字列の連結を
行うプログラムを作る
19
例題3.文字列の連結
#include <stdio.h>
#include <string.h>
#pragma warning(disable:4996)
int main()
{
char s1[80], s2[80];
printf("s1=");
scanf("%s", s1);
printf("s2=");
scanf("%s", s2);
strcat(s1, s2);
printf("s1=%s, s2=%s¥n", s1, s2);
return 0;
}
20
文字列の連結
s1=abc
s2=def
s1=abcdef, s2=def
実行結果の例(1)
s1=あい
s2=うえお
s1=あいうえお, s2=うえお
実行結果の例(2)
21
例題4.文字列の比較
2つの文字列を読み込んで,文字列の比較を
行うプログラムを作る
22
#include <stdio.h>
#include <string.h>
#pragma warning(disable:4996)
int main()
{
char s1[80], s2[80];
int n;
printf("s1=");
scanf("%s", s1);
printf("s2=");
scanf("%s", s2);
n = strcmp(s1, s2);
if ( n < 0 ) {
printf( "%s<%s¥n", s1, s2 );
}
else if ( n == 0 ) {
printf( "%s==%s¥n", s1, s2 );
}
else if ( n > 0 ) {
printf( "%s>%s¥n", s1, s2 );
}
return 0;
}
23
文字列の比較
s1=configure
s2=control
configure<control
実行結果の例(1)
s1=happy
s2=angry
happy>angry
実行結果の例(2)
s1=give
s2=give
give==give
実行結果の例(3)
24
例題5.文字列の検索
¥を含むファイル名を,文字列として読み込
んで,最後の¥以降の部分を表示するプログ
ラムを作る.
¥を含まない場合には,そのまま表示すること
25
文字列の検索
#include <stdio.h>
#include <string.h>
#pragma warning(disable:4996)
int main()
{
char name[80], base[80];
char *p, *search;
printf("name=");
scanf("%s", name);
search = name;
while( ( p = strstr(search, "¥¥") ) != NULL ) {
search = p + 1;
}
strcpy( base, search );
printf("name=%s, base=%s¥n", name, base);
return 0;
}
NULLの意味
strstr関数では,検索
文字列が見つからない
ことを意味する
26
文字列の検索
name=a:¥test¥file.txt
name=a:¥test¥file.txt, base=file.txt
実行結果の例
27
文字列用のライブラリ関数
文字列用のライブラリ関数を使うときには,次の
1行をプログラムに含めること
#include <string.h>
コピー strcpy
長さ取得 strlen
連結 strcat
比較 strcmp
検索 strstr
など
28
例題6.文字列のメモリアドレ
文字列から,各文字のメモリアドレスを表示
する関数を作る
29
#include <stdio.h>
#include <string.h>
#pragma warning(disable:4996)
void printstring( char* s )
{
int i;
for (i=0; i<strlen(s); i++) {
printf("address(%c) = %p¥n", s[i], &s[i]);
}
return;
}
int main()
{
char x[100];
printf("string=");
scanf("%s", x);
printstring(x);
return 0;
}
&」はメモリアドレス
の取得
%p」はメモリアドレス
の表示
s[i]」は i 番目の文字
という意味
%c」は1文字の表示
30
関数呼び出しの流れ
printstring 関数
void printstring( char* s )
main 関数
int main()
printstring(x);
関数呼び出し
return
戻り
31
文字列のメモリアドレス
実行結果の例
address(C) = ffbef440
address(o) = ffbef441
address(m) = ffbef442
address(p) = ffbef443
address(u) = ffbef444
address(t) = ffbef445
address(e) = ffbef446
address(r) = ffbef447
表示された
メモリアドレス
32
プログラムとデータ
メモリ
x[0]
x[1]
x[2]
x[3]
x[4]
x[5]
x[6]
x[7]
C
o
m
p
u
t
e
r
¥0x[8]
「文字列の末尾」を
表す特別な文字
scanf の実行で,自
動的にセットされる)
ffbef440
ffbef441
ffbef442
ffbef443
ffbef444
ffbef445
ffbef446
ffbef447
33
関数への文字列の受け渡し
呼び出し側
変数名を書いて,文字列(文字列を格納した配
列)の先頭メモリアドレスを,関数に渡す
例) printstring( x );
関数側
文字列を受け取る(つまり,文字列の先頭メモリ
アドレス)ことを宣言しておく
void printstring( char* s )
文字列 x の先頭メモリアドレス
&x[0] の省略形)
「文字列の先頭メモリアドレス」
を受け取って,s として使うという意味.
34
文字列とポインタ
プログラム中に文字列の名前(つまり,文字列を格納し
た配列名を単独で書くと,文字列の先頭メモリアドレス
という意味
プログラム例: printstring(s);
s
s[0]
s[1] s[2] s[3]
s[4]
s[5] s[6]
文字列の先頭
35
課題2.文字列を扱う関数
3つの文字列を受け取って,辞書順に表示す
る関数を作成しなさい.同時に,この関数を
使う main 関数を作成し,正しく動作するこ
とを確認すること.
strcmp 関数を使用すること
36
例題7.曜日の表示
数字を読み込んで,曜日を表示するプログラムを
作成する
Sun
Mon
Tue
Wed
Thr
Fri
Sat
37
曜日の表示
#include <stdio.h>
#pragma warning(disable:4996)
void print_youbi( int youbi )
{
char x[7][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri",
"Sat" };
printf( "%s¥n", x[youbi]);
return;
}
int main()
{
int n;
printf("youbi=");
scanf("%d", &n);
print_youbi( n );
return 0;
}
38
曜日の表示
youbi=3
Wed
実行結果の例
youbi=0
Sun
実行結果の例(2)
39
関数呼び出しの流れ
print_youbi 関数
void print_youbi( int youbi )
main 関数
int main()
print_youbi(n);
関数呼び出し
return
戻り
40
プログラムとデータ
メモリ
printf( "%s", x[youbi]);
S
M
T
W
T
F
S
u
o
u
e
h
r
a
n
n
e
d
u
i
t
¥0
¥0
¥0
¥0
¥0
¥0
¥0
41
課題3.小数部分の抜き出し
「小数付きの数」を読み込んで,小数部分のみを
抜き出して表示するプログラムを作りなさい.
例) 18.256” の小数部分は 256
「小数付きの数」を文字列データとして読み込むこと
42