• ベストアンサー

strtokについて

ただ今、C言語の勉強中のヨッピーともうします。 今回質問させていただきたいのは、strtokについてです。 時間を格納している文字列 char time[] = "2007:10:18:22:30:55";//年月日時間 から不要な「:」を抜き出す作業を行っています。 ただ、抜き出して表示するのではなく、別の変数に「:」を抜かした 文字列を代入させたいのです。 char kakunou[16];     //用意した変数に kakunouに"20071018223055" //「:」が入っていない日付を入れたい 自分で調べましたら、strtokやstrtokenという関数が使用したらいいのではないことが分かりました。 どうしたら、不要な文字を抜かして新しい変数に代入できるでしょうか? また、他にいい方法がありましたら、strtokを使用しなくても大丈夫です。 よろしくお願いいたします。

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

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

int j = 0; for ( int i = 0; time[i] != '\0'; i++ ) {   if ( time[i] != ':' ) {     kakunou[j] = time[i];     j++;   } } kakunou[j] = '0'; strtokを使うのであれば char sep[] = ":"; char* tok; kakunou[0] = '\0'; tok = strtok( time, sep ); while ( tok != NULL ) {   strcat( kakunou, tok );   tok = strtok( NULL, sep ); } ライブラリ関数を使いたいならお使いのコンパイラのヘルプを確認しましょう

yoppy_c
質問者

お礼

strtokの例題を載せていただきまして、 ありがとうございます。 strtokをよく分かっていなかった事が判明しました。 文字列をNULL留めにされるので、2回に分けて行わないと できないんですね。 参考になりました。

その他の回答 (4)

回答No.5

  #include <stdio.h> int main(void) { char *time = "2007:10:18:22:30:55"; char str[16]; puts(time); sprintf(str, "%.4s%.2s%.2s%.2s%.2s%s", time, time + 5, time + 8, time + 11, time + 14, time + 17); puts(str); return 0; }

yoppy_c
質問者

お礼

回答ありがとうございます。 そうですね。sprintfもありました。 まだまだ考えが浅い事を実感しました。

noname#48699
noname#48699
回答No.4

不要な文字を抜かして新しい変数に代入したい、「どうしたら」できるかとのこと、 まず、 ★文字列がどのようにメモリ内に格納されているか、をイメージしましょう。 >char time[] = "2007:10:18:22:30:55"; の宣言(代入)ですので(char は8ビットで1文字)、 time[0]には、00110010(0x32)が入り、 time[1]には、00110000(0x30)が入ります。 ここまでは判りますよね、そして末端 time[19]には、00000000(0x00)がコンパイラによって入れられます。 《必要な知識:アスキーコード、c言語の文字列の扱い》 つぎに、 ★頭から、不要な文字(':'=0x3A)を抜かして 0x00が現れるまで順次、新たな変数に代入するだけ。 ・新たな変数の末端に自分で0x00をつける必要があることに注意。 または、結果からのひとつの「方法」として、0x30≦数字≦0x39 だけを代入し、末端に0x00をつける。 そこで、 ★strtok ですが、これは「不要な文字列」を指定して切り出す関数のようです(使用経験なし)が、例えば、 char time[] = "2007/10/18 22:30:55"; ということもあり、使いにくそう。 というか、 【結論】関数を探すのではなく、自分で関数を《作る》気概で勉強すれば・・・。 と思います(今年でC言語はじめてちょうど20執念・・いやいや周年)。

yoppy_c
質問者

お礼

イメージがあまり掴めていませんでした。 ちゃんと、どう動いているのかを把握しながらやるのが大切なんですね。 大変参考になりました。 私も執念を重ねて行こうと思います。

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

★単純に『:』文字以外を別の配列にコピーすれば良い。だけ。 ・配列とか、文字列とかに理解していますか?  分かれば strtok 関数は使わずに出来ます。  下にサンプルを2つ載せておきます。 サンプル1: char time[] = "2007:10:18:22:30:55"; //年月日時間 char kakunou[ 16 ]; //用意した変数に int i; for ( i = 0 ; time[i] != '\0' ; i++ ){  kakunou[ i ] = time[ i ]; // 全部ならコピー } kakunou[ i ] = '\0'; サンプル2: char time[] = "2007:10:18:22:30:55"; //年月日時間 char kakunou[ 16 ]; //用意した変数に int i, j; for ( j = i = 0 ; time[i] != '\0' ; i++ ){  if ( isdigit(time[i]) ){   kakunou[ j++ ] = time[ i ]; // 0-9 文字ならコピー  } } kakunou[ j ] = '\0'; 解説: ・サンプル1はそのままを time → kakunou 配列にコピーしています。  サンプル2は数字文字を time → kakunou 配列にコピーしています。  ifの条件は『:』文字以外と判定しても良いです。  今回は 0-9 の文字を isdigit 関数で判別しています。 ・以上。ちなみに ctype.h をインクルードしないと isdigit は利用できません。

yoppy_c
質問者

お礼

2つも例題を下さりありがとうございました。 色々な考え方がありますね。 isdisitを使用した事がなかったので、参考になりました。

  • a-saitoh
  • ベストアンサー率30% (524/1722)
回答No.1

先頭からfor分で1文字ずつ見ていけばいいでしょう。 strtokを使ったほうが面倒です。

yoppy_c
質問者

お礼

ありがとうございました。 for分と、strtok両方作って見ることにします。

関連するQ&A

  • strtok()について

    c言語にてstrtok()を使用しています。 以下の型をグローバル変数で宣言し、 (ヘッダ) typedef struct { char *pTmp; int len; } stAAA; (.cソース) stAAA stA; ある関数にてmalloc()によりstA.pTmpに動的に領域を割り当て、 "ABCDEFG:ABCDEFG:ABCDEFG:"という値を格納するとします。 その後他関数にてstA.pTmp内の":"をトークンとしstrtok()で 切り出す場合、stA.pTmpを切り出し後もアドレス移動させたく ないため strtok()使用関数にて以下のようにしたのですが・・・・ グローバル変数のアドレスが操作されてしまいます。 どうすればよいでしょうか?strtok()用にmalloc()する? int test(){ char *pTmp; char *pTok; pTmp = stA.pTmp; while ((pTok = strtok(pTmp, ":")) != NULL) { : : } }

  • strtok

    strtokにて分解した文字を各変数に格納する場合 char *p; FILE *fp; char buf[1000]; if((fp = fopen("○","r"))==NULL){ return 0; } if(!fgets(buf,1000,fp)) return 0; strcpy(p, buf); number = strtok(p,","); class_type = strtok(NULL,","); name = strtok(NULL,","); subject = strtok(NULL,","); と一行の文字列を各変数に格納しています。 ファイルの一行は以下のような形式になっています。 1,A,山田,数学//番号,クラスタイプ,名前,得意教科 これで各値は変数に格納できています。 しかし このファイルはCSVファイルなのですが、空の欄があると 1,A,,数学というデータがbuf内に入っています。 この場合 number→1 class_type→A name→数学 と空欄の箇所が飛ばされてしまっています。 改善する方法がわからないのですが strtokを使わない方がいいのでしょうか?

  • c#でC言語のstrtokに相当する関数は何か

    文字列から指定した文字でデータを区切る関数strtokがC言語にはある これに相当するC#の関数は何か 例えばCでは以下のように書く。 char data1[]= " 123 , 456 Yamada " ; char *token ; strtok( data, " ," ) ; /* スペースとカンマを区切りに文字列を抽出 */ token = strtok( str, " ." ); printf(" token chat = %s\n", token ) ; while ( token != NULL ) { token = strtok( NULL," ." ); if ( token != NULL ) printf(" token chat = %s\n", token ) ; } これに相当するc#のSplit関数を使用すると 不要な空白を取り出しているようである 知っている方がおりましたら、教えて下さい。

  • strtok

    strtokの問題というよりも、文字列とポインターの考え方がまだちゃんと分かってないせいだとは思うんですが、strtok()のところで、Access Violationとでます。すごく単純そうな問題だとは思いますが、教えてください。お願いします。 #include <iostream.h> #include <string.h> int main() { char *chk = "3453/5252"; char *tokenPtr; tokenPtr = strtok(chk, "/"); while (tokenPtr != NULL) { tokenPtr = strtok(NULL, "/"); } return 0; }

  • CHAR型ポインタについて。

    CHAR型ポインタについて。 当方C言語初心者です。 ポインタと文字列の関係分からないことが出てきました。 参考にしている本があり、そのページに下記のソースで「const char *pc1」のポインタ変数を用意して、そこに直接文字列を代入しています。 本来、「char *pc1」はchar型のアドレスを格納するための変数のはずなのに、その変数に文字列を代入してることに疑問を感じました。 この記述の仕方は間違っていないのでしょうか?また、アドレスを格納するための変数「*pc1」に「abcdefg」の文字列はどのようにメモリ上で格納されているのでしょうか? 知ってどうなるの?みたいな質問かもしれませんが、ご教授いただけると幸いです。 #include <stdlib.h> #include <string.h> void func(void) { const char *pc1 = "abcdefg"; //←ココ char *pc2 = (char *)malloc( strlen(pc1) +1); if ( pc2 ) { strcpy( pc2, pc1 ); free( pc2 ); } }

  • strtokのしくみについて

    よろしくお願い致します。 strtokは以下のように使いますよね。 (と言っても今回初めて使うのですが) 1回目はstrを渡しているので自然ですが、2回目以降はNULLですよね。なのにどうしてstrを続けて分解するということが出来るのでしょうか? うまく説明できませんが、要はstrtokはどういうコードで実現されているのでしょうか? int main(void) { char str[] = "ABCD ef.1234.G"; char *tp; /* スペース.を区切りに文字列を抽出 */ tp = strtok( str, " ." ); puts( tp ); while ( tp != NULL ) { tp = strtok( NULL," ." ); if ( tp != NULL ) puts( tp ); } return 0; }

  • 文字を16進変換

    C言語にて関数などを使わずに計算式なので文字を16進数に変換したいのですがどのような処理にしたらいいでしょうか?? char型で用意した変数に1文字を格納し、それをアスキーコードの16進数に変換したいです。 よろしくお願いします。

  • C言語 strtok

    現在CSVファイルを読み込み多次元配列に格納しているのですが1行をstrtokで区切ってしまうと空白を無視してしまい、困っています。 例"xxx","","yyy","" のような文字列、空白、文字列があるとして空白は空白で読み込みたいです。 説明が下手ですいませんがなにかいい方法がありましたらご教授頂きたいです。 よろしくお願い致します。。

  • getchar,isalphaについて

    C言語を習いはじめてまもない者です。getcharとisalphaについて教えてください。  まず、getcharから。この関数は、キーボードから文字を一文字ずつ読み、読み出した文字を返す。といった働きをするそうですが、この関数を用いて、取り込んだ文字をなぜか、int型で宣言した変数に代入しています。(例:int aなどのaに取り込んだ文字を代入している。)なぜ、文字を取り込んでいるのに、intで宣言した変数に代入すのでしょうか?charで宣言した変数に代入しなくていいのですか?  次に、isalphaについてです。この関数は、変数に代入されている文字が数字か文字かを判断して、文字が入力されていると、0以外の値を返す関数だそうです。しかし、この関数も、変数の宣言がintです。なぜ、charではなくintで宣言するのでしょうか?

  • 【c++】文字列の操作

    お世話になります。 テキストの操作について質問があります。 getline関数を使用してテキストの1行分を読み込み その文字列をstrtok関数を使用し区切り文字ごとに配列に入れたいと考えています。 ですがgetlineはstd::string型の変数が必要でstrtok関数はchar型しか受け付けないため 関数同士で型が合わず困っています。 何とか型を合わせる方法は無いでしょうか。 以下にソースコードを記載しますのでご指導お願いします。 int main(){ using namespace std; string strText; char chArray[100]; ifstream fs("test.txt"); //パスで指定されたファイルから1行分の文字列を取得する while( getline(fs , strText , '\n') ){ //区切りごと配列に入れたい chArray = strtok(strText , ","); } }

専門家に質問してみよう