プログラムの条件分岐による値の省略方法について

このQ&Aのポイント
  • プログラムでG01X30Y30を実行すると直線が引かれますが、GやXが省略された場合に前回の値を使いたい場合、どのように変更すればいいのでしょうか。
  • 現在のプログラムでは、Gの値が省略された場合には前回の値が使われない仕様になっています。GやXが省略された場合に前回の値を使うように変更する方法を教えてください。
  • プログラムでG01X30Y30を実行すると直線が引かれますが、GやXが省略された場合には前回の値を使いたいです。現在のプログラムではそのような処理は行われませんので、どのように変更すればいいのか教えてください。
回答を見る
  • ベストアンサー

プログラム

{ FILE *fp; char *str,buf[1000];   char subbuf[100],*s1; char buf2[100],*s2;   char buf3[100],*s3; char buf4[100],*s4; static double bx=0; static double by=0; if ((fp = fopen("test.txt", "r")) == NULL) { printf("ファイルが開けません\n"); return EXIT_SUCCESS; } while (fgets(buf, 1000, fp) != NULL) { str=buf;        while((*str!='\0'){ if(*str!='\0' && *str=='G'){ *str++; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) s2=buf2; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) while(*str!='\0'&&(isdigit(*str) || *str=='-' || *str=='.')) *s2++=*str++; *s2='\0'; } if(*str!='\0' && *str=='X'){ *str++; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) s3=buf3; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) while(*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) *s3++=*str++; *s3='\0'; } if(*str!='\0' && *str=='Y'){ *str++; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) s4=buf4; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) while(*str!='\0' &&(isdigit(*str) |*str=='||*str=='.')) *s4++=*str++; *s4='\0'; } CDC *v; v=GetDC(); if((int)atof(buf2)==92){ MoveTo((int)atof(buf3),(int)atof(buf4)); bx=(int)atof(buf3); by=(int)atof(buf4); ReleaseDC(v); } else if((int)atof(buf2)==01){ MoveTo((int)bx,(int)by); LineTo((int)atof(buf3),(int)atof(buf4)); bx=(int)atof(buf3); by=(int)atof(buf4); ReleaseDC(v); } else str++; } } fclose(fp); return 0; } という風なプログラムになっているのですが 今現在 G01X30Y30 G01X30Y120というファイルをこのプログラムにて実行すると (0,0)→(30,30)→(30,120)というような直線が引かれます。 しかしこれを G01X30Y30 Y120 とかかれたときも同様の結果がでるようにしたいです。 つまり最初のG○○が省略されているときは前回のGの値を X○○が省略されているときは前回のXの値を使うように 変更したいのですがどのように変更すればいいのかがわかりません。 教えてください。

  • zaqwe
  • お礼率15% (19/123)

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

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

「その行で G?? などが指定されているかどうか」をフラグで持つ. もちろん実際にフラグを新たに導入してもいいし, 「フラグの代わりになるもの」を使ってもいい. でも, 全体を見て思うんだけど strtod を使ったらもっと簡単にならんか?

zaqwe
質問者

お礼

解決しました感謝です。

関連するQ&A

  • プログラム

    { FILE *fp; char *str,buf[1000]; char xbuf[100],*xstr;   char ybuf[100],*ystr; static double bx=0; static double by=0; if ((fp = fopen("kadai.txt", "r")) == NULL) { printf("ファイルが開けません\n"); return EXIT_SUCCESS; } while (fgets(buf, 1000, fp) != NULL) { str=buf;        while((*str!='\0'){ if(*str!='\0' && *str=='X'){ *str++; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) xstr=xbuf; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) while(*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) *xstr++=*str++; *xstr='\0'; } if(*str!='\0' && *str=='Y'){ *str++; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) ystr=ybuf; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) while(*str!='\0' &&(isdigit(*str) |*str=='||*str=='.')) *ystr++=*str++; *ystr='\0'; } else str++; } pDC->MoveTo((int)bx,(int)by); pDC->LineTo((int)atof(xbuf),(int)atof(ybuf)); bx=(int)atof(xbuf); by=(int)atof(ybuf); } } fclose(fp); return 0; } とテキストファイルを読み込みその中のXとYに付属する値を 取り出し図形を書くというプログラムなのですが X100Y100 X200Y100というファイルなら (0,0)→(100,100)→(200,100)という2つの直線が描かれます。 実行の結果正常に動きました。 str=buf; の部分ではbufの先頭要素のアドレスをstrに設定している のはわかりました。 しかしxstr=xbufの所ではわからないことがあります。 bufでfpから読み込んだ文字列1行が入っているのはわかります。 しかしxbufにはまだ何も入ってないはずなのに xstr=xbufの所でxbufにはxの値がしっかり入っていました。 これはどうしてでしょうか xbufとかybufとかいらないような気もするのですが もしそうならばどのように書き直せばいいのでしょうか? この2点について教えてください。

  • プログラム

    以前ファイルからXとYの値だけ取り出し図形を作る質問をした者ですが void Ctest::OnOK() { FILE *fp; char *str,buf[1000];     char buf3[100],*s3; char buf4[100],*s4; if ((fp = fopen("test.txt", "r")) == NULL) { printf("ファイルが開けません\n"); return EXIT_SUCCESS; } while (fgets(buf, 1000, fp) != NULL) { str=buf;        while((*str!='\0'){ if(*str!='\0' && *str=='X'){ *str++; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) s3=buf3; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) while(*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) *s3++=*str++; *s3='\0'; } if(*str!='\0' && *str=='Y'){ *str++; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) s4=buf4; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) while(*str!='\0' &&(isdigit(*str) |*str=='||*str=='.')) *s4++=*str++; *s4='\0'; CDC *v; GetDC(); MoveTo(0,0); LineTo(atof(buf3),atof(buf4)); ReleaseDC(v); } else str++; } } fclose(fp); return 0; } でコンパイルはできるのですが直線の作図がされません。 どこが間違ってるのでしょうか。VC+6.0のMFC使ってます

  • 関数

    FILE *fp; char *str,buf[1000]; char xbuf[100],*xstr;   char ybuf[100],*ystr; static double bx=0; static double by=0; if ((fp = fopen("kadai.txt", "r")) == NULL) { printf("ファイルが開けません\n"); return EXIT_SUCCESS; } while (fgets(buf, 1000, fp) != NULL) { str=buf;        while((*str!='\0'){ if(*str=='X'){ *str++; if(isdigit(*str) || *str=='-' || *str=='.') xstr=xbuf; if(isdigit(*str) || *str=='-' || *str=='.') while(isdigit(*str) || *str=='-' || *str=='.')*xstr++=*str++; *xstr='\0'; } if(*str=='Y'){ *str++; if(isdigit(*str) || *str=='-' || *str=='.') ystr=ybuf; if(isdigit(*str) || *str=='-' || *str=='.') while(isdigit(*str) |*str=='||*str=='.') *ystr++=*str++; *ystr='\0'; } else str++; } } ファイルからの一行の切り分けのプログラムなのですが if(*str=='X'){ *str++; if(isdigit(*str) || *str=='-' || *str=='.') xstr=xbuf; if(isdigit(*str) || *str=='-' || *str=='.') while(isdigit(*str) || *str=='-' || *str=='.')*xstr++=*str++; *xstr='\0'; } の部分と if(*str=='Y'){ *str++; if(isdigit(*str) || *str=='-' || *str=='.') ystr=ybuf; if(isdigit(*str) || *str=='-' || *str=='.') while(isdigit(*str) |*str=='||*str=='.') *ystr++=*str++; *ystr='\0'; } の部分は変数が違うだけでほとんど同じ文ですよね。 関数を作ってこの処理のときに呼び出せれば応用が利くと思い 考えてみたのですが中々できません。よろしければ教えて下さい。 まだ戻り値や関数の理解が今ひとつです。

  • プログラムが止まってしまいます

    Visual Studio 2012 c++ でプログラムを動かそうと思っているのですが、デバッグ開始すると画像のようなウィンドウが出て実行途中で止まってしまいます。 呼び出し履歴のint mqoLoadFileのソースを貼ります. int mqoLoadFile( MQO_OBJECT *mqoobj, char *filename, double scale, unsigned char alpha) { FILE *fp; MQO_OBJDATA obj[MAX_OBJECT]; MQO_MATDATA *M = NULL; char buf[SIZE_STR]; // 文字列読み込みバッファ char path_dir[SIZE_STR]; // ディレクトリのパス char path_tex[SIZE_STR]; // テクスチャファイルのパス char path_alp[SIZE_STR]; // アルファテクスチャファイルのパス int n_mat = 0; // マテリアル数 int n_obj = 0; // オブジェクト数 int i; // MaterialとObjectの読み込み fopen_s(&fp,filename,"rb"); if (fp==NULL) return 0; mqoobj->alpha = alpha; memset(obj,0,sizeof(obj)); i = 0; while ( !feof(fp) ) { fgets(buf,SIZE_STR,fp); // Material if (strstr(buf,"Material")) { sscanf_s(buf,"Material %d", &n_mat); M = (MQO_MATDATA*) calloc( n_mat, sizeof(MQO_MATDATA) ); mqoReadMaterial(fp,M); } // Object if (strstr(buf,"Object")) { sscanf_s(buf,"Object %s", obj[i].objname);//ココの実行中に止まる mqoReadObject(fp, &obj[i]); i++; } } n_obj = i; fclose(fp);

  • このプログラムは

    どこかおかしいですか? int main(void){ FILE *str; char buf[1000]; if((fp=fopen("ファイル名","r"))=NULL){ printf("ファイルが開けません"); return EXIT_SUCCESS; } while(fgets(buf,1000,fp) !=NULL){ str=buf; printf("%s",buf); } return EXIT_SUCCESS; } で実行すると前半4割程度が表示されません。 何故だかわかる人いませんか? 使用言語:C言語 環境:visualC++6.0 のコンソールアプリケーション。

  • ファイル

    ファイルを読み込み単語ごとに表示するプログラムです。 例 ファイル データ 形式 歴史・・ のように単語の後には空白がありますファイルです FILE *fp; char buf[1000]; char buf_word[1000]; char *str; char *bufstr; if((fp = fopen("test.txt","r")) == NULL){ printf("error!"); return 0; } while(fgets(buf,1000,fp) !=NULL){ str = buf; while(*str !='\0'){ strbuf = buf_word; if(*str ==' '){ printf("%s",buf_word); } else{ *strbuf++ = *str++; } } } とプログラムしてみましたが*strの値がどうもおかしく 最初が "フ" じゃなく"・"になってます。 最初の単語がG11とかなら"G"になっていますが・・ 教えて下さい。

  • ファイルを読み込むプログラムについて

    下のプログラムで分からない所がありますので、教えて頂ければと思います。宜しくお願い致します。 text = fgets(buf,256,fp);はfpのファイルから一行を読み込んでbufに格納するという処理ということは分かります。でも、while文内なので次にこの処理をする時に今度は、2行目(下の段)を読み込むはずですが、プログラム中のどこに2行目に移動させる処理があるのか分かりません。 予想ですが、text = fgets(buf,256,fp);の中にそのような意味の処理が含まれているのでしょうか? どなたかご教授お願い致します。 #include <stdio.h> int main(void) { FILE *fp; char buf[256]; char *text; char flname[256]; printf("ファイル名:"); gets(flname); fp = fopen(flname,"r"); do{ text = fgets(buf,256,fp); if(text != NULL){ printf("%s",text); } }while(text != NULL); fclose(fp); return(0); }

  • 迷路を解くプログラムについて

    迷路を脱出する経路を探索するプログラムを作成したいのですが、 何をすればいいのかまったくわかりません 以下のプログラムはあるんですが、このプログラムを改良していくということなんでしょうか?左上からスタートして右下がゴールらしいのですがやり方教えてください #include <stdlib.h> #include <stdio.h> #include "List.h" #define LEN 256 int maze[LEN][LEN]; void readMaze(char* filename, int *w, int *h, int maze[LEN][LEN]) { FILE *fp; int x, y; if (0 != fopen_s(&fp, filename, "r")) { fprintf(stderr, "指定された迷路の入力ファイルを開くことができませんでした.\n"); exit(-1); } fscanf_s(fp, "%d,%d\n", w, h); for (y = 0; y < 2 * *h + 1; y++) { for (x = 0; x < 2 * *w + 1; x++) { fscanf_s(fp, "%d%*[^-0-9]", &(maze[y][x])); } } fclose(fp); } void writeMaze(char* filename, int w, int h, int maze[LEN][LEN]) { FILE *fp; int x, y; if (0 != fopen_s(&fp, filename, "w")) { fprintf(stderr, "指定された迷路の出力ファイルを開くことができませんでした.\n"); exit(-1); } fprintf_s(fp, "%d,%d\n", w, h); for (y = 0; y < 2 * h + 1; y++) { for (x = 0; x < 2 * w + 1; x++) { fprintf_s(fp, "%d", maze[y][x]); if (x < 2 * w) { fprintf_s(fp, ","); } else { fprintf_s(fp, "\n"); } } } fclose(fp); } // シンプルなバージョン:なるべく右下へ行けるなら右下へ int main(int argc, char** argv) { int w, h; int x, y; if (argc < 3) { fprintf(stderr, "迷路の入出力ファイル名を指定してください.\n"); exit(-1); } // 迷路読込 readMaze(argv[1], &w, &h, maze); // maze[1][1] から maze[2*h-1][2*w-1] までのルートを探す x = 1; //座標の初期化 y = 1; while (x != 2 * w - 1 || y != 2 * h - 1){ if (maze[y][x + 1] == 0) { // 右にまだ行ってない? maze[y][x] = 1000; x = x + 1; } else if (maze[y + 1][x] == 0) { // 下にまだ行ってない? maze[y][x] = 1000; y = y + 1; } else if (maze[y][x - 1] == 0) { // 左にまだ行ってない? maze[y][x] = 1000; x = x - 1; } else if (maze[y - 1][x] == 0) { // 上にまだ行ってない? maze[y][x] = 1000; y = y - 1; } else if (maze[y][x + 1] == 1000) { // 行き止まりなので右に引き返す maze[y][x] = 1; x = x + 1; } else if (maze[y + 1][x] == 1000) { // 行き止まりなので下に引き返す maze[y][x] = 1; y = y + 1; } else if (maze[y][x - 1] == 1000) { // 行き止まりなので左に引き返す maze[y][x] = 1; x = x - 1; } else if (maze[y - 1][x] == 1000) { // 行き止まりなので上に引き返す maze[y][x] = 1; y = y - 1; } } maze[2 * h - 1][2 * w - 1] = 1000; // ゴール // 答えを濃い色に // 上記のプログラムはすでに答えを濃い色(1000)にしている // 迷路書出 writeMaze(argv[2], w, h, maze); return 0; }

  • メモリ2(ポインタ編)

    #include "stdafx.h" #include <ctype.h> #include <string.h> #include <stdlib.h> int check(int a[100], int n); typedef struct { char *number; char *class_type; char *name; char *subject; } my; int main(int argc, char* argv[]) { FILE *fp; int field = 0, line = 0; char buf[1000], *str; char bufG[1111]; int i, len; my *o; if((fp=fopen("test3.csv","r"))==NULL){ printf("ファイルが開けません"); } while(fgets(buf,1000,fp) !=NULL){ str=buf; len = strlen(buf); o = (my *) calloc(len + 1, sizeof(my *)); while(*str != '\0'){ if(*str != ','){ for(i = 0; *str != ',' && *str != '\0' ; i++){ if(*str == '\n'){ } else{ bufG[i] = *str; } str++; } bufG[i] = '\0'; switch(field){ case 0: o[line].number = bufG; break; case 1: o[line].class_type = bufG; break; case 2: o]line].name = bufG; break; case 3: o[line].subject = bufG; } field++; } else{ str++; } } line++; field = 0; } fclose(fp); return 0; } 固定なのがいけないといわれたのでこのように 変更しました。もちろん上手く動かないわけですが 原因を教えて下さい。 ちなみにエラーはo[0].numberが国語とかになってたり ちゃんとアクセスができません。

  • 関数化

    #include <ctype.h> #include <string.h> #include <stdlib.h> void swap(char p[], char q[]); char *get(char *str, char buf[], int line, int field); typedef struct { int number; char *class_type; char* name; char *subject; } my; my *data; int main(int argc, char* argv[]) { FILE *fp; int field = 0, line = 0; char buf[1000], *str; char *bufG; int line2 = 0; if((fp=fopen("test3.csv","r"))==NULL){ printf("ファイルが開けません"); } while(fgets(buf, 1000, fp) != NULL){ line2++; } fclose(fp); printf("%d\n", line2); if((fp=fopen("test3.csv","r"))==NULL){ printf("ファイルが開けません"); } data = (my *)malloc(sizeof(my) * line2); while(fgets(buf,1000,fp) != NULL){ str = buf; while(*str != '\0'){ bufG = get(str, buf, line, field); switch(field){ case 0: data[line].number = atoi(bufG); break; case 1: data[line].class_type = (char *)malloc(strlen(bufG) +1); strcpy(data[line].class_type, bufG); break; case 2: data[line].name = (char *)malloc(strlen(bufG) + 1); strcpy(data[line].name, bufG); break; case 3: data[line].subject =(char *)malloc(strlen(bufG) + 1); strcpy(data[line].subject, bufG); break; } str++; field++; } line++; field = 0; } fclose(fp);     for(int m = 1; m < line; m++){ printf("%d\n", data[m].number); printf("%s\n", data[m].class_type); printf("%s\n", data[m].name); printf("%s\n", data[m].subject);     } return 0; } char *get(char *str, char buf[], int line, int field) { char bufG[1111]; int i; for(i = 0; *str != ',' && *str != '\0' ; i++){ if(*str == '\n'){ bufG[i] = '\0'; } else{ bufG[i] = *str; } str++; } bufG[i] = '\0'; return bufG; } 前回の質問 http://okwave.jp/qa5094929.html で提示していただいたサンプルの関数化をはかりましたが うまくいきません。これを実行すると1しか表示されません。 原因はおそらくポインタだと思いますがどうすればいいのか わかりません。教えて下さい。bufを引数にする意味ないのでは という意見は今の所はとりあえずなしで fieldの値によってbufGが色々とってくる。 例えば1,A,山田,数学の場合 field = 0のときbufGは1 filed=1のときbufGはA field=2のときbufGは山田 filed=3のときbufGは数学という ような値が返ってくるようにしたいです。

専門家に質問してみよう