• ベストアンサー

可変長文字列で困ってます

宿題出で全くわかりません。 ここを実装っていうところがわかりません。 よろしくお願いします。 /* 単方向リストプログラム */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <assert.h> #include <crtdbg.h> /********************* リスト処理部 *********************/ /* リストセル 構造体定義 */ typedef struct cell { char *string; struct cell *next; } CELL, *PCELL; /* PCELL ListInsert(PCELL pos, const char *string) 指定されたセルの次に,新しいセルの挿入する PCELL pos : 挿入位置のセルを指すポインタ char *string : 新セルに含める文字列 戻り値: 新しく確保したセルのアドレス メモリ確保に失敗した場合にはNULL */ PCELL ListInsert(PCELL pos, const char *string) { PCELL pNewCell; pNewCell = calloc(1, sizeof(CELL)); if (pNewCell != NULL) { // ここを実装する } return pNewCell; } /* void ListDelete(PCELL pos) セルの削除.pos の指すセルの次のセルを削除する. PCELL pos : 削除するセルの直前のセルを指すポインタ */ void ListDelete(PCELL pos) { // ここを実装 } /* void ListDestory(PCELL header) リスト全体の削除 PCELL header : ヘッダセルへのポインタ */ void ListDestroy(PCELL header) { // ここを実装 }

質問者が選んだベストアンサー

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.3

★アドバイス ・宿題ですので頑張りましょう。ただし、少しだけアルゴリズムを教えましょう。 ・『ListInsert』の実装は CELL 構造体の next メンバに pNewCell のアドレスを  セットして、CELL 構造体の string メンバに引数の string をメモリ確保した  アドレスをセットします。 ・『ListDelete』の実装は CELL 構造体の next メンバのメモリを解放します。  CELL 構造体の string メンバのメモリ解放も行う。その後、CELL 構造体の  メモリ領域も解放させる。 ・『ListDestroy』の実装は CELL 構造体の next メンバをたどっていき ListDelete 関数と  同じような処理を行う。 ・最後に、単方向リストの仕組みを紙に書いてイメージしてお勉強しましょう。 →頭の中で出来るようになりましょう。頑張って下さい。さようなら。

その他の回答 (2)

  • asfd
  • ベストアンサー率21% (25/117)
回答No.2

単方向リストですね。linked listとかともいいます。 基本的なデータ構造です。まぁ宿題ですので自分で色々調べて 下さい(^^; 検索すると色々出てくると思いますよ。ずばり答えもでてくるかも?

参考URL:
http://homepage1.nifty.com/daccho/program/algo/slinklst.htm
noname#22058
noname#22058
回答No.1

ことリスト構造に関しては、人に答えを教えてもらっただけでは 「絶対に」理解できません。 テキストや授業の内容を確認しながら、自分の頭をフル回転させて ウンウンうなりながら解いてください。

関連するQ&A

  • C言語単方向リストのメモリリークについて

    ListInsert,ListDeleteに問題があると思うのですが、その問題に気づけません。アドバイス、間違いの指摘等していただければと思います。よろしくお願いします。 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<crtdbg.h> /* リストセル定義 */ typedef struct cell{ char *string; struct cell *next; }CELL,*PCELL; /* リストヘッダ作成 */ PCELL ListCreate(){ return calloc(1,sizeof(CELL)); } /* headerで指定されたリストからstrで指定された文字列を 格納したセルを検索し,その直前のセルを指すポインタを返す */ PCELL ListGetPrevPos(PCELL header,const char *str){ while (header->next){ if (strcmp(header->next->string,str)==0){ return header; } header=header->next; } return NULL; } /* PCELL pos:特定のセルを指すポインタ 戻り値:posの次のセルのポインタ */ PCELL ListNext(PCELL pos){ return pos->next; } /* リスト表示 */ void ListPrintAll(PCELL header){ puts("- addr -- next -:string"); printf("[%08x][%08x]:HEADER\n", header, header->next); header=header->next; while(header){ printf("[%08x][%08x]:<%s>\n",header,header->next,header->string); header=header->next; } puts("------"); } /* 新しいセルを挿入する */ PCELL ListInsert(PCELL pos, const char *string){ PCELL pNewCell; pNewCell=calloc(1,sizeof(CELL)); if(pNewCell!=NULL){ pNewCell->string=malloc(strlen(string)+1); strcpy(pNewCell->string,string); pNewCell->next=pos->next; pos->next=pNewCell; } return pNewCell; } /* セルの削除 */ void ListDelete(PCELL pos){ struct cell *ptemp1; char *ptemp2; ptemp2=calloc(1,sizeof(pos->next->string)); ptemp1=pos->next; ptemp2=pos->next->string; pos->next=pos->next->next; free(ptemp2); free(ptemp1); } /* リスト全体の削除 */ void ListDestroy(PCELL header){ while(header->next!=NULL){ ListDelete(header); } free(header); } int main(){ PCELL header; header=ListCreate(); ListInsert(header,"grape"); ListInsert(header,"apple"); ListInsert(header,"kiwi"); ListPrintAll(header); ListInsert(ListNext(ListGetPrevPos(header,"apple")),"banana"); ListDelete(ListGetPrevPos(header,"apple")); ListDelete(header); ListPrintAll(header); ListDestroy(header); _CrtDumpMemoryLeaks();//メモリリークの表示 }

  • 可変長のリスト

    格納する文字列の長さを変えられるリストを作っているのですが、削除で困っています。 セルは、 typedef struct cell { char *str; struct cell *next; } CELL, *pCELL; で定義してあります。この上で、 void Delete(pCELL p) { pCELL tmp; char *ad; tmp = p->next; ad = tmp->str; p->next = tmp->next; free(tmp); free(ad); } を使ってposの次のセルを削除したいのですがうまくいきません。ビルドはできるのですが、実行するとエラーがでます。 エラーメッセージはDAMAGR:after Normal block (#46) at 0x003710F0です。 動作環境は、XPでVS.NETです。 どなたかわかるかたお願いします。

  • ハッシュ法が得意な人お願いします。

    辞書検索プログラムが実行できません。どこがおかしいか教えてください。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define BUCKET_SIZE 100 typedef struct pointer { struct cell *chain; }pointer; struct cell{ char eng[20]; char jp[40]; struct cell *next; } table[BUCKET_SIZE]; int n; void read_dic(); void init_table(); int hash(char *tango); void main(); struct cell *find(char *tango); struct pointer bucket[BUCKET_SIZE]; void init_table() { int i; for (i=0;i<BUCKET_SIZE;i++){ strcpy(table[i].eng,"0"); strcpy(table[i].jp,"0"); } } void main() { int m; struct cell *p; char tango[20]; read_dic(); while(1){ printf("\n単語を入力: "); scanf("%s", tango); if (strcmp(tango, "*") == 0){ printf("検索を終了\n"); exit(0); } if((p= find(tango)) == NULL) printf("単語は見つかりませんでした\n"); else printf("訳語: %s \n", table[p].jp); } } まだ続きます。。。

  • 可変長引数の扱い

     以下のプログラムが、 Hello,world. Hello, という出力しかしません。どうしてでしょう?  もしこういったことはcでは無理なのだとすれば、printfやsyslogなどのフォーマット指定のある出力関数のラッパーを書く他のいい方法があるんでしょうか? #include <stdio.h> #include <stdarg.h> #include <stdlib.h> void messout(const char *format, ...); int main(void) {   char *str = "world.";   printf("Hello,%s\n", str);   messout("Hello,%s\n", str);   exit(0); } void messout(const char *format, ...) {   va_list list;   va_start(list, format);   printf(format, list);   va_end(list); }

  • 構造体宣言したポインタ変数に値を代入するには?

    strcpy(p -> key ,name);と打ってp -> key に入力した名前を格納したいのですがうまくいきません。 ほかにもp -> key = nameなども試してみましたがコンパイルエラーが出現してダメでした。 うまく格納できるやり方があれば教えてください。よろしくお願いします。 #include<stdio.h> #include<string.h> #define WORD_LENGTH 50 /* 文字列の最大長 */ typedef struct cell{ char key[WORD_LENGTH]; struct cell *next; /* 次のセルへのポインタ */ } CELL; void main(void) { char name[WORD_LENGTH]; CELL *p; printf("名前入力\n"); scanf("%s\n", name); strcpy(p -> key ,name); printf("%s\n", p -> key); }

  • 文字列扱い方

    構造体の中の配列へ文字列を入れる方法がわからなくてこまっています! #include <stdio.h> struct TEST{     char str[32]; }; int main(){     TEST test;     test.str = "test";     return 0; } このように入力するとconst char [5]' から 'char [32]' に変換できません。と出てしまいます。 何か良い方法がありましたらぜひご教授お願いいたします。

  • 文字列をうまく返してくれない

    数値を文字列として呼び出し元に渡し、呼び出し元で文字列を数値に変えようとしたのですがatoi関数(strtolを使うと最初の文字のみ帰ってくるため2桁以上の数値に対応できない)を使うとうまく行きませんでした。 どのように変更したらatoiが使える文字列になりますか? #include <stdio.h> #include <stdlib.h> static struct{   char *name; }kuda[5]={   { "もも" , "りんご" , "みかん" , "バナナ" , "パイナップル" } } char *re_3( void ){   int a = 3;   char str_h[100];   char *str;   sprintf_s( str_h , 100 , "%d" , a );   *str = *str_h; //原因はおそらくここ   return str; } void main( void ){   printf( "%s" , kuda[ atoi( re_3() ) ].name ); }

  • C言語の自己参照型プログラムについて

    #include <stdio.h> #include <string.h> #include <stdlib.h> struct list { int key; /* キー */ char name[20]; /* 名前 */ struct list *next; /* 次のデータへのポインタ */ }; struct list *add_list(int key, char *name, struct list *head); void show_list(struct list *p); void free_list(struct list *p); int main(void) { struct list *head; /* 先頭ポインタ */ char name[20]; int key = 0; head = NULL; /* 先頭ポインタにNULLを設定 */ printf("キーと名前(MAX:19文字)を入力(終了:CTRL+Z)\n"); while (scanf("%d %s", &key, name) != EOF) { /* リストにデータを登録 */ head = add_list(key, name, head); } /* リストの表示 */ show_list(head); /* リストの開放 */ free_list(head); return 0; } /*** リストにデータを登録 ***/ struct list *add_list(int key, char *name, struct list *head) { struct list *p; /* 記憶領域の確保 */ if ((p = (struct list *) malloc(sizeof(struct list))) == NULL) { printf("malloc error\n"); exit(EXIT_FAILURE); } /* リストにデータを登録 */ p->key = key; strcpy(p->name, name); /* ポインタのつなぎ換え */ p->next = head; /* 今までの先頭ポインタを次ポインタに */ head = p; /* 新たな領域を先頭ポインタに */ return head; } /*** リストの表示 ***/ void show_list(struct list *p) { while (p != NULL) { /* 次ポインタがNULLまで処理 */ printf("%3d %s\n", p->key, p->name); p = p->next; } } /*** リストの開放 ***/ void free_list(struct list *p) { struct list *p2; while (p != NULL) { /* 次ポインタがNULLまで処理 */ p2 = p->next; free(p); p = p2; } } これを実行すると、 新しく入力された順にリストが表示されます。 そうではなく、キーの昇順に表示したいです。 どなたかそのように実行できるようにプログラムを書き換えてくれませんか? 図々しいですがよろしくお願いいたします。m(_ _)m

  • c++11での文字列リテラルの特殊化について

    c++11言語でのテンプレート部分特殊化についての質問です。 コメントアウト部分は出力結果です template<class T> struct VT { static const int type = 1;}; template<class T,int N> struct VT< T[N] > { static const int type = 2;}; template<class T,int N> struct VT< const T[N] > { static const int type = 3;}; template<class T> struct VT< T* > { static const int type = 4;}; template<class T> struct VT< const T*const > { static const int type = 5;}; #include<iostream> #include<typeinfo> int main(){ std::cout<<"A:"<< VT< char >::type << std::endl; // A:1 std::cout<<"B:"<< VT< char[10] >::type << std::endl; // B:2 std::cout<<"C:"<< VT< char* >::type << std::endl; // C:4 std::cout<<"D:"<< VT< char const [1] >::type << std::endl; // D:3 std::cout<<"E:"<< VT< decltype("") >::type << std::endl; // E:1 std::cout<<"G:"<< typeid( char const [1] ).name() << std::endl;// G:char const [1] std::cout<<"H:"<< typeid( "" ).name() << std::endl;// H:char const [1] } 型名を直接記述したD,G、文字列リテラルを記述したE,H。 コンパイラ毎の差はあれど、GとHの型名は同じものが表示されます。 ですが、[D:3] [E:1]と値は違い、別の特殊化テンプレートが使われています。 この部分が分かりません。 また、配列リテラル、文字列リテラルに対し部分特殊化テンプレートを宣言する方法などありましたら、ご教示お願いします。

  • fwrite文について

    char型で宣言した配列の方はうまくいきましたが、構造体を用いたfwrite文がうまく出力されません。 どうしてでしょうか? #include <stdio.h> #include <string.h> #include <stdlib.h> struct ll{ char name[20]; int ten[3]; }list[3] = { {"aaa", 11}, {"bbb",22}, {"ccc",33} }; FILE *fpbin, *fpcsv; /*FILE構造体(グローバル変数)*/ void main(void) { char i[] = {'a','b'}; fpbin = fopen("data.txt","w"); //fwrite(&i,sizeof(char),2,fpbin); fwrite(&list[0].name,sizeof(struct ll),2,fpbin); fclose(fpbin); }

専門家に質問してみよう