文字列について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
困ったさん

文字列について

#1

投稿記事 by 困ったさん » 17年前

二つの文字列s1,s2 をキーボードから入力し,それぞれの文字列の長さ(NULL 文字は含まな
い)を画面表示し,さらに文字列s1 の後ろに文字列s2 を連結して画面表示する
(ただし,文字列s1 と文字列s2 を連結したものを一度文字列s1 に格納してから
表示を行うこと.)っていうプログラムの作成が課題で出たんですけど
strlen(),strcat()等の関数が使えなくて・・・。
文字列の長さにstrlenが使えないし、文字列を連結するのにもstrcatが使えないなんて・・・(汗)
どうしたらいいんですか?

管理人

Re:文字列について

#2

投稿記事 by 管理人 » 17年前

使えないというのは、使ってはいけないとされているんですか?

困ったさん

Re:文字列について

#3

投稿記事 by 困ったさん » 17年前

一応今回の課題では使わずにプログラムしなきゃならないみたいです。

GPGA

Re:文字列について

#4

投稿記事 by GPGA » 17年前

関数を作ってしまうのが普通ですね。
int _strlen(const char* str)
{
	int i;
	for (i = 0; *str != '\0'; i++) {
		str++;
	}
	return i;
}

char* _strcat(char* str1, const char* str2)
{
	char* tmp = str1;
	int i;
	for (i = 0; *str1 != '\0'; i++) {
		str1++;
	}
	for (i = 0; *str2 != '\0'; i++) {
		*str1 = *str2;
		str1++;
		str2++;
	}
	*str1 = '\0';

	return tmp;
}

box

Re:文字列について

#5

投稿記事 by box » 17年前

サンプルです。
#include <stdio.h>

#define BUFLEN (512)

int main(void)
{
	char s1[BUFLEN], s2[BUFLEN];
	int len1, len2, i;
	
	printf("文字列s1:"), scanf("%s", s1);
	printf("文字列s2:"), scanf("%s", s2);
	
	for (len1 = 0; s1[len1] != '\0'; len1++)
		;
	for (len2 = 0; s2[len2] != '\0'; len2++)
		;
	printf("s1の長さ=%d, s2の長さ=%d\n", len1, len2);
	
	for (i = len1; i < len1 + len2; i++)
		s1 = s2[i-len1];
	s1 = '\0';
	printf("連結後のs1='%s'\n", s1);
	return 0;
}

困ったさん

Re:文字列について

#6

投稿記事 by 困ったさん » 17年前

すいませんboxさん。BUFLENっていうのはなんですか?

box

Re:文字列について

#7

投稿記事 by box » 17年前

BUFLENは、結合後の文字列s1を格納するのに十分な大きさを表わす値です。
サンプルでは、文字列終端の'\0'を含めて512バイトまで対応している、ということです。

困ったさん

Re:文字列について

#8

投稿記事 by 困ったさん » 17年前

なるほど・・・初めて見ました(笑)
勉強になります。

管理人

Re:文字列について

#9

投稿記事 by 管理人 » 17年前

では、私は違った方向で・・ってやってること一緒ですが
#include <stdio.h>

int main(){
	int i=0,j=0;
	char s1[512],s2[512];
	
	printf("1つ目の文字列入力 ->\n") , scanf("%s",s1);
	printf("2つ目の文字列入力 ->\n") ,	scanf("%s",s2);

	printf("1: %s\n"  ,s1);
	printf("2: %s\n\n",s2);

	while(s1!='\0')
		i++;

	while((s1[i+j]=s2[j]) != '\0')
		j++;

	printf("連結: %s\n",s1);

	return 0;
}


文字列の長さがわからなくても、\0が出てくるまでカウントアップしてやればわかります。
最初のループの部分ですね。

次のループはs1は先ほど\0だったところをスタート地点にして、s2は最初をスタート地点にして代入をおこないます。
代入されたものが\0ではなかったらjをカウントアップして次々に代入していきます。

keichan

Re:文字列について

#10

投稿記事 by keichan » 17年前

>strlen(),strcat()等の関数が使えなくて・・・。
ではこれならいいですか?
#include <stdio.h>

int main()
{
    char s1[512], s2[512];
    scanf("%s", s1);
    scanf("%s", s2);
    sprintf(s1, "%s%s", s1, s2);
    printf("%s\n", s1);
    return 0;
}

管理人

Re:文字列について

#11

投稿記事 by 管理人 » 17年前

おぉ、なるほど。

先生がさせようとしていることを賢くうまく外して見せるのも
やらしくて面白いですねw

box

Re:文字列について

#12

投稿記事 by box » 17年前

入力した文字列の長さを表示する、
という仕様をお忘れでは?

管理人

Re:文字列について

#13

投稿記事 by 管理人 » 17年前

あぁ、長さの調査がいるんですねm(_ _)m

困ったさん

Re:文字列について

#14

投稿記事 by 困ったさん » 17年前

管理人さんへ

> char s1[512],s2[512];

もし[/url]に512みたいな具体的な数値がなかったらどうなりますか?

> printf("1つ目の文字列入力 ->\n") , scanf("%s",s1);
> printf("2つ目の文字列入力 ->\n") , scanf("%s",s2);


printf("1つ目の文字列入力 ->\n");
scanf("%s",s1);
printf("2つ目の文字列入力 ->\n");
scanf("%s",s2);

と同等の意味なんですか?どちらの書き方でもOKですか?
2つともバカみたいな質問でごめんなさい。

管理人

Re:文字列について

#15

投稿記事 by 管理人 » 17年前

>> char s1[512],s2[512];

>もし[/url]に512みたいな具体的な数値がなかったらどうなりますか?

[512]という数字は「配列の要素数」と呼ばれ、配列の要素をいくつ作るか示すものです。
宣言の時にはいくつ生成するか決めているので、具体的な数字を書いてやらないと、
コンパイラはいくつ配列要素を作ればいいかわからず、エラーを吐き出してしまいます。

しかし、省略できる時もあります。

char s1[/url]="省略可能なkakikata..";

このように宣言と同時に格納する文字を示してやれば、いくつ用意すればいいのか
わかりますのでエラーになりません。
こうすると、全角文字が5つ、半角文字が10文字あるから、配列要素は20個必要です。
文字列は最後に終端記号である\0を入れる必要がありますから、
合計21個配列要素が必要だとわかりますね。

つまり宣言と同時に初期化しないときには、配列要素数の省略は不可。
同時に初期化するなら省略は可能ということです。

後、コンマについてですが、
①,②,③
と書けば、①から順番に③まで処理をしろといういみなので、
普通にたてに書いても同じです。
2つの値を交換する時など、1行の処理が少ない時や、
短く書きたい時によく使用します。

>2つともバカみたいな質問でごめんなさい。

全然そんなことないので、少しでも疑問があれば、何でも聞いてくださいね。

box

Re:文字列について

#16

投稿記事 by box » 17年前

> 先生がさせようとしていることを賢くうまく外して見せるのも

文字列の連結は、keichanさんがお書きになった
sprintf関数を使う方法が最良です。

標準関数のstrcatを使う場合、下手なコーディングをすると
strcatの連鎖地獄に陥ってしまいます。

しかし、sprintf関数を使えば、
sprintf(dest, "%s%s%s", src1, src2, src3);
のように、おそらく誰が見てもスッキリしたコードとなります。
コードがスッキリしている分、テストや保守が楽です。

困ったさん

Re:質問

#17

投稿記事 by 困ったさん » 17年前

いろいろと細かい所も質問できたおかげで理解が深まりました。
みなさんご指導ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る