
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の長さが固定でないため配列の要素をどのように増やすか、
です。
どなたか助けていただけないでしょうか。
直接回答を教えていただけたらすごく助かります。
参考のページや考え方を教えていただいてもありがたいです。
よろしくお願いします。
No.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;
}
}
本質ではない部分は省略していますので、自分で補ってください。
No.3
- 回答日時:
// 文字列、配列の要素数は変更しやすいように
// #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
*/
No.2
- 回答日時:
まず、用語を整理しましょう。
いろんな言葉が混っていて、実際になにがやりたいか正確に把握できません。「配列にポインタを入れたい 」「配列の要素にアドレスを入れること」を文面通りに受け取るなら
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も変わってしまいます
No.1
- 回答日時:
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が見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語のプログラムについてです
-
std::stringクラスのc_str()で...
-
char型にint型の数値を代入する。
-
new charとnew char[N]の違いは?
-
CStringからchar*への型変換に...
-
文字列内の数字削除
-
ポインタを使って回文かどうか...
-
char 文字列型 の表現範囲が-12...
-
VBAのプログラムで、DIAG = 1# ...
-
プログラムによく出てくるst...
-
C言語 配列の長さの上限
-
C# DataTableの行をソートしてD...
-
C++で、メンバもヒープに確保さ...
-
c言語のポインタへの文字列入力...
-
銀行ATMの数字キーの配列
-
C#で構造体の配列を持った構造...
-
newしないオブジェクトについて
-
Integer変数をカラにしたいので...
-
配列の要素数に変数を入れたい...
-
C言語 ファイルの指定された行...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CStringからchar*への型変換に...
-
char*を初期化したいのですが
-
C言語のintとcharの違いってな...
-
C言語にて構造体のメンバがNULL...
-
fstream型オブジェクトを関数の...
-
char型にint型の数値を代入する。
-
char 文字列型 の表現範囲が-12...
-
文字列を比較するプログラムな...
-
ostringstreamではまりました
-
文字列内の数字削除
-
C言語のプログラムについてです
-
csvファイルをfscanfで読み込む...
-
エクセルのMID関数は、C言語では?
-
ポインタを使って回文かどうか...
-
C言語でポインターで詰まってい...
-
文字列の途中から途中までを抽出
-
new charとnew char[N]の違いは?
-
文字列str内の全ての数字を...
-
以下のようなプログラムを書い...
-
char AA[]{"全角文字"};から"全...
おすすめ情報