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

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

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

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

Q&A

解決済

3回答

3030閲覧

C言語の構造体で2分木を作るプログラムの実行時エラーの解決策を教えてください。

Breaststroke

総合スコア8

C

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

0グッド

0クリップ

投稿2017/05/08 18:47

編集2017/05/09 01:33

初心者なので不備が多いかと思いますが、とりあえず動くようにしたいです。
自分でいろいろいじってみましたがどうしてもわかりません。
どこをどう直せばいいのかどなたかご教授お願い致します。

###概要
英文が書かれたテキストファイルから単語(スペースで区切られた塊)
を切り出して2分木にソートして順番に表示するプログラム
###問題点
コンパイルは通るが、実行時に「動作を停止しました。」と出る。
デバッグすると、printTree()内のprintf()でアクセス違反が生じている。
###環境
windows10
Visual Studio 2013

###追記
お二方回答ありがとうございます。
fscanfで読み込んで、新しく型のエラーが生じたところを修正したところ、
一応例外は吐かなくなりました。残りは何とか考えますmm

###修正前コード

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5typedef char DATA; 6struct node { 7 DATA d; 8 int count; 9 struct node *left; // 左部分木 10 struct node *right; // 右部分木 11}; 12typedef struct node NODE; 13typedef NODE *BTREE; 14BTREE insertNode(BTREE, DATA*); 15BTREE allocNode(DATA); 16void printBtree(BTREE); 17void freeBtree(BTREE); 18 19int main(void){ 20 FILE *fp; 21 BTREE root = NULL; 22 DATA str[50]; 23 fp = fopen("./a.txt", "r"); 24 if (fp == NULL){ 25 printf("\aファイルをオープンできません。\n"); 26 } 27 else { 28 while (fgetc(fp) != EOF){ 29 root = insertNode(root, str); 30 } 31 printBtree(root); 32 freeBtree(root); 33 fclose(fp); 34 } 35 return 0; 36} 37 38BTREE insertNode(BTREE node, DATA *x) { 39 BTREE p = node; 40 DATA dat = *x; 41 if (p == NULL) { // rootに挿入 42 p = allocNode(dat); 43 return p; 44 } 45 if (dat == p->d) 46 { 47 p->count++; 48 } 49 else if (dat < p->d) 50 { 51 // 左部分木に割り当て 52 p->left = insertNode(p->left, &dat); 53 // 再帰呼出し 54 } 55 else { 56 // 右部分木に割り当て 57 p->right = insertNode(p->right, &dat); 58 // 再帰呼出し 59 } 60 return p; 61} 62 63BTREE allocNode(DATA x) { 64 BTREE p; 65 p = (BTREE)malloc(sizeof(NODE)); 66 p->d = x; 67 p->left = p->right = NULL; 68 return p; 69} 70 71void printBtree(BTREE p) { 72 if (p != NULL) { 73 printBtree(p->left); // 左部分木の処理(再帰呼び出し) 74 printf("WORD : %s COUNT : %d\n", p->d, p->count); 75 printBtree( p->right ); // 右部分木の処理(再帰呼び出し) 76 } 77 else printf("p==NULL\n"); 78 return; 79} 80 81void freeBtree(BTREE p) { 82 if (p != NULL) { 83 freeBtree(p->left); // 左部分木の処理(再帰呼び出し) 84 freeBtree( p->right ); // 右部分木の処理(再帰呼び出し) 85 free( p ); 86 } 87 return; 88}

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

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

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

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

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

guest

回答3

0

printfのフォーマット指定子が間違っているようです。

charを出力する際には%cをつかいます。
%sはchar*(NUL文字で終わる文字列)を出力する際に用いるものです。

投稿2017/05/08 20:05

KSwordOfHaste

総合スコア18394

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

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

Breaststroke

2017/05/09 01:24

回答ありがとうございます!
guest

0

ベストアンサー

ちょっと見ですが

c

1 while (fgetc(fp) != EOF){ 2 root = insertNode(root, str); 3 }

1.fgetc()で文字を読み込んでいない
2.この段階でstrのは何が入っているか分からない
3.strに文字列を格納するなら空白が出てくるまで読み込んで、文字列(終端'\0')として渡す必要がある。
[追記]

c

1struct node { 2 DATA d; <-これは?これでいいのか? 文字列では? 3 int count; 4 struct node *left; // 左部分木 5 struct node *right; // 右部分木 6};

文字列と文字との処理が混在しているようですが?

投稿2017/05/08 21:41

編集2017/05/08 21:55
cateye

総合スコア6851

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

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

Breaststroke

2017/05/09 01:21

ありがとうございます!
cateye

2017/05/09 01:51

私の方に勘違いがあったようで、ファイルから読み込んだ文字列中の文字の出現率をカウントしてるようですが・・・であればfgets()を使って一行丸ごと読んでから処理した方がいい気がします。この場合、空白もカウントしても(表示するときにカットするなどすれば)問題ないような気もします。
guest

0

解決済ですがfgetcで作成してみました。

#include <stdio.h> #include <stdlib.h> #include <string.h> typedef char DATA; struct node { DATA d[50]; int count; struct node *left; // 左部分木 struct node *right; // 右部分木 }; typedef struct node NODE; typedef NODE *BTREE; BTREE insertNode(BTREE, DATA *); BTREE allocNode(DATA *); void printBtree(BTREE); void freeBtree(BTREE); int main(void){ FILE *fp; BTREE root = NULL; BTREE rootS = NULL; char buf[50] = {0}; char c; DATA *str = buf; int i = 0; fp = fopen("./a.txt", "r"); if (fp == NULL){ printf("\aファイルをオープンできません。\n"); } else { while ((c=fgetc(fp)) != EOF){ if ( c == '\n' || c == ' ' || c == '.' || c == ',' ){ if ((strlen(str)) > 0){ root = insertNode(root, str); if ( rootS == NULL ) rootS=root; } i=0; }else{ buf[i] = c; i++; } buf[i] = '\0'; } printBtree(rootS); freeBtree(rootS); fclose(fp); } return 0; } BTREE insertNode(BTREE node, DATA *x) { BTREE p = node; DATA *dat = x; if (p == NULL) { // rootに挿入 p = allocNode(dat); return p; } if ((strcmp(dat,p->d)) == 0) { p->count++; } else if ((strcmp(dat,p->d)) < 0) { // 左部分木に割り当て p->left = insertNode(p->left, dat); // 再帰呼出し } else { // 右部分木に割り当て p->right = insertNode(p->right, dat); // 再帰呼出し } return p; } BTREE allocNode(DATA *x) { BTREE p; p = (BTREE)malloc(sizeof(NODE)); strcpy(p->d, x); p->count=1; p->left = p->right = NULL; return p; } void printBtree(BTREE p) { if (p != NULL) { printBtree(p->left); // 左部分木の処理(再帰呼び出し) printf("WORD : %-14s COUNT : %d\n", p->d, p->count); printBtree( p->right ); // 右部分木の処理(再帰呼び出し) } return; } void freeBtree(BTREE p) { if (p != NULL) { freeBtree(p->left); // 左部分木の処理(再帰呼び出し) freeBtree( p->right ); // 右部分木の処理(再帰呼び出し) free( p ); } return; }

投稿2017/05/11 03:32

A.Ichi

総合スコア4070

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問