「C言語の基礎 - 文字列」の版間の差分
255行目: | 255行目: | ||
</source> | </source> | ||
<br><br> | <br><br> | ||
== 文字列の末尾にある空白を削除する == | |||
C言語には、文字列の末尾にある空白を削除する関数やマクロは存在しないので、各自でこの機能を実装する必要がある。<br> | |||
実装は以下の手順で行うことが出来る。<br> | |||
# 文字列の末尾の位置を探す | |||
# 手順1で探した末尾から順に、空白でない位置を探す | |||
# 手順2で探した位置 + 1 に終端の'\0'を付加する | |||
<source lang="c"> | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
int TrimEnd(char *s); | |||
int main(void) | |||
{ | |||
int ret; | |||
char snoopy[] = "SNOOPY "; | |||
ret = TrimEnd(snoopy); | |||
printf("変換後: \"%s\"\n", snoopy); | |||
printf("削除した空白: %d文字\n", ret); | |||
return EXIT_SUCCESS; | |||
} | |||
/* 文字列の末尾にある空白を削除する */ | |||
/* @param[in] s 対象文字列 */ | |||
/* @return 削除した空白の数を返す */ | |||
int TrimEnd(char *s) | |||
{ | |||
int i; | |||
int count = 0; | |||
/* 空ポインタか? */ | |||
if ( s == NULL ) | |||
{ | |||
return -1; | |||
} | |||
/* 文字列長を取得する */ | |||
i = strlen(s); | |||
/* 末尾から順に空白でない位置を探す */ | |||
while ( --i >= 0 && s[i] == ' ' ) count++; | |||
/* 終端ナル文字を付加する */ | |||
s[i + 1] = '\0'; | |||
return count; | |||
} | |||
</source> | |||
<br><br> | |||
== 文字列の長さを取得する == | |||
C言語で文字列の長さを取得するには、string.hのstrlen関数を使用する。<br> | |||
strlen関数は、第1引数が指す文字列の長さを取得する関数である。なお、文字列の長さに終端'\0'は含まない。<br> | |||
<source lang="c"> | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
int main(void) | |||
{ | |||
char s[] = "スヌーピー!"; | |||
int length; | |||
length = (int)strlen(s); | |||
printf("%sの長さ: %d\n", s, length); | |||
return EXIT_SUCCESS; | |||
} | |||
</source> | |||
<br><br> | |||
== 文字列を比較する == | |||
C言語で文字列を比較するには、string.hのstrcmp関数またはstrncmp関数を使用する。<br> | |||
<br> | |||
strcmp関数は、第1引数が指す文字列と第2引数が指す文字列を比較する関数である。文字列を最初から最後まで比較したいときに使用する。<br> | |||
strncmp関数は、第1引数が指す文字列の始めの第3引数の文字数分と、第2引数が指す文字列の始めの第3引数の文字数分を比較する関数である。<br> | |||
(文字列の終端'\0'に続く文字の比較は行わない)<br> | |||
主に文字列の一部を比較したいときに使用する。<br> | |||
<br> | |||
strcmp関数とstrncmp関数は、比較する文字列が同じなら0、第1引数 > 第2引数なら正の整数、第1引数 < 第2引数なら負の整数を返す。<br> | |||
<source lang="c"> | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
int main(void) | |||
{ | |||
char s1[] = "Hoge01"; | |||
char s2[] = "Hoge02"; | |||
puts("全文字比較"); | |||
if ( strcmp(s1, s2) == 0 ) | |||
{ | |||
printf("%sと%sは同じ文字列です.\n", s1, s2); | |||
} | |||
else | |||
{ | |||
printf("%sと%sは異なる文字列です.\n", s1, s2); | |||
} | |||
puts("先頭の4文字分比較"); | |||
if ( strncmp(s1, s2, 4) == 0 ) | |||
{ | |||
printf("%sと%sは同じ文字列です.\n", s1, s2); | |||
} | |||
else | |||
{ | |||
printf("%sと%sは異なる文字列です.\n", s1, s2); | |||
} | |||
return EXIT_SUCCESS; | |||
} | |||
</source> | |||
<br><br> | |||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:C]] | [[カテゴリ:C]] |
2020年4月24日 (金) 12:10時点における版
文字列を初期化する
C言語で文字列を初期化するには、string.hのmemset関数を使用する。
memset関数は、第1引数が指すオブジェクトの先頭から第3引数の文字数分だけ、第2引数の文字列をセットする関数である。
この関数を利用すれば、文字列を指定した文字で埋めることができる。
注意
memset関数は、文字列の終端'\0'を自動的に付加しないので、'\0'以外の文字で埋める場合は、文字列の最後に終端'\0'を付加する必要がある。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 16
int main(void)
{
char s[N];
/* 文字列 s を 15 文字分 'z' で埋める. */
memset(s, 'z', N);
s[N - 1] = '\0';
printf("s: %s\n", s);
return EXIT_SUCCESS;
}
文字列をコピーする
文字列をコピーするには、string.hのstrcpy関数またはstrncpy関数を使用する。
ただし、strcpy関数はバッファオーバーフローを発生させやすい関数なので、ここでは、strncpy関数を記載する。
strncpy関数は、第2引数が指す文字列から、第1引数が指す文字列に最大で第3引数の文字数分をコピーする関数である。
なお、第2引数が指す文字列の終端'\0'に続く文字はコピーされない。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 256
int main(void)
{
char s1[N] = {'\0'};
char s2[] = "Snoopy!";
printf("-- コピー前 --\n");
printf("s1: %s\n", s1);
printf("s2: %s\n", s2);
/* s2の内容をN文字分だけs1にコピー */
strncpy(s1, s2, N);
if ( N > 0 )
{
s1[N - 1] = '\0';
}
printf("\n-- コピー後 --\n");
printf("s1: %s\n", s1);
printf("s2: %s\n", s2);
return EXIT_SUCCESS;
}
注意
strncpy関数は、第3引数の値が第2引数のサイズよりも大きい場合、第1引数に文字列をコピーした後、自動的に文字列の最後まで'\0'を付加する。
しかし、第3引数の値が第2引数のサイズよりも小さい場合、終端'\0'を付加しない。
したがって、第2引数のサイズが第3引数の値よりも大きい場合は、なんらかの対策が必要になる。
最も簡単な対策法としては、コピー後の文字列のn - 1番目の要素に'\0'をセットする方法がある。
具体的には以下のように実装する。
strncpy(s1, s2, n);
if (n > 0)
{
s1[n - 1] = '\0';
}
文字列を連結する
文字列を連結するには、string.hのstrcat関数またはstrncat関数を使用する。
ただし、strcat関数はバッファオーバーフローを発生させやすい関数なので、ここでは、strncat関数を記載する。
strncat関数は、第2引数が指す文字列から最大で第3引数の文字数分の文字列を、第1引数が指す文字列の最後に付加する。
なお、文字列の終端'\0'は自動的に付加されるので、第3引数の値が第2引数のサイズよりも小さい場合でも、手動で'\0'を付加する必要はない。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 256
int main(void)
{
char s1[] = "Snoopy";
char s2[] = "Charlie Brown";
/* 文字列の連結 */
strncat(s1, s2, 7);
printf("s1 + s2 (7文字分) : %s\n", s1);
return EXIT_SUCCESS;
}
文字列を指定文字で分割する
文字列を指定文字で分割するには、string.hのstrtok関数を使用する。
strtok関数は、第1引数が指す文字列を、第2引数が指す文字列の中のいずれかの文字で区切られる字句の列に分割する関数である。
strtok関数は、1回の呼び出しで複数の分割を行うことができない。文字列の分割は、strtok関数を呼び出すごとに1回ずつ行われる。
strtok関数の1回目の呼び出しには、第1引数に分割する対象の文字列を指定する。
2回目以降の呼び出しは、第1引数にNULLを指定することで、前回分割された場所の次から分割を開始する。
分割できる文字列がなくなると、strtok関数はNULLを返す。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char s1[] = "0055,Ichiro Suzuki,Seattle,090-9999-9999";
char *code, *name, *address, *tel, *empty;
/* 1回目の呼出し */
code = strtok(s1, ",");
/* 2回目以降の呼出し */
name = strtok(NULL, ",");
address = strtok(NULL, ",");
tel = strtok(NULL, ",");
empty = strtok(NULL, ",");
printf("code: %s\n", code);
printf("name: %s\n", name);
printf("address: %s\n", address);
printf("tel: %s\n", tel);
printf("empty: %s\n", empty);
return EXIT_SUCCESS;
}
文字列の先頭と末尾にある空白を削除する
C言語には、文字列の先頭と末尾にある空白を削除する関数やマクロは存在しない。
したがって、各自でこの機能を実装する必要がある。
実装は以下の手順で行うことが出来る。
- 文字列の末尾の位置を探す
- 手順 1 で探した末尾から順に,空白でない位置を探す
- 手順 2 で探した位置 + 1 に終端の '\0' を付加する
- 文字列の先頭から順番に空白でない位置を探す
- 手順 4 で探した位置から末尾まで文字列をコピーする
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int Trim(char *s);
int main(void)
{
int ret;
char snoopy[] = " SNOOPY ";
ret = Trim(snoopy);
printf("変換後: \"%s\"\n", snoopy);
printf("削除した空白: %d文字\n", ret);
return EXIT_SUCCESS;
}
/* 文字列の先頭と末尾にある空白を削除する */
/* @param[in] s 対象文字列 */
/* @return 削除した空白の数を返す */
int Trim(char *s)
{
int i;
int count = 0;
/* 空ポインタか? */
if ( s == NULL )
{
return -1;
}
/* 文字列長を取得する */
i = strlen(s);
/* 末尾から順に空白でない位置を探す */
while ( --i >= 0 && s[i] == ' ' ) count++;
/* 終端ナル文字を付加する */
s[i+1] = '\0';
/* 先頭から順に空白でない位置を探す */
i = 0;
while ( s[i] != '\0' && s[i] == ' ' ) i++;
strcpy(s, &s[i]);
return i + count;
}
文字列の先頭にある空白を削除する
C言語には、文字列の先頭にある空白を削除する関数やマクロは存在しないので、各自でこの機能を実装する必要がある。
実装は以下の手順で行うことが出来る。
- 文字列の先頭から順番に空白でない位置を探す
- 手順 1 で探した位置から末尾まで文字列をコピーする
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int TrimStart(char *s);
int main(void)
{
int ret;
char snoopy[] = " SNOOPY";
ret = TrimStart(snoopy);
printf("変換後: \"%s\"\n", snoopy);
printf("削除した空白: %d文字\n", ret);
return EXIT_SUCCESS;
}
/* 文字列の先頭にある空白を削除する */
/* @param [in] s 対象文字列 */
/* @return 削除した空白の数を返す */
int TrimStart(char *s)
{
int i = 0;
/* 空ポインタか? */
if ( s == NULL )
{
return -1;
}
/* 先頭から順に空白でない位置を探す */
while ( s[i] != '\0' && s[i] == ' ' ) i++;
strcpy(s, &s[i]);
return i;
}
文字列の末尾にある空白を削除する
C言語には、文字列の末尾にある空白を削除する関数やマクロは存在しないので、各自でこの機能を実装する必要がある。
実装は以下の手順で行うことが出来る。
- 文字列の末尾の位置を探す
- 手順1で探した末尾から順に、空白でない位置を探す
- 手順2で探した位置 + 1 に終端の'\0'を付加する
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int TrimEnd(char *s);
int main(void)
{
int ret;
char snoopy[] = "SNOOPY ";
ret = TrimEnd(snoopy);
printf("変換後: \"%s\"\n", snoopy);
printf("削除した空白: %d文字\n", ret);
return EXIT_SUCCESS;
}
/* 文字列の末尾にある空白を削除する */
/* @param[in] s 対象文字列 */
/* @return 削除した空白の数を返す */
int TrimEnd(char *s)
{
int i;
int count = 0;
/* 空ポインタか? */
if ( s == NULL )
{
return -1;
}
/* 文字列長を取得する */
i = strlen(s);
/* 末尾から順に空白でない位置を探す */
while ( --i >= 0 && s[i] == ' ' ) count++;
/* 終端ナル文字を付加する */
s[i + 1] = '\0';
return count;
}
文字列の長さを取得する
C言語で文字列の長さを取得するには、string.hのstrlen関数を使用する。
strlen関数は、第1引数が指す文字列の長さを取得する関数である。なお、文字列の長さに終端'\0'は含まない。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char s[] = "スヌーピー!";
int length;
length = (int)strlen(s);
printf("%sの長さ: %d\n", s, length);
return EXIT_SUCCESS;
}
文字列を比較する
C言語で文字列を比較するには、string.hのstrcmp関数またはstrncmp関数を使用する。
strcmp関数は、第1引数が指す文字列と第2引数が指す文字列を比較する関数である。文字列を最初から最後まで比較したいときに使用する。
strncmp関数は、第1引数が指す文字列の始めの第3引数の文字数分と、第2引数が指す文字列の始めの第3引数の文字数分を比較する関数である。
(文字列の終端'\0'に続く文字の比較は行わない)
主に文字列の一部を比較したいときに使用する。
strcmp関数とstrncmp関数は、比較する文字列が同じなら0、第1引数 > 第2引数なら正の整数、第1引数 < 第2引数なら負の整数を返す。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char s1[] = "Hoge01";
char s2[] = "Hoge02";
puts("全文字比較");
if ( strcmp(s1, s2) == 0 )
{
printf("%sと%sは同じ文字列です.\n", s1, s2);
}
else
{
printf("%sと%sは異なる文字列です.\n", s1, s2);
}
puts("先頭の4文字分比較");
if ( strncmp(s1, s2, 4) == 0 )
{
printf("%sと%sは同じ文字列です.\n", s1, s2);
}
else
{
printf("%sと%sは異なる文字列です.\n", s1, s2);
}
return EXIT_SUCCESS;
}