配列について

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

配列について

#1

投稿記事 by KI » 9年前

文字列とコピーしたい文字数を入力して、文字列の指定された文字数だけ後ろから出力させたいのですが、
ポインタと組み合わせると全く分からなくなってしまいます。
お手伝いお願いします。

コード:

#include<stdio.h>
#define N 100

int back(char *str1, int n, char *str2);

int main(void)
{
	char a[N], b[N];
	int n,m;

	printf("文字列を入力:");
	scanf("%s", a);

	printf("\n表示したい文字数:");
	scanf("%d", m);

	m = back(a, n, b);

	printf("文字数:%d", m);
	printf("%s", b);
}

int back(char *str1, int n, char *str2)
{
	int i, j;



}

box
記事: 2002
登録日時: 14年前

Re: 配列について

#2

投稿記事 by box » 9年前

こういうことがしたいのかな?

コード:

#include <stdio.h>
#include <string.h>

#define N (100)

void back(char *str1, int n, char *str2);

int main(void)
{
    char a[N], b[N];
    int n, m;

    printf("文字列を入力:");
    scanf("%s", a);

    do {
        printf("文字数:");
        scanf("%d", &n);
    } while (0 > n || n > strlen(a));

    back(a, n, b);
    printf("%s\n", b);
}

void back(char *str1, int n, char *str2)
{
    int i;

    for (i = 0; i < n; i++) {
        str2[i] = str1[strlen(str1) - 1 - i];
    }
    str2[i] = '\0';
}
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

KI

Re: 配列について

#3

投稿記事 by KI » 9年前

はい!
ありがとうございます。
29~32行目の部分を説明をお願いしてもいいですか?

box
記事: 2002
登録日時: 14年前

Re: 配列について

#4

投稿記事 by box » 9年前

コード:

void back(char *str1, int n, char *str2)
{
    int i;
 
    for (i = 0; i < n; i++) {
        str2[i] = str1[strlen(str1) - 1 - i];
    }
    str2[i] = '\0';
}
具体的な例で説明する方がわかりやすいと思います。
まず、back関数の仕様は、第1引数str1の後ろの方から第2引数n文字分だけ取ってきて
第3引数str2に格納する、というものです。

例えば、str1が"abcdefg"で、nが3だとします。このとき、str2に入ってほしいのは"gfe"ですね。
str2には3文字分(=n文字分)だけ入ってほしいので、ループを3回(=n回)回します。これが、
29行目(すぐ上のコードでは5行目)の意味です。

さて、back関数の肝は30行目(すぐ上のコードでは6行目)にあります。
ここで、str1の長さは7であることを覚えておいてください。
str1とnを用いてstr2にどういう風に格納しているかというと、
 ・str2[0]には、str1[6]であるところの'g'を格納する
 ・str2[1]には、str1[5]であるところの'f'を格納する
 ・str2[2]には、str1[4]であるところの'e'を格納する
ということを行なっています。

格納先の[0]には元の文字列の[6]を格納
格納先の[1]には元の文字列の[5]を格納
格納先の[2]には元の文字列の[4]を格納
という規則で動いています。
ここで、[0]と[6]、[1]と[5]、[2]と[4]という組合せについて、何か規則性を見いだせないでしょうか。
いずれの場合も、加えると6になっていて、6というのは元の文字列の長さである7より1だけ小さいのです。

上記を一般化すると、
格納先のには元の文字列の[元の文字列の長さ - 1 - i]を格納
ということになり、これをC言語で書いたのが30行目(すぐ上のコードでは6行目)です。

for文のループを抜けたときのiの値はnに等しく、3になっています。
str2[0]~str2[2]には正しい結果が入っていますので、str2を文字列として
正しく終端させるためにstr2[3]に'\0'を格納します。これが32行目(すぐ上のコードでは8行目)です。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

かずま

Re: 配列について

#5

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

別解です。

コード:

void back(char *str1, int n, char *str2)
{
    int i, j = strlen(str1);
 
    for (i = 0; i < n; i++) str2[i] = str1[--j];
    str2[i] = '\0';
}

閉鎖

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