【C言語】配列にポインタを入れる方法とは?
- C言語のプログラム作成で文字列を配列にポインタを入れたい場合の方法を調べています。
- 文字列を で区切って配列に格納する方法についてわからない部分があります。
- 配列の要素にアドレスを入れる方法や可変長の文字列の配列を扱う方法について教えていただきたいです。
- ベストアンサー
配列にポインタを入れたい
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の長さが固定でないため配列の要素をどのように増やすか、 です。 どなたか助けていただけないでしょうか。 直接回答を教えていただけたらすごく助かります。 参考のページや考え方を教えていただいてもありがたいです。 よろしくお願いします。
- kitakazetotaiyou
- お礼率35% (47/134)
- C・C++・C#
- 回答数4
- ありがとう数1
- みんなの回答 (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; } } 本質ではない部分は省略していますので、自分で補ってください。
その他の回答 (3)
- kb-nike
- ベストアンサー率36% (72/200)
// 文字列、配列の要素数は変更しやすいように // #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 */
- kmee
- ベストアンサー率55% (1857/3366)
まず、用語を整理しましょう。いろんな言葉が混っていて、実際になにがやりたいか正確に把握できません。 「配列にポインタを入れたい 」「配列の要素にアドレスを入れること」を文面通りに受け取るなら 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も変わってしまいます
- salsberry
- ベストアンサー率69% (495/711)
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の手順を繰り返す。
関連するQ&A
- 文字列を改行で区切り配列に格納したい
データをプログラムに明記し、プログラムで いろいろ加工したり処理をしたい場合ですが、 例えば、 Dim hairetu(10) As String hairetu(0) = "aaa" hairetu(1) = "bbb" hairetu(2) = "ccc" 途中省略 hairetu(10) = "zzz" これをイメージとして以下のように行う方法はありますでしょうか あくまでもイメージとしてです。 Dim mojiretu As String Dim hairetu(10) As String mojiretu="aaa\nbbb\nccc\n途中省略zzz" ← hairetu=mojiretuを”\n”で区切り順次配列に格納する ←は、mojiretu="aaa bbb ccc 省略 zzz" のようなイメージです。 よろしくお願いします
- ベストアンサー
- Visual Basic
- 配列に入っている値のソート
str(1)="bbb" str(2)="aaa" str(3)="ddd" str(4)="eee" str(5)="ccc" という配列があるとします。 これを昇順にソートさせて、 str(1)="aaa" str(2)="bbb" str(3)="ccc" str(4)="ddd" str(5)="eee" とさせたいのですが、どのようにすればよろしいでしょうか?
- ベストアンサー
- Visual Basic
- 文字列を配列定義に使用するには
文字列を配列の定義に使用したいのですが、可能でしょうか? 具体的には以下のような内容です。 $AAA = array("name"=>"山田","val"=>"10"); とすると変数$AAAは配列になります。 $BBB = 'array("name"=>"佐藤","val"=>"20")'; とすると変数$BBBは文字列になります。 $CCC = $BBB; と変数$CCCに代入した場合に、 変数$CCCを配列として認識させたいです。 つまり print $CCC[name]; //佐藤 print $CCC[val]; //20 というように出力させたいのですが、 根本的に可能なのでしょうか…? よろしくお願いいたします。
- ベストアンサー
- PHP
- ArrayListに多次元配列
ArrayListに多次元配列の変数を格納したのですが、取り出し方がわからず困っています。 ----------------------------------------------- String[][] str = {{"aaa","bbb","ccc","ddd","eee","fff"}, {"aaa","bbb","ccc","ddd","eee","fff"}, }}; ArrayList array = new ArrayList(); array.add(str[0]); array.add(str[1]); ----------------------------------------------- 上記の場合で、str[0][2];を取得する方法がわかりません。 java初心者なのでおかしな質問かもしれませんが、宜しくお願いします。
- ベストアンサー
- Java
- 配列の組み合わせを数える方法
配列の組み合わせを数えるイイ方法はないでしょうか? たとえば ArrayA[]={"aaa","bbb","aaa","ccc","bbb","aaa"} ArrayB[]={"1","1","1","2","1","2"} ↑の配列があるとして、 aaa - 1 : 2個 aaa - 2 : 1個 bbb - 1 : 2個 ccc - 2 : 1個 と組み合わせの数を数えることができる方法で悩んでいます。 Strtusを用いて作成しています。 よろしくお願いします。
- ベストアンサー
- Java
- シェルでファイルを読み込み、そのレコードを分解し、分解した文字列を使用
シェルでファイルを読み込み、そのレコードを分解し、分解した文字列を使用してコマンドを発行したい。 ■処理内容 下記のファイルを読み込み、aaa=○○の○○を使用してコマンドを発行したいです。 ■理解している所 & 質問 ファイルを引数に起動し、配列として取得 str=`cut -f 1 -d ',' $1 | cut -c 8-` ループで回して値を一個一個取り出して実行 i=0 while [ $i < ${#str[@]} ];do echo $str[$i] i = $i + 1 done なんとなくできるような気はしているのですが、 cutでstr変数に入れた所で一つの文字列と入ってしまっているようで、 正しくループが回せません。(分解した後にecho "${str[1]}" echo "${str[2]}"] などと実行しても空です) 完全案を教えてください。 ■ファイル aaaaaaa=testdata1,bbb=testdata2,ccc=testdata3 aaaaaaa=hhogedata1,bbb=hugahugadata2,ccc=piyopiyodata3 ※aaa=○○,bbb=××,ccc=△△という形式で、各○○の部分の長さは不定。 ※レコード数は不定。
- ベストアンサー
- その他(プログラミング・開発)
- C#: 改行コードを含む文字列の長さ検出
前略 下記のような改行コードを含む文字列について、”改行コードを1文字として、文字列の長さを取得”したいのですがどのようにすればよいのか教えてください。 string str = "aaa\nbbb\nccc\nddd\n"; str.Length では 改行コードを含まない値が取得されてしまいます。 以上、よろしくおねがいします。
- ベストアンサー
- C・C++・C#
- ''で囲まれていない文字列にマッチする正規表現
下記のような文字列($str)に対して置換を行い、 my $str = qq{ AAA = BBB - 'CCC' }; $str =~ s/★正規表現★/sprintf("DDD(%s)",$1)/xmsge ; 変換後 $str = DDD(AAA) = DDD(BBB) - 'CCC' ; を実現する★正規表現★を書きたいと思っています。 ・AAA,BBB,CCCは[\w]で構成される文字列です。 ですが、シングルクォーテーション('')で囲まれていない文字列にマッチする正規表現が書けなく困っています。 一度、シングルクォーテーションで囲まれているものも含めて全てDDD()をつけて、そのあとで、シングルクォーテーションを含むものは元に戻すことでやりたいことは実現できているのですが、1行で実現できる方法を探しています。 アドバイスよろしくお願いします。
- ベストアンサー
- Perl