質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

Q&A

解決済

3回答

822閲覧

C言語 文字列ポインタの配列をデータ構造のリスト構造にしたい

prof

総合スコア179

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

0グッド

1クリップ

投稿2021/04/24 11:02

編集2021/04/24 12:29

文字列ポインタの配列{"ab","cd",NULL}をデータ構造のリスト構造にしたいです。

引数を文字列ポインタの配列とし、返り値を構造体のポインタとしたいです。

以下、考えたコードです。

疑問点は、

  • 配列を引数に受け取るが再帰ではどのように進めればいいか
  • 次の構造体をどのように代入すればいいか

ということです。

C

1 2#include <stdlib.h> 3#include <stdio.h> 4 5// struct定義 6typedef struct wordlist { 7 char *word; 8 struct wordlist *next; 9} WordList; 10 11WordList *function(char **argv){ 12 13 WordList *p ; 14 p = (WordList*) malloc(sizeof(WordList)); 15 WordList *head = NULL; 16 17 // 引数が配列だから再帰処理できない? 18 // NULLまでループ 19 int i = 0; 20 while(argv[i] != NULL){ 21 if(p != NULL){ 22 p->word = argv[i]; 23 }else{ 24 return NULL; 25 } 26 // 次がNULLならnextはNULL 27 if(argv[i+1] == NULL){ 28 p->next == NULL; 29 }else{ 30 //どのように与えるのか 31 p->next = head; 32 } 33 i++; 34 } 35 return result; 36} 37 38int main(void){ 39 char *words[] = { 40 "aa", "bb", "cc", "dd", "ee","NULL", 41 }; 42 WordList *res = function(words); 43 printf("%s\n",res->word); 44 free(res); 45 return 0; 46}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2021/04/24 11:15

提示のコードではどういう不具合があるんでしょうか。 くわしく説明しましょう
BeatStar

2021/04/24 11:23

単純に有名なリスト構造のデータを int型から char型ポインタまたは配列にすればいいのでは?
guest

回答3

0

ベストアンサー

再帰してみた

C

1#define _CRT_SECURE_NO_WARNINGS 2#include <stdlib.h> 3#include <stdio.h> 4#include <string.h> 5 6typedef struct wordlist { 7 char* word; 8 struct wordlist* next; 9} WordList; 10 11WordList* make_node(const char* word) { 12 WordList* node = (WordList*)malloc(sizeof(WordList)); 13 node->word = (char*)malloc(strlen(word) + 1); 14 strcpy(node->word, word); 15 node->next = NULL; 16 return node; 17} 18 19WordList* last_node(WordList* node) { 20 return ( node == NULL || node->next == NULL ) ? node : last_node(node->next); 21} 22 23WordList* function(WordList* head, const char** argv) { 24 if ( *argv ) { 25 WordList* tail = make_node(*argv); 26 if ( head == NULL ) { 27 head = tail; 28 } else { 29 last_node(head)->next = tail; 30 } 31 function(head, argv + 1); 32 } 33 return head; 34} 35 36int main() { 37 const char* argv[] = { "abc", "def", "ghi", NULL }; 38 WordList* head = function(NULL, argv); 39 WordList* p = head; 40 while ( p != NULL ) { 41 WordList* tmp = p->next; 42 printf("[%s]\n", p->word); 43 free(p->word); 44 free(p); 45 p = tmp; 46 } 47 return 0; 48}

投稿2021/04/24 12:48

episteme

総合スコア16612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

prof

2021/04/24 14:30

いつも回答頂きありがとうございます。 自己参照とmallocの使い方の理解がないので、復習してから確認させていただきます。
guest

0

初期化間違いはすでに指摘済みですが、全然、再帰じゃないですね。

C

1WordList *function(char **argv){ 2 3 WordList *p = malloc(sizeof(WordList)); 4 if(p == NULL){ 5 printf("Error !!\n"); exit(0); 6 } 7 8 if (*argv == NULL) { 9 return NULL; 10 } 11 p->word = *argv; 12 p->next = function(argv + 1); 13 return p; 14}

こんな感じ?

ただ、これだと、mainでの出力が最初の一つのみ、freeも全く足りてませんが。(再帰が必要)

投稿2021/04/24 12:42

pepperleaf

総合スコア6385

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

prof

2021/04/24 14:28

mainの出力は仮で記述しました、説明不足でした。
prof

2021/04/24 14:31

free()を再帰的にする関数をmain外で作って、mainで呼び出す感じで良いでしょうか?
actorbug

2021/04/24 20:47 編集

*argv == NULL だった場合に、p に確保されたメモリが解放されない不具合があるように見えます。 *argvのNULL判定とメモリ確保の順番を逆にすべきではないでしょうか。
pepperleaf

2021/04/25 06:18

profさん、 freeの件は、それで良いと思います。 actorbugさん、ご指摘通りです。
prof

2021/04/25 12:12

承知しました。ご丁寧にありがとうございます。
guest

0

まずひとつ。

NULLで終了標識としたいなら、
char *words[] = {
"aa", "bb", "cc", "dd", "ee",NULL,
};
とする必要があります


//どのように与えるのか

p->next = head;

とありますが、headにはNULLしかはいってません
ここは、WordListの実態が入る必要があるので、その分の領域確保、構造体の初期化、変数の設定を済ませたもののアドレスを入れてください

投稿2021/04/24 11:25

編集2021/04/24 12:39
y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

prof

2021/04/24 12:31

完全に見落としていました。修正します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問