文字列を連結させたい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
KTN19
記事: 23
登録日時: 9年前

文字列を連結させたい

#1

投稿記事 by KTN19 » 9年前

文字列の入力したものをスペースの空白を用いて入力した文字を複写して,それを5回繰り返したものを出力したいのですが,わからなくなってしまいました.
どうかご教授よろしくお願いします.

コード:

#include<stdio.h>
#include<string.h>
#define N 100


void get_line( char s[], int size );
void str_cat( char s[], char t[] );

int main( void )
{
	char s_in[ N ];
	char s_out[ N+N ];
	int i, len;
	
	printf( "入力せよ>>" );
	
	get_line( s_in, N );
	printf( "%s\n", s_in );
	
	strcpy( s_in, s_out );
	
	for( i = 0; i < N - 1; i++ ){
		str_cat( s_out, " " );
		strcat( s_out, s_in );
	}
	s_out[ i ] ='\0';
	
	len = strlen( s_out );
	printf( "%d %s", len, s_out );
	
}

void get_line( char s[], int size )
{
	int i, c;
	
	for( i = 0; i < size - 1; i++ ){
		c = getchar();
		if( c == EOF || c == '\n' ) break;
		s[ i ] = c;
	}
	s [ i ] = '\0';
}

void str_cat( char s[], char t[] )
{
	int i, j;
	
	for( i = 0; s[ i ] != '\0'; i++ ){ ; }
	for( j = 0; t[ j ] != '\0'; j++, i++ ){
		s[ i ] =t[ j ];
	}
	s[ i ] = '\0';
}
	

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 文字列を連結させたい

#2

投稿記事 by みけCAT » 9年前

  • 未初期化の自動変数の値を読み取ってはいけません。
  • strcat関数が使えるなら、わざわざ自前でstr_cat関数を用意する必要は無いでしょう。
  • これだと99回繰り返す処理になるかもしれません。
  • 変な所で文字列を終端する処理は蛇足です。
  • 5回、もしくは99回繰り返すのに、2個文の領域しか確保しないとバッファオーバーランのリスクが高まります。

コード:

#include<stdio.h>
#include<string.h>
#define N 100
/* 繰り返す回数の定義を追加 */
#define REPEAT_NUM 5


void get_line( char s[], int size );
/* str_catのプロトタイプ宣言を削除 */

int main( void )
{
	char s_in[ N ];
	char s_out[ (N + 1) * REPEAT_NUM ]; /* スペースの分も含めて十分な領域を確保 */
	int i, len;
	
	printf( "入力せよ>>" );
	
	get_line( s_in, N );
	printf( "%s\n", s_in );
	
	strcpy( s_out, s_in ); /* s_inのデータをs_outにコピーするように修正 */
	
	/* 条件式を修正 */
	/* for( i = 0; i < REPEAT_NUM - 1; i++ ){ でもよいが、この方が最初の1回を飛ばしていることがわかりやすそう */
	for( i = 1; i < REPEAT_NUM; i++ ){
		strcat( s_out, " " ); /* str_catの代わりにstrcatを使用 */
		strcat( s_out, s_in );
	}
	/* 文字列を無駄に切るかもしれない処理を削除 */
	
	len = strlen( s_out );
	printf( "%d %s", len, s_out );
	
	return 0; /* 明示的に戻り値を書いたほうがわかりやすい */
}

void get_line( char s[], int size )
{
	int i, c;
	
	for( i = 0; i < size - 1; i++ ){
		c = getchar();
		if( c == EOF || c == '\n' ) break;
		s[ i ] = c;
	}
	s [ i ] = '\0';
}

/* str_cat関数を削除 */
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

KTN19
記事: 23
登録日時: 9年前

Re: 文字列を連結させたい

#3

投稿記事 by KTN19 » 9年前

ご指摘ありがとうございます。
確かに99回ループさせる処理に意味はないですね。(苦笑

コード:

int main( void )
{
	char s_in[ N ];
	char s_out[ ( N+1 )*REPEAT ];
	int i, len;
	
	printf( "入力せよ>>" );
	
	get_line( s_in, N );
	printf( "%s\n", s_in );
	
	strcpy( s_out, s_in );
	
	for( i = 1; i < REPEAT; i++ ){
		strcat( s_out, " " );
		strcat( s_out, s_in );
	}
	
	len = strlen( s_out );
	printf( "%d %s", len, s_out );
	
	return 0;
}


かずま

Re: 文字列を連結させたい

#4

投稿記事 by かずま » 9年前

s_out のサイズは、N * REPEAT で十分でしょう。
strcat より strcpyのほうが効率が良いので、次のようにしてみました。

コード:

int main( void )
{
    char s_in[ N ];
    char s_out[ N * REPEAT ];
    int i, j, len;
    
    printf( "入力せよ>>" );
    
    get_line( s_in, N );
    printf( "%s\n", s_in );
    
    len = strlen( s_in );
    strcpy( s_out, s_in ), j = len;

    for( i = 1; i < REPEAT; i++ ){
        s_out[j++] = ' ';
        strcpy( s_out + j, s_in ), j += len;
    }
    
    printf( "%d %s", j, s_out );
    
    return 0;
}

閉鎖

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