• 締切済み

Cで文字列の分割

ある文字列を5文字ずつ抜き出だすC言語のプログラムを作りたいのですが, なかなか苦戦しています. どなたかご教授頂けるとたすかります. ちなみに,使っているデータ国土地理院発行の火山10mメッシュデータで,こんな感じです・・・ -9999-9999-9999-9999 1255 1259 1257 1252 1245 1238 1231 1224 1218 1メッシュが整数値5文字で表されており,それが1000個横に並んでいます.全てのメッシュの間にスペースがあれば楽なのですが,それがない時もあります・・・ よろしくお願いします.

みんなの回答

  • yama5140
  • ベストアンサー率54% (136/250)
回答No.8

>国土地理院発行の火山10mメッシュデータ  国土地理院発行の「テキスト」データは、FORTRAN言語の書式仕様で作られていますよね。    Cで、これに相当する書式を探せばよいかと。      I5 → %5d    http://www.k-cube.co.jp/wakaba/server/format.html >1メッシュが整数値5文字で表されており,それが1000個横に並んでいます.  若干手を加えられ、独自仕様にされたのかな?。  ソースを投稿します。仕様、レコード数に合わせてお試し下さい。  (BorlandC++5.6.4) 蛇足  10cm単位の整数位ですので、データの格納に short は無理です。  (読み込みは現状の int で(-9999 を 0 とし) unsigned short にキャストすれば、富士山も可能) #include <stdio.h> int  main() {   FILE  *fp;   int  iSpace, iRecNo, iRaw, iCnt;   int  iVal[ 20 ][ 1000 ];  // 20レコード分   fp = fopen( "Z:\\Mesh.lem", "r" );   if( NULL == fp ) return( -9 );   while( 1 == fscanf( fp,"%6d", &iSpace ) ){  // 空き容量     fscanf( fp,"%4d", &iRecNo );  // レコード番号     printf( "%6d %4d\n", iSpace, iRecNo );     iCnt = 0;     while( 1 == fscanf( fp,"%5d", &iRaw ) ){       iVal[ iRecNo ][ iCnt++ ] = iRaw;       if( 1000 <= iCnt )  break; // 次のレコードへ     }   }   fclose( fp ); //  処理   return( 0 ); } 注:インデントに全角空白を用いています。タブに一括変換して下さい。

全文を見る
すると、全ての回答が全文表示されます。
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.7

文字数で取得しないといけないようです 火山の標高データを10cm単位の数値で表しているようです 1000mの場合 10000 100mの場合 1000 となるので 100m,1000m,100m のデータは _100010000_1000 となるようです # _ はブランク(空白) # Fortranで出力しているようです 当方のサンプル #define MAXARRAY 1000 /// GetData /// pSrc : 分割文字列 /// nStep : 分割文字数 /// pDest : 分割文字列格納配列 /// nMax : 分割文字列格納配列の最大値 int GetData( char* pSrc, int nStep, char* pDest[], size_t nMax ) {   size_t n, nCnt, nLen;   char buf[32], *p = NULL;   nCnt = ( nLen = strlen( pSrc ) ) / nStep;   if ( nCnt > nMax ) nCnt = nMax;   nCount = 0;   // %.5s を生成   sprintf( buf, "%%.%ds", nStep );   for( n = 0; n < nCnt; n++ ) {     sprintf( pDest[n], buf, &pSrc[ n * nStep ] );     // 先行スペースの削除     p = pDest[n];     while( *p == ' ' )       p++;     if ( p != pDest[n] ) {       sprintf( pDest[n], "%s", p );     }   }   return nCnt; } int main(int argc, _TCHAR* argv[]) {   char chSrc[] = {"-9999-9999-9999-9999 1255 1259"     " 1257 1252 1245 1238 1231 1224 1218"};   char chDest[MAXARRAY][6];   char* p1[MAXARRAY];   int nCnt, n;   memset( chDest, 0, sizeof( chDest ) );   for( n = 0; n < MAXARRAY; n++ ) {     p1[n] = chDest[n];   }   nCnt = GetData( chSrc, 5, p1, 1000 );   for( n = 0; n < nCnt; n++ ) {     printf( "%3d:%s\n", n, chDest[n] );   }   return 0; }

全文を見る
すると、全ての回答が全文表示されます。
回答No.6

  >5文字は無視して数値が空白か-記号のみで区切られていると保証されているなら  残念ながら、 >全てのメッシュの間にスペースがあれば楽なのですが,それがない時もあります・・・ です。

全文を見る
すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.5

> ある文字列を5文字ずつ抜き出だす という仕様からすると、結果は文字列でないとまずいのではないだろうか。 もし結果は整数値であるとすると、#3でsscanf()した結果を直接int型の配列に入れてしまえばよい。

全文を見る
すると、全ての回答が全文表示されます。
  • php504
  • ベストアンサー率42% (926/2160)
回答No.4

5文字は無視して数値が空白か-記号のみで区切られていると保証されているなら #include <stdio.h> #define MAX_DATA 1000 int mesh_data[MAX_DATA]; int main(void) { FILE* fp; int i = 0; fp = fopen("test.txt", "r"); if (!fp) { printf("file open error\n"); return 0; } while (!feof(fp)) { fscanf(fp, "%d", &mesh_data[i]); printf("%d\n", mesh_data[i]); if (++i >= MAX_DATA) { break; } } fclose(fp); return 0; }

全文を見る
すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.3

当該データのフォーマットが絶対に崩れないのであれば、 #include <stdio.h> int main(void) { char s[] = "-9999-9999-9999-9999 1255 1259 1257 1252 1245 1238 1231 1224 1218"; char str[1000][6], *p = s; int n, i; for (i = 0; i < 1000 && *p; i++, p += 5) { if (sscanf(p, "%5d", &n) == 1) { sprintf(str[i], "%5d", n); printf("'%5s'\n", str[i]); } } return 0; }

全文を見る
すると、全ての回答が全文表示されます。
回答No.2

   この方がいいのかな? #include <stdio.h> #include <ctype.h> #define MAX 20 int Split(FILE *fp, char table[][6], int n) { int c, i = 0, j = 0; while((c = fgetc(fp)) != EOF){ if(isdigit(c)){ table[i][j] = c; table[i][++ j] = '\0'; j %= 5; if((i += !j) >= n) break; } } if(i < n) table[i][0] = '\0'; return i; } int main(void) { FILE *fp = fopen("test.dat", "r"); char table[MAX][6]; int i, j; if(!fp) return 1; j = Split(fp, table, MAX); for(i = 0; i < MAX && table[i][0]; ++ i) puts(table[i]); printf("(DATA : %d)\n", j); fclose(fp); return 0; }   "test.dat" -99999-9999999999-99999 12355 1235912357 12352 12345 12338123311232412318  

全文を見る
すると、全ての回答が全文表示されます。
回答No.1

#include <stdio.h> #include <ctype.h> #include <string.h> #define MAX 20 int Split(char *str, char table[][6], int n) { char *p = str + strlen(str); int i; for(i = 0; i < n && str < p; i ++){ while(!isdigit(*str)) str ++; sprintf(table[i], "%.5s", str); str += 5; } if(i < n) table[i][0] = '\0'; return i; } int main(void) { char *str = "-99999-99999-99999-99999 1235512359 1235712352 12345 12338123311232412318"; char table[MAX][6]; int i, j; puts(str); j = Split(str, table, MAX); for(i = 0; i < MAX && table[i][0]; i ++) puts(table[i]); printf("(DATA : %d)\n", j); return 0; }

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • C言語の文字列操作について

    C言語について質問です。 整数を入力させ、その入力された整数に’1’が含まれているかどうかを調べるプログラムを作りたいのですが、うまくできません。 文字列操作を使えばよいのですかね? 可能であればプログラムを書いていただきたいです。

  • 文字列の部分読み込み

    C言語によるプログラムを勉強中なのですが、分からないことがあるので質問させてください。 「fgets」を用いてファイルから一行分の文字列を読み込んだのですが、この文字列の○文字目から×文字目を読み込む関数などはあるのでしょうか? もし無ければ、どのようにしたら読み込めるのでしょうか? 読み込んだ文字列は □□□□1234□□□5678□□abcd のようなもので、□は半角のスペースです。 区切り文字などが無く、先頭の半角スペース部分に文字が入る場合もあるので、○文字目から×文字目のように指定したいと思っています。 初心者で申し訳ありませんが、よろしくお願いいたします。

  • 教えていただけませんか?C言語 文字列について

    学校で文字列のプログラムを組む課題が出ました 以下のような課題です 1つの文字列を読み込んで,ピリオドで改行し出力するプログラムを作成しろ ・読み込む文字列の長さ 最大で80文字 ・文字列の終わりは必ずピリオドで ・文字列の途中に現れるピリオドの次には必ずスペースが続く ・ピリオドに続くスペースは出力しない 例えば Hello. It is fine. Good-bye.  と打つと Hello. It is fine. Good-bye. と表示されるようなプログラムです そして自分で以下のプログラムを組みました ----------------------------------------------------------- #include <stdio.h> #include <string.h> int main(void){ int i; char A[100]; char *a; fgets(A,80,stdin); a = strtok(A, "."); printf("%s.\n",a); while(a != NULL){ a = strtok(NULL,"."); if (a != NULL){ printf("%s.\n",a); } } return 0; } --------------------------------------------------------------- ですがこれだとピリオドの後のスペースと文字列の後によくわからない改行が出力されてしまいます 自分で何とかするべきなのでしょうがどうにもうまく行きません どこをどうすればいいのか教えていただけないでしょうか?

  • 文字列を数列に変換

    文字列(アルファベットのみ)を数列に変換するプログラムを作りたいのですが、うまくいきません。 [A = 01、B = 02、~ Z = 26、 Space = 00]とし、例えば入力が「ADAM」であれば、出力は「01040113」となるようなプログラムです。A~Z以外の文字(!, ?, @, 1, 2など)は無視します。 ちなみに言語はJavaです。 誰かご教授いただけないでしょうか?

    • ベストアンサー
    • Java
  • 整数を文字列として認識したい

    整数を文字列として認識したいんですが、可能なのでしょうか? 例えば、i=12470というint型の整数があるとして、1万の位の数1や、十の位の数7だけを取り出したいんです。 しかし、この際、1万の位の数1をi/10000、十の位の数7を(i%100)/10などというようにしては取り出したくないんです。 ややこしい質問ですが、よろしくお願いします。 というのも、整数を文字列として認識する目的は、int型として送られてきたデータが本当に整数なのかをチェックするためだからです。 初心者なので合っているか分かりませんが、整数を文字列として認識できれば、isdigit関数を使うことで、データが本当に整数なのかをチェックすることができるのかなあと考えているんですが・・・ もし、私の考えが間違っていたり、他に良い方法があったら是非教えて欲しいと思います。

  • 改行コードを含む文字列の分割について

    Java初心者です。 Java言語で、ある文字列を"\r\n"だけを区切り記号として別々の文字列にしたいのですがうまくいきません。 StringTokenizerを使って、 StringTokenizer(msg,"\\r\\n") のようにやって見たのですが、これだと"\r"や"\n"まで区切り記号として分割されてしまいました。 "\r\n"だけを区切り記号として処理するにはどうしたらいいでしょうか? 例えばPOSTで送信した"データ1\r\nデータ2\r\nデータ3\nテスト"という文字列を、 "データ1"、"データ2"、"データ3\nテスト"の3つにしたいのですが。

    • ベストアンサー
    • Java
  • C言語で整数を文字列へ型変換

    C言語で整数を文字列へ型変換 int result[11]; const char *tmp; resultの中の11個の数字を 1,2,3,4,5,6,7,8,9,10,11 のような文字列にして、tmpへ代入したんですが、やり方が分かりません。 Cの初心者ですので、教えていただきたいです。

  • 整数型の配列に a,b,c,: などの文字を入れたら・・・

    整数型の配列に整数データを格納するプログラムで、 入力時に文字を入力してしまった場合、 エラーチェックを行いたいのですが、 具体的にどのような方法があるのでしょうか? 文字を入力した場合に、 とてつもないことがDos画面でおこってしまいます。 どうか皆さん、よろしくお願いします。 言語はC言語で、 visualC++6.0を使っています。

  • 文字列

    C言語初心者です。プログラムについて質問なのですが、テキストファイルからある文字列(アルファベットではなく日本語)を探すにはどのようにすればいいのですか?

  • 大文字の文字列→小文字の文字列

    C言語初心者です。 ある演習問題をやっていて詰まっています。 自分で入力した大文字の文字列を小文字にするプログラムを作るという問題なのですが、↓の条件があり、こんがらがってしまいました。 ・入力した文字列に小文字が含まれていたら、エラーと表示して再び入力を促し、0を入力するとプログラム終了という流れにする。 ・ポインタ変数を使う。 ・continue文を使う。 ・標準ライブラリ関数は使わない。 です。 ・continue文というのがよくわからない。 ・宣言した関数でどの処理をすればいいのかわからない。 ・大文字を小文字にするというプログラムがわからない。 (アスキーコードをどう使うのか) でつまっています。 どなたかアドバイス・解説・模範解答・指摘などしていただけないでしょうか。 よろしくお願い致します。

このQ&Aのポイント
  • BJC-5500jはWindows10に対応していますか。
  • Windows10でBJC-5500jを使用するためのドライバーについて教えてください。
  • Windows10でのBJC-5500jの動作保証について知りたいです。
回答を見る

専門家に質問してみよう