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

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

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

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

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

Vim

VimとはUnix / Linux 系のOSに標準搭載されているターミナル上で動くテキストエディタです。

Q&A

解決済

3回答

1267閲覧

vi での日本語の取り扱いについて

masuter0413

総合スコア50

C

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

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

Vim

VimとはUnix / Linux 系のOSに標準搭載されているターミナル上で動くテキストエディタです。

0グッド

0クリップ

投稿2019/06/09 00:45

以下のプログラムを実行したとき,name.txtがすべて英数字だとうまく実行されます.
しかし,名前の部分を日本語に帰るとcore dumputedとなり1行も表示されません.
実行環境はubuntsuの上でviエディタを使ってます.
どうすれば改善されるでしょうか.

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include <errno.h> 5 6/* ハッシュテーブルの要素数 */ 7#define SIZE 50 8 9/*キー型,データ型 定義*/ 10typedef char KEY; 11typedef char DATA; 12 13/*連結リスト構造体*/ 14struct cell { 15 KEY *key; 16 DATA *data; 17 struct cell *next; 18}; 19typedef struct cell CELL; 20 21/*ハッシュテーブル*/ 22CELL *table[SIZE]; 23 24/*ハッシュテーブル初期化*/ 25void init(CELL **table) 26{ 27 int i = 0; 28 for (i = 0; i < SIZE; i++) { 29 table[i] = NULL; 30 } 31 return; 32} 33 34/*! 35* 連結リストからセルを解放する*/ 36static void cell_free(CELL *cell) 37{ 38 if (cell->key != NULL) free(cell->key); 39 if (cell->data != NULL) free(cell->data); 40 free(cell); 41 return; 42} 43 44/* ハッシュテーブルの要素を解放する*/ 45void hash_free(CELL **table) 46{ 47 int i = 0; 48 CELL *temp = NULL; 49 CELL *swap = NULL; 50 51 for (i = 0; i < SIZE; i++) { 52 temp = table[i]; 53 /* リストの解放 */ 54 while (temp != NULL) { 55 swap = temp->next; 56 cell_free(temp); 57 temp = swap; 58 } 59 } 60 init(table); 61 return; 62} 63 64 65/* ハッシュ値を取得する*/ 66static int hash(KEY *key) 67{ 68 int hashvalue = 0; 69 while (*key) { 70 hashvalue += *key++; 71 } 72 return(hashvalue % SIZE); 73} 74 75/* 76* ハッシュ表を探索して、キーに対応するデータを取得する 77* @table ハッシュテーブル 78* @key ハッシュキー 79* @return データへのポインタ。存在しない場合にはNULLを返す。 80*/ 81DATA *search_cell(CELL **table, KEY*key) 82{ 83 int hashval = hash(key); 84 CELL *hp = table[hashval]; 85 86 for (; hp != NULL; hp = hp->next) { 87 if (strcmp(key, hp->key) == 0) return(hp->data); 88 } 89 90 return(NULL); 91} 92 93/*! 94* 文字列を領域確保してコピーする 95* @dest 文字列のコピー先 96* @src 文字列 97* @return 0 success 98* @return -1 failure 99*/ 100static int strcpy_alloc(char **dest, char *src) 101{ 102 int length = 0; 103 104 length = strlen(src); 105 if (length <= 0) { 106 fprintf(stderr, "ERROR: Invalid parameter(%d line)\n", __LINE__); 107 return(-1); 108 } 109 110 *dest = (char *)malloc(length); 111 if (*dest == NULL) { 112 fprintf(stderr, "ERROR: %s(%d line)\n", strerror(errno), __LINE__); 113 return(-1); 114 } 115 116 if (strncpy(*dest, src, length) == NULL) { 117 fprintf(stderr, "ERROR: %s(%d line)\n", strerror(errno), __LINE__); 118 return(-1); 119 } 120 121 return(0); 122} 123 124/*! 125* ハッシュテーブルに登録する 126* @table ハッシュテーブル 127* @key ハッシュキー 128* @data 登録するデータ 129* @return 0 success 130* @return -1 failure 131*/ 132int insert_cell(CELL **table, KEY *key, DATA *data) 133{ 134 CELL *p = NULL; 135 int hashval = 0; 136 137 /* 同一キーがすでに登録されているか確認する */ 138 if (search_cell(table, key) != NULL) { 139 fprintf(stderr, "key[%s] is already exist in hash table.\n", key); 140 return(-1); 141 } 142 143 /* セル領域を確保する */ 144 p = (CELL *)malloc(sizeof(CELL)); 145 if (p == NULL) { 146 fprintf(stderr, "ERROR: %s(%d line)\n", strerror(errno), __LINE__); 147 return(-1); 148 } 149 150 /* キーとデータをセルに保存する */ 151 if (strcpy_alloc(&(p->key), key) != 0) return(-1); 152 if (strcpy_alloc(&(p->data), data) != 0) return(-1); 153 154 /* セルをハッシュテーブルに登録する */ 155 hashval = hash(key); 156 p->next = table[hashval]; 157 table[hashval] = p; 158 159 return(0); 160} 161 162/*! 163* @brief ハッシュテーブルから削除する 164* @param[in] table ハッシュテーブル 165* @param[in] key ハッシュキー 166* @return 0 success 167* @return -1 failure 168*/ 169int delete_cell(CELL **table, KEY *key) 170{ 171 CELL *target = NULL; 172 CELL *chain = NULL; 173 int hashval = hash(key); 174 175 /* ハッシュキーがハッシュテーブルに存在しているか確認する */ 176 target = table[hashval]; 177 if (target == NULL) { 178 fprintf(stderr, "target[%s] is not exist in hash table.\n", key); 179 return(-1); 180 } 181 chain = target->next; 182 183 /* リストの先頭要素を削除する場合 */ 184 if (strcmp(key, target->key) == 0) { 185 table[hashval] = chain; 186 CELL(target); 187 return(0); 188 } 189 190 /* 先頭以外の要素を削除する場合 */ 191 while (target != NULL) { 192 if (strcmp(key, target->key) == 0) { 193 chain->next = target->next; 194 cell_free(target); 195 return(0); 196 } 197 chain = target; 198 target = target->next; 199 } 200 201 return(-1); 202} 203 204/*! 205* ハッシュテーブルのデータ一覧を表示する 206* @table ハッシュテーブル 207*/ 208static void hash_print_table(CELL **table) 209{ 210 int i = 0; 211 CELL *chain = NULL; 212 213 for (i = 0; i < SIZE; i++) { 214 if (table[i] != NULL) { 215 printf("table[%d]:{", i); 216 chain = table[i]; 217 /* リスト内部を調査して出力する */ 218 for (; chain != NULL; chain = chain->next) { 219 printf("{%s:", (chain->key)); 220 printf("%s", (chain->data)); 221 printf(" %d}",hash(chain->key)); 222 } 223 printf("}\n"); 224 } 225 } 226} 227 228int main(void) 229{ 230 231 FILE*fp; 232 /* ハッシュの初期化 */ 233 init(table); 234 char key[256]; 235 char data[256]; 236 char name[256]; 237 char del[256]; 238 int i, ren; 239 240 fp = fopen("name.txt", "r"); 241 for (i = 0;; i++) { 242 ren = fscanf(fp, "%s %s \n", key, data); 243 if (ren == EOF)break; 244 insert_cell(table, key, data); 245 } 246 247 hash_print_table(table); 248 249 /* データを検索する */ 250 printf("Search stu-num\nname please:"); 251 scanf("%s", name); 252 printf("number:%s\n", search_cell(table, name)); 253 254 /* データを削除する */ 255 printf("DELET-WORD:\nname please:"); 256 scanf("%s", del); 257 delete_cell(table, del); 258 hash_print_table(table); 259 260 /* ハッシュテーブルを解放する */ 261 hash_free(table); 262 263 return(0); 264} 265

txt

1田中 J1877 2梅島 D4563

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

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

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

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

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

cateye

2019/06/09 00:54

2行目"梅島 D4563"に全角空白文字が入っているようですが?
1T2R3M4

2019/06/09 00:58

viは関係ないんじゃないの。
masuter0413

2019/06/09 00:59

半角に修正してもダメでした.
guest

回答3

0

strcpy_alloc ですが、文字列終端の '\0' もコピーしましょう。

C

1 int length = strlen(src); 2 *dest = (char *)malloc(length + 1); // '\0' の分も確保 3 strcpy(*dest, src); // '\0' までコピー

投稿2019/06/09 09:07

kazuma-s

総合スコア8224

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

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

0

ベストアンサー

ren = fscanf(fp, "%s %s \n", key, data);

renが2以外だと、入力データがおかしいと言うことなので、エラー表示して終了しましょう。
これで、全角空白を発見できます。

また、ハッシュ値関係の型を全部intからuintにしましょう。負数になるとテーブル範囲外になる。

あと、Cのプログラムの話であり、エディタは何を使おうが関係ないので、タイトルとタグからviを消しましょう。

投稿2019/06/09 02:05

otn

総合スコア84555

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

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

kazuma-s

2019/06/09 08:46

田中 J1877 梅島□D4563 佐藤□K2718 name.txt がこのようになっていた場合(□は全角スペース)、 key="梅島□D4563"、data="佐藤□K2718" のように読み込んで ren が 2 になるので、全角スペースを検出できません。 fgets + sscanf で読み込んだほうがよいと思います。
otn

2019/06/09 11:47

なるほど。\n があるから大丈夫と思っていましたが、やっぱり駄目ですね。
guest

0

text

1usr ~/tmp % od -x aa.txt 20000000 94e7 e4b0 adb8 4a20 3831 3737 e60a 85a2 30000020 b3e5 e3b6 8080 3444 3635 0a33 40000034 5usr ~/tmp % cat aa.txt 6田中 J1877 7梅島 D4563 8usr ~/tmp %

全角空白(8080)が入っています。

ren = fscanf(fp, "%s %s \n", key, data);

で、keyの値しか読めてないと思います。

if (ren == EOF)break;

は、やめて項目数(ここでは2)にしましょう。
ちゃんと読めなくても通ってしまいます。

if (ren == EOF)break;

if (ren != 2)break;

投稿2019/06/09 01:01

編集2019/06/09 01:04
cateye

総合スコア6851

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

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

cateye

2019/06/09 01:14

insert_cell(table, key, data);呼び出し前にprintf()とかやってみましょう。
cateye

2019/06/09 01:58 編集

search_cell()が怪しいけど時間がないので後は自分で調べて下さい。 usr ~/tmp % ./a.out init in init out 田中:J1877 田中:J1877 search_cell in Segmentation fault (core dumped) usr ~/tmp % と、vimのタグは外して・・・ あと、23個もワーニングが出ます。“プロトタイプがない”なんてのも有るけど、自分で説明が付けられないワーニングは消しましょう。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問