重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

C言語のプログラム作成で全然分からなくて非常に困っています。
そのため教えていただきたく思います。

目的は、
文字列 str="aaa\nbbb\nccc\n"
を \n で区切って配列に入れたいです。
文字列は不定長さで str="aa\n" や str="aaa\nbb\nc\nddd\neee\n" などです。
必ず\nで区切られています。

それらを配列に入れて
hairetu[0] = "aaa\n"
hairetu[1] = "bbb\n"
hairetu[2] = "ccc\n"
・・・
という結果を得たいです。

自分でまったく分からないところは、
配列の要素にアドレスを入れること、
文字列strの長さが固定でないため配列の要素をどのように増やすか、
です。

どなたか助けていただけないでしょうか。
直接回答を教えていただけたらすごく助かります。
参考のページや考え方を教えていただいてもありがたいです。
よろしくお願いします。

A 回答 (4件)

期待する結果を得るには文字列のコピーが不可欠になります。


こんな感じでしょうか...

   size_t n = 0;
   const char *ss = str;
   while (*ss != '\0')
   {
     ss = strchr(ss, '\n');
     if (ss != NULL)
     {
        ++ss;
        ++n;
     }
   }

   char *hairetu[n];
   const char *s1 = str;
   for (size_t i = 0; i < n; i++)
   {
     const char *s2 = strchr(s1, '\n');
     if (s2 != NULL)
     {
        ++s2;
        size_t length = s2 - s1;
        hairetu[i] = malloc(length + 1);
        memcpy(hairetu[i], s1, length);
        hairetu[i][length] = '\0';
        s1 = s2;
     }
   }

本質ではない部分は省略していますので、自分で補ってください。
    • good
    • 0

// 文字列、配列の要素数は変更しやすいように


// #define 文で与えています。
// malloc()を使って必要分だけ割り当てる方法もありますが、
// 先ず、要素数固定で動かしてみてトークン(語句)分割を理解されたほうがよいでしょう。

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

#define STRLEN 100 // 文字列の最大長
#define NTOKEN 100 // トークン(語句)の最大個数
#define TOKENLEN 5 // トークン(語句)の最大長+1

int main( int argc, char *argv[] )
{
char str[STRLEN];
char delim[] = "\n"; // 区切り文字
char *tok; // トークン(語句)切り出し作業用
char hairetu[NTOKEN][TOKENLEN]; // トークン(語句)保存用
int i, count; // トークンの個数

// strにテスト用の文字列をコピーする。
// 実用的にはファイルから読み込むなどの処理を記述する。
strcpy(str, "aaa\nbbb\nccc\nddd\n");

i = 0;
tok = strtok(str, delim);
while(tok != NULL) {
// strに語句がある間繰り返す
strcpy(hairetu[i], tok);
i ++;
// 次のトークンへのポインタを取得
tok = strtok(NULL, delim);
}

// トークンの個数を保存
count = i;

// 確認用出力
for(i=0; i<count; i++){
printf("hairetu[%d]=%s\n", i, hairetu[i]);
}

return 0;
}


/*
出力
hairetu[0]=aaa
hairetu[1]=bbb
hairetu[2]=ccc
hairetu[3]=ddd
*/
    • good
    • 0

まず、用語を整理しましょう。

いろんな言葉が混っていて、実際になにがやりたいか正確に把握できません。

「配列にポインタを入れたい 」「配列の要素にアドレスを入れること」を文面通りに受け取るなら
XXX * a[SIZE];
などと「XXX型へのポインタ」の配列 a を宣言して、 a[0],a[1],...をそれぞれポインタ変数とし使う、ということになります。
文字列ということなので
char *hairetu[SIZE] ;
hairetu[0] = &(str[0]);
hairetu[1] = &(str[3]);
...
とすれば、「配列にアドレス」は入ります。

ただ、これは、あなたの求めているものでは無い、と思います。

○不定な長さの配列の準備
方法1:あらかじめ、「十分に大きな配列を用意しておく」
今回のなら
char hairetu[100][1000]とか。(1000-1文字までの文字列が100個)
みたいに。ただ、あまり大きすぎると領域確保に失敗するし、小さいと足りません。

方法2: mallocを使って動的に確保す。
詳細はここでは説明しませんが、Cでの基本テクニックです。検索するなり本を読むなりして理解して使ってください。

○文字列のコピー
基本は「1文字ずつコピー」です。\0が足りなければ追加します。
strcpyやstrncpyを使う方法もありますが。

アドレスだけだと、strの中身が変ってしまうとコピーしたつもりのhairetuも変わってしまいます
    • good
    • 0

1. strを先頭から末尾まで一度走査して、\nの数を数える。

その数をnとする。
2. char **hairetu=(char**)malloc(sizeof(char*)*n);でメモリを確保する。
3. strの中のi番目の文字列(i=0~n-1)について、その長さ(\nを含む)を調べる。その数をlとする。
4. hairetu[i]=(char*)malloc(sizeof(char)*(l+1));でメモリを確保する。
5. strの中のi番目の文字列を、4で確保したメモリにコピーする。末尾に\0をつける。
6. 3~5の手順を繰り返す。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!