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

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

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

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

1384閲覧

自作spilit関数

linkinpark

総合スコア42

C

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/07/31 10:19

編集2021/08/01 02:01

C

1コード 2#include <stdio.h> 3#include <stdlib.h> 4#include <string.h> 5 6#define MAX_LENGTH 20 7 8int split(char *str,char *list[],const char delimiter){ 9 int index; 10 list[index++]=??? 11 while(?????){ 12 str++ 13 if(){ 14 *str="\0"; 15 ??????? 16 ??????? 17 } 18 } 19 return index; 20} 21 22int main(void){ 23 char str[]="One,Two,Three,Four"; 24 char *result[MAX_LENGTH]; 25 int length; 26 length=split(str,result,","); 27 for(i=0;i<length;i++){ 28 printf("%s\n",length[i]); 29 } 30 return 0; 31}

split関数を実装したいのですが??の部分がわかりません
strtok関数を使うのかなとは予想しているのですがどのように実装すればよいかがわかりません。
院試の過去問なのでコードもらいたいだけのように思われてしまうかもしれませんが、
頼れるところがないのでもしよろしければ教えていただけると幸いです
よろしくお願いいたします。

追記部分

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5#define MAX_LENGTH 20 6 7int split(char *str,char *list[],char delimiter){ 8 int index=0; 9 list[index++]=str; 10 while(*str!='\0'){ 11 str++; 12 if(*str==delimiter){ 13 *str='\0'; 14 str++; 15 list[index++]=str; 16 //printf("%s\n",list[index-1] ); 17 } 18 for(int i=0;i<index;i++){ 19 printf("%s\n",list[i]); 20 } 21 } 22 return index; 23} 24 25int main(void){ 26 char str[]="One,Two,Three,Four"; 27 char *result[MAX_LENGTH]; 28 int length; 29 length=split(str,result,','); 30 for(int i=0;i<length;i++){ 31 printf("%s\n",result[i]); 32 } 33 return 0; 34} 35

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/07/31 10:32

https://teratail.com/help/avoid-asking > コードをください・デバッグしてください等の丸投げの質問 > 何かを作りたいのでコードを書いてほしい、学校の課題を解いてほしい等の質問は、具体的にプログラミングで困っている質問ではないと考え、推奨していません。 > strtok関数を使うのかなとは予想しているのですがどのように実装すればよいかがわかりません 予想してるなら、関数のリファレンスやWebのサンプル調べながら書いてみればいいんじゃないですか? 他の部分のコードは自分で書いたんですか?どっかのサンプルコードのコピペですか?
otn

2021/07/31 10:35 編集

まずは、仕様を決めるところからですね。 と思ったけど、strは破壊して良いと言うことになっているのか。 それでは、strtokを使うので良いかと思います。
thkana

2021/07/31 10:40

他人に作らせたら「自作」じゃなくなっちゃいますね。ソコはいいのですか? そもそもが作るというより穴埋めみたいですが。
jimbe

2021/07/31 10:44

件名が「spilit」になっちゃってますが。
episteme

2021/07/31 10:53

仕様の確認: ",a,,b" を ','区切りで split すると "a", "b" ですか? それとも "", "a", "", "b" ですか?
yumetodo

2021/07/31 13:21

というか文字列分割ごとき、ありふれてるのでぐぐればいいのでは
dodox86

2021/07/31 13:39

最初の list[index++]のところで思いっ切りバグですね。穴埋めの元も合っている保証が無い感。
linkinpark

2021/07/31 15:56

皆さん未熟な自分に様々なアドバイスありがとうございます。 以降気を付けながら利用していきます。
jimbe

2021/07/31 17:58

>院試の過去問 これは過去問そのままでしょうか。それとも linkinpark さんがどこか書き込んでいるのでしょうか。 既に指摘されてます通り初歩的なバグがあり、このまま出題されたようには思えません。
linkinpark

2021/08/01 01:15

自分が穴埋めしたところはlength=split(str,result,",");のresultを穴埋めしただけになります。 ただ問題では文字列strを破壊的に分割してその文字列のリスト作成するとなっています。
episteme

2021/08/01 01:21

穴埋め? 自作じゃなかったん? ひと様に問題解かせてるってこと?
linkinpark

2021/08/01 01:44

すいません問題がそのような内容だったのでそう書きました。 誤解を生むような書き方でした。気を付けます。
episteme

2021/08/01 03:47

> 問題がそのような内容だったのでそう書きました。 要は「丸投げ」なんだ...
guest

回答3

0

ベストアンサー

穴埋めして一応動きますが、問題のあるコードです。

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5#define MAX_LENGTH 20 6 7int split(char *str,char *list[],char delimiter){ 8 int index=0; 9 list[index++]=str; 10 while(*str!='\0'){ 11 str++; 12 if(*str==delimiter){ 13 *str='\0'; 14 str++; 15 list[index++]=str; 16 } 17 } 18 return index; 19} 20 21int main(void){ 22 char str[]="One,Two,Three,Four"; 23 char *result[MAX_LENGTH]; 24 int length; 25 length=split(str,result,','); 26 for(int i=0;i<length;i++){ 27 printf("%s\n",result[i]); 28 } 29 return 0; 30}

投稿2021/07/31 18:14

編集2021/07/31 18:20
jimbe

総合スコア13209

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

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

linkinpark

2021/08/01 01:50

すいませんどのように問題があるのでしょうか? 実行するとちゃんと実行結果は出てきたのですが よろしければ教えて頂きたいです。
linkinpark

2021/08/01 02:01

One,Two,Three,Four One,Two,Three,Four Two,Three,Four One Two,Three,Four One Two,Three,Four One Two,Three,Four Three,Four One Two Three,Four One Two Three,Four One Two Three,Four One Two Three,Four One Two Three,Four Four One Two Three Four One Two Three Four One Two Three Four One Two Three Four One Two Three Four One Two Three Four
linkinpark

2021/08/01 02:04

printfでlistがどのように推移していくのかを調べていたのですが、 なぜlist[0],list[1]の値が変わっていくのが理解できません。 list[0]は最初に代入したあとは変更を加えていないように見えます。 何個も申し訳ないのですがよろしくお願いいたします。
kazuma-s

2021/08/01 02:43 編集

どこにどんな printf を入れたのか書かないと 表示だけ見せられても何のことやらわかりません。 あるいは、list[0] = 'One' のような表示にするとかしないと 何のことやらわかりません。
linkinpark

2021/08/01 02:39

書き忘れていましたが追加のプログラムは上の質問欄に記述されています。
kazuma-s

2021/08/01 02:57 編集

これは失礼。でも次のようにでもしないと分かりにくいですね。 for(int i=0;i<index;i++) printf(" [%d] %s ", i, list[i]); putchar('\n'); while (*str!='\0'){ の次に printf(" %c", *str); を入れておくとさらによいでしょう。
linkinpark

2021/08/01 03:27

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

2021/08/01 04:04 編集

> どのように問題があるのでしょうか 既に episteme さんの依頼コメントや kazuma-s さんの回答にも書かれていますが、つまり「最適な条件でしか考え/試されていない」ので、それ以外の場合にどうするのか/どうなるのかが分からないという点です。 "文字列分割"のような汎用的に使われるコードの場合、どこまで直感的に(分かり易く)使えるかも評価の一つです。(もちろん汎用的でないコードでも直感的なことは大事ですが。) 「2件以上のデータが含まれ、データは全て1文字以上である」場合だけでなく、区切り文字がどのように出現しても(しなくても)直感的に「こうなるだろう」という形で処理されることが評価されるということです。 "One,Two,Three,Four" では想定通り動作しましたが、",One,,Two,,,Three,Four," ではどうでしょう。 どのように分割されて list/result に入るのが正しいと思われますか。そして現状ではどのように分割されるでしょうか。
linkinpark

2021/08/01 04:21

本来なら One two three four となってほしいですがこのコードだと One ,Two ,,Three Four ということになってしまうということでよろしいですか?
jimbe

2021/08/01 05:15

「なってほしい」は linkinpark さんのお考えですし、「なってしまう」のはコードの実行結果ですので、事実確認としては「よろしい」ことになるでしょうか。 それで、その状況をどうするか、です。 試験問題ということですので、成否の判断は出題側にあります。問題があくまで「"One,Two,Three,Four"」を分割するコードを書くことであり、その他の文字列だったらどうするかは明記されていない=『無視』、と解釈すれば、提示させていただいたコードでも正解かもしれません。 ですが、文字列分割のコードは比較的安易な例としてあちこちに落ちていそうなレベルのもので(院試というのがどのくらいのプログラミング能力を試そうとしているのか分かりませんが)特定の文字列"だけ"を対象にしたコードで点が取れるようでは、そんな程度でいいのか・・・とさえ思ってしまいます。 エンジニアとしては、自身の知っている文字列分割の実装・機能をなるべく詰め込もうとするでしょう。当然、特定の文字列だけを処理するモノは作りません。仕事上そのような要件はありませんので。 (もし「"One,Two,Three,Four" を分割した形を何かに使用する」となれば、最初から char *list[]={"One","Two","Three","Four"}; を準備するでしょう。) "," 区切りというのは CSV 形式のファイルとして Excel でも使えるのでよく利用されます。その場合 ",,," となっていてもデータが無いということでは無く、文字列長 0 (="") のデータが 4 件という意味になります。 ですので ",One,,Two,,,Three,Four," は 9 件のデータとなり、開発の現場ではこのほうが一般的に思います。 しかし、linkinpark さんのお考えとは異なるようですので、どちらを取るかを決めなくてはなりません。 それが「仕様が…」と言われる所以です。
episteme

2021/08/01 05:48

↑とまぁ、このくらい(あるいはそれ以上の)考察を述べよ、とあるなら立派な院試問題になりそうねwww
linkinpark

2021/08/01 16:41

試験問題がその他の数学などもあるのでプログラミングの部分にそれほど時間がないため 多少荒い出題にはなっていると思います(笑) エンジニアの方の意見とても参考になりました。まだまだ未熟ですが精進していきます。
guest

0

元の質問では、, が先頭や末尾にあったり、途中に 2個以上連続したりした場合、
どのように分割するのかの仕様が曖昧です。
また、分割後の個数が MAX_LENGTH を超える場合への対応を考えたほうがよいでしょう。

C

1#include <stdio.h> // printf 2 3#define MAX_LENGTH 20 4 5int split(char *str, char *list[], char delimiter) 6{ 7 int index = 1; 8 for (list[0] = str; *str && index < MAX_LENGTH; str++) 9 if (*str == delimiter) { 10 *str = '\0'; 11 list[index++] = str + 1; 12 } 13 return index; 14} 15 16int main(void) 17{ 18 char str[] = ",One,Two,,Three,Four,"; 19 char *result[MAX_LENGTH]; 20 int length = split(str, result, ','); 21 for (int i = 0; i < length; i++) 22 printf("[%s]\n", result[i]); 23}

投稿2021/08/01 02:25

kazuma-s

総合スコア8224

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

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

linkinpark

2021/08/01 02:41

,が先頭や末尾にある場合は想定していませんでした。 MAX_LENGTHを超える場合はwhile文に記載することによって 回避します。
guest

0

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5#define MAX_LENGTH 20 6 7int split(char* str, const char* list[], const char* delimiter){ 8 int index = 0; 9 for ( const char* token = strtok(str, delimiter); token; token = strtok(NULL, delimiter) ) { 10 list[index++] = token; 11 } 12 return index; 13} 14 15int main(void){ 16 char str[] = "One,Two,Three,Four"; 17 char* result[MAX_LENGTH]; 18 int length = split(str, result, ","); 19 for ( int i = 0; i < length; i++ ) { 20 printf("[%s]\n", result[i]); 21 } 22 return 0; 23}

投稿2021/07/31 14:43

episteme

総合スコア16612

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

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

linkinpark

2021/07/31 15:59

返信ありがとうございます。 tokenには何が代入されていてまた、次にtoken = strtok(NULL, delimiter)を使用しているのは なぜか聞かせていただいてもよろしいですか?
linkinpark

2021/07/31 16:14

ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問