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

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

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

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

Q&A

解決済

2回答

450閲覧

最後の要素だけコンマを削除したい場合

romina

総合スコア6

C

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

0グッド

1クリップ

投稿2022/05/26 13:59

こんにちは
現在、ハッシュテーブルを学んでいます。
Keyとvalueの値を並べて出力する時に、配列最後の要素だけコンマ", " をとって表示したい場合のコードですが、
このint flagの働きがよく理解できません。

出力結果:
{'Betty': 'Cool', 'python': 'awesome', 'Bob': 'and Kris love asm', '98': 'Battery Street', 'N': 'queens', 'c': 'fun', 'Asterix': 'Obelix'(←ここだけコンマがない)}

どなたか説明いただけないでしょうか?

void hash_table_print(const hash_table_t *ht) { unsigned long int index; unsigned long int flag; hash_node_t *temp; if (ht == NULL) return; printf("{"); for (index = 0; index < ht->size; index++) { temp = ht->array[index]; while (temp) { if (flag == 1) printf(", "); printf("'%s': '%s'", temp->key, temp->value); flag = 1; temp = temp->next; } } printf("}\n"); }

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

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

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

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

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

Zuishin

2022/05/26 14:03

このコード、間違ってませんか? どこにあったものでしょう?
jimbe

2022/05/26 16:44

array がノードのリンクリストの配列なら合ってそうですが。
guest

回答2

0

ベストアンサー

コードをどう書くのかということであれば、実行できるコードをご提示頂いたほうが良いです。

最初に付けない場合でも最後に付けない場合でも、要するに if 文の条件をどうやって最初/最後と判定させるかということです。
フラグ変数を初期値 0 とし、一度でも表示したら 1 にすることで、最初か否かの判断が出来ます。
もし表示する件数が予め分かっていれば、表示した数をカウントして最後かどうかの判断が出来ます。
次のコードの hash_table_print2 では、"array のループの最後 かつ 次へのポインタが NULL " なら最後としています。

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5typedef struct hash_node { 6 char *key; 7 char *value; 8 struct hash_node *next; 9} hash_node_t; 10 11typedef struct hash_table { 12 hash_node_t *table[256]; 13 int size; 14 hash_node_t **array; //有効データ 15} hash_table_t; 16 17int calcHash(char *key) { 18 return key[0]; //テキトウ 19} 20 21//最初の前に "," を付けない 22void hash_table_print(const hash_table_t *ht) { 23 if(ht == NULL) return; 24 25 printf("{"); 26 for(int i=0, flag=0; i<ht->size; i++) { 27 for(hash_node_t *node=ht->array[i]; node!=NULL; node=node->next) { 28 if(flag == 1) printf(", "); //最初だけ条件が偽になる 29 printf("'%s': '%s'", node->key, node->value); 30 flag = 1; 31 } 32 } 33 printf("}\n"); 34} 35 36//最後の後に "," を付けない 37void hash_table_print2(const hash_table_t *ht) { 38 if(ht == NULL) return; 39 40 printf("{"); 41 for(int i=0; i<ht->size; i++) { 42 for(hash_node_t *node=ht->array[i]; node!=NULL; node=node->next) { 43 printf("'%s': '%s'", node->key, node->value); 44 if(i < ht->size-1 || node->next != NULL) printf(", "); //最後だけ条件が偽になる 45 } 46 } 47 printf("}\n"); 48} 49 50int put(hash_table_t *ht, char *key, char *value) { 51 hash_node_t *node = malloc(sizeof(hash_node_t) + strlen(key)+1 + strlen(value)+1); 52 if(node == NULL) return -1; 53 node->key = (char*)node + sizeof(hash_node_t); 54 strcpy(node->key, key); 55 node->value = node->key + strlen(key)+1; 56 strcpy(node->value, value); 57 node->next = NULL; 58 59 int hash = calcHash(key); 60 if(ht->table[hash] == NULL) { 61 hash_node_t **a = realloc(ht->array, (ht->size+1) * sizeof(void*)); 62 if(a == NULL) return -1; 63 ht->array = a; 64 ht->array[ht->size++] = node; 65 66 ht->table[hash] = node; 67 return 0; 68 } 69 70 hash_node_t **pp = &ht->table[hash]; 71 while(*pp != NULL && strcmp((*pp)->key, node->key)) pp = &(*pp)->next; 72 if(*pp != NULL) { 73 node->next = (*pp)->next; 74 free(*pp); 75 } 76 *pp = node; 77 return 0; 78} 79 80int main(void) { 81 hash_table_t ht; 82 memset(&ht, 0, sizeof(hash_table_t)); 83 84 put(&ht, "Betty", "Cool"); 85 put(&ht, "python", "awesome"); 86 put(&ht, "Bob", "and Kris love asm"); 87 put(&ht, "98", "Battery Street"); 88 put(&ht, "N", "queens"); 89 put(&ht, "c", "fun"); 90 put(&ht, "Asterix", "Obelix"); 91 92 hash_table_print(&ht); 93 hash_table_print2(&ht); 94 95 return 0; 96}

実行結果 ( 実装が想像ですので並び順は無視してください。 )

plain

1{'Betty': 'Cool', 'Bob': 'and Kris love asm', 'python': 'awesome', '98': 'Battery Street', 'N': 'queens', 'c': 'fun', 'Asterix': 'Obelix'} 2{'Betty': 'Cool', 'Bob': 'and Kris love asm', 'python': 'awesome', '98': 'Battery Street', 'N': 'queens', 'c': 'fun', 'Asterix': 'Obelix'}

投稿2022/05/26 18:47

編集2022/05/26 18:53
jimbe

総合スコア12659

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

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

romina

2022/05/26 19:16

フラグ変数自体を知らなかったのでとても勉強になりました。調べてみると、真偽値を保持する変数なんですね。 様々な例までつけていただいて感動しました。早くここまでできるようになりたいです。 本当にありがとうございました。
romina

2022/05/27 08:59

度々すみません、アドバイスいただいたコードで書き直してみたのですが、こちらのコードについて、なぜかうまく表示されません。(最後にどうしても”,”(コンマ)がついてしまいます) お分かりになりますか? void hash_table_print(const hash_table_t *ht) { unsigned long int index; hash_node_t *temp; if (ht == NULL) return; printf("{"); for (index = 0; index < ht->size; index++) { for (temp = ht->array[index]; temp != NULL; temp = temp->next) { printf("'%s': '%s'", temp->key, temp->value); if (index < ht->size - 1 || temp->next != NULL) printf(", "); } } printf("}\n"); } int main(void) { hash_table_t *ht; ht = hash_table_create(1024); hash_table_print(ht); hash_table_set(ht, "c", "fun"); hash_table_set(ht, "python", "awesome"); hash_table_set(ht, "Bob", "and Kris love asm"); hash_table_set(ht, "N", "queens"); hash_table_set(ht, "Asterix", "Obelix"); hash_table_set(ht, "Betty", "Cool"); hash_table_set(ht, "98", "Battery Street"); hash_table_print(ht); return (EXIT_SUCCESS); }
jimbe

2022/05/27 11:00 編集

そのコードで最後に "," ということは、 array の構造が私が(ご質問でご提示されたコードから)想定したものとは違うということになります。 例えば、 array に null の個所がある場合です。 回答のコードでは array は table とは別として、 null が存在しないようにしています。 array に null が存在する場合、 index のループが最後かどうかで最後の表示かの判断は出来ません。(index が最後じゃなくても、現在の index より後にデータが無ければ今のが最後となりますよね。) ではどうすれば良いのか…を考えるのがプログラムを作る上で最も苦しくもあり楽しくもあり、「モノ作り」たるプログラミングの醍醐味の部分です。 各変数を表示して、どのような条件に一致・不一致となる為に表示されてしまうのか、そして、そうならないようにする為にどのような情報を得れば、もしくは作り出せばよいのか…。 回答に少し書いていますが、例えば先にデータの件数を数えておくとか、array の中で "最後に NULL では無い位置" を探しておくとかいうテがあります。 ( このように"最後"を扱うのは結構面倒なので、 maisumakun さんがご自身の回答のコメントで「1回目を判定するほうが最後を判定するより楽です」と仰っているのです。 )
guest

0

配列最後の要素だけコンマ", " をとって表示したい場合のコードですが

結果はそのようになりますが、コードの流れはそうではなく、「項目の前にコンマを打つけど、1回目だけはコンマを割愛」というようになっています。

投稿2022/05/26 14:02

maisumakun

総合スコア145192

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

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

romina

2022/05/26 14:17

早速ありがとうございます。 コード間違ってますか?(汗)すみません。。。 コードの流れという問題では無いことがよく理解できました。 今後、活用したいので伺いますが、 「項目の前にコンマを打つけど、1回目だけはコンマを割愛」がこのような書き方をする場合、 「項目の後にコンマを打つけど、最後だけはコンマを割愛」したい場合はどのような書き方をするのでしょうか? 参考までに教えていただけますか?
maisumakun

2022/05/26 15:10

> 「項目の前にコンマを打つけど、1回目だけはコンマを割愛」がこのような書き方をする場合、 「項目の後にコンマを打つけど、最後だけはコンマを割愛」したい場合はどのような書き方をするのでしょうか? 結果は同じなのですが、それでもあえて後者の書き方をしたいのですか?(1回目を判定するほうが最後を判定するより楽です)
romina

2022/05/26 16:11

いえ、すみません。 初めて見るので、どのような指示ができるのか、他に例を知りたかっただけです。すみません
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問