• 締切済み

文字列を比較

文字列を比較して 一つでも一致したらファイルに書き込まず抜ける 一つも一致しなかった場合一度書き込んで抜けるという操作を 下記のコードで実現したいんですけど、 "cPid[n] = cStoRegiAdd; for(j = 0;j < MAX;j++){ if(cPid[n] != cRegiTab[j]){ iflag = 1; } } if(iflag == 1){ fprintf(fh,"#define %s 0\n",cStoRegiAdd); }" の部分で何かおかしいとこはありますか?? もしあれば教えていただきたいんですけど?? #include<stdio.h> #include<string.h> #include<stdlib.h> #define MAX 1024 char *cRegiTab[MAX]; // 文字列登録表 int n = 0; int main() { rightsidehfunction(); leftsidehfunction(); } /* 左辺の値をとって.hファイルに書き込む関数 */ int leftsidehfunction() { FILE *ft; FILE *fh; char buf[MAX]; char buf1[MAX]; char *cPid[MAX]; char *cWorkRegiAdd; char *cStoRegiAdd; int istr = 0; int k; char *p; char *q; int s; int i; int j; int iflag = 0; ft = fopen("test.txt","r"); fh = fopen("test.h","a+"); if (fh == NULL || ft == NULL) { printf("ファイルを開けません。\n"); return 1; } /* ファイルを1行ずつ読み込む処理 */ while (fgets(buf, sizeof buf, ft) != NULL){ cWorkRegiAdd = strtok(buf, "="); for(k = 0;k < n;k++){ if(*cPid[k] != *cWorkRegiAdd)continue; if(strcmp(cPid[k],cWorkRegiAdd) == 0)break; } if(k < n) continue; cStoRegiAdd = malloc(strlen(cWorkRegiAdd) + 1); strcpy(cStoRegiAdd,cWorkRegiAdd); cPid[n] = cStoRegiAdd; for(j = 0;j < MAX;j++){ if(cPid[n] != cRegiTab[j]){ iflag = 1; } } if(iflag == 1){ fprintf(fh,"#define %s 0\n",cStoRegiAdd); } n++; } fclose(fh); fclose(ft); return 0; } /* 右辺の値をとって.hファイルに書き込む関数 */ int rightsidehfunction() { FILE *ft; // 入力ファイルポインタ FILE *fh; // 出力ファイルポインタ int c; //読み込み文字 char buf[MAX]; //バッファ領域 char buf1[MAX]; char cPid[MAX]; // 採取したPID char *cWorkRegiAdd; // 採取文字列作業域アドレス char *cStoRegiAdd; // 文字列格納域アドレス int iflag = 0; // 0/1; 右/左のクオート int ichs = 0; // chrの文字数 int istr = 0; // strの文字数 int k; // ntrの探索index int iOid; //OID char *p; ft = fopen("test.txt", "r"); fh = fopen("test.h", "w"); if (fh == NULL || ft == NULL) { printf("ファイルを開けません。\n"); return 1; } //ファイルを1文字ずつ読み込む while ((c = fgetc(ft)) != EOF) { switch (c) { case '"': iflag = 1 - iflag; /*右のクオート*/ if (iflag == 0) { cPid[ichs] = '\0'; cWorkRegiAdd = cPid; for(k = 0;k < istr;k++){ if(*cRegiTab[k] != *cWorkRegiAdd) continue; if(strcmp(cRegiTab[k],cWorkRegiAdd) == 0) break; } if(k == istr){ cStoRegiAdd = malloc(strlen(cWorkRegiAdd) + 1); strcpy(cStoRegiAdd,cWorkRegiAdd); cRegiTab[istr] = cStoRegiAdd; istr++; fprintf(fh, "#define %s 0\n", cStoRegiAdd); } ichs = 0; } break; case '\n': if (iflag == 1) { cPid[ichs] = '\0'; iflag = 0; } ichs = 0; break; default: if (iflag == 1) { cPid[ichs] = c; if (ichs < MAX - 1){ ichs++; } } break; } } /* ファイルの最後が改行じゃなかった場合 */ if (ichs>0) { cPid[ichs]='\0'; } fclose(ft); fclose(fh); return 0; }

みんなの回答

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.11

> もしMAXポイント数を超えた場合エラー これはトークンの総数がMAXを超えた場合、ということでいいですか? でしたら、cRegiTab[n]に登録する前にn < MAXでなければエラー、としてください。

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.10

んー…… ではまがりなりにもコードを書いた私からも#8と似たような事を言いましょうか。 とりあえず#7のコードを見れば、あなたのコードがカケラもないのはわかりますよね。 これは以前のQ/Aとか提示コードから期待される動作を推測したうえで完全に書き直しており、「設計からやり直したほうが早い」方のコードです。 まぁトークン切り出し部分が間違ってるかもしれませんが、そこは仕様を推測して書いてるため&切り出し部のコードは読み込んでないって事でご容赦を。 #トークンを配列のままリスト構造にしてないのはわざとです。念のため で、コードを書く際に気をつけることは…… ・手順を明確にし、切り分けられるところは切り分けて複数のことを同時にやろうとしない  たとえばリスト作成とファイル出力を#7では分けてます。この程度なら同時にやってしまってもさほど問題はないんですが、分けることにより出力ファイルの管理をここでやらなくてもよくなっています。  一箇所で管理するものはなるべく少なくすることで、見通しがよくデバッグのしやすいプログラムになります。 ・例示されたコードは少なくとも「なぜそうなるのか」が理解できるまで絶対に使わない  これは動作が理解できていないと「自分の環境への適応」や「不具合があったときの切り分け」ができないため。  #5のコードはトリッキーな部類なので今は見なかったことにしておいた方がいいかもしれません。 ・わかりやすい変数名・関数名を入れる。適度に何をしているかのコメントもつける  特に複数の英単語で構成されるような名前は全部小文字で区切りなしだと何書いてるのかわからなくなります。_で区切るか2単語目以降の頭文字を大文字にするとわかりやすくなります。  また「頭文字だけ取ってあわせた略称」はやめた方がいいです。一般的なものならともかく、そうでない場合変数名から意味を推察できなくなります。  コメントは将来の自分用と思って、少なくとも処理内容単位で何やってるかを書いておいた方がいいですね。 ・変数の役割、スコープ、入出力のタイミングを把握する  これは最初の「手順を明確に」にも通じるところですが、「(トークン数カウンタの)nをグローバル変数に」の理由が理解できていなかったようなので。 キツいことを言われてカチンとくるのはわからなくもないですが、私も概ね#8と同じ意見であると思ってもらっていいです。 ここでは仕事じゃないんで「その場で動けばとりあえずいいか」な回答もした上で、こういった原則を述べるようにはしてますが。 #なお今暇人してるのは別にサボってる訳じゃなくて入院中だからです。

lilhalileh
質問者

補足

ご返信ありがとうございます。いろいろと勉強になりました。 修行不足だったみたいですんでまたいちから出直してきます。 最後に一つだけ質問させてください。本当にこれが最後ですので☆ 聞きながらも結構苦労してコードを完成させたので.... 最初のコードで#define MAX 1024と定義しているのですが。。。。 もしMAXポイント数を超えた場合エラーという出力をさせる場合 どういう感じにしたらいいでしょうか?? どこでifを使ってエラーを出力させるかがいまいちわかりません。 最初に自分が書いたコードでいいのでよろしくお願いできますでしょうか?? とりあえずこれが最期なので一生のおねがいということで☆

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.9

ご自分の頭をフル回転させて、ウンウンうなりながら 作ったプログラムが動いたときの気持ちよさを味わえるようになってください。 人からもらったプログラムをただ動かすだけでは、プログラミングという 知的作業の醍醐味を感じることができません。

  • arain
  • ベストアンサー率27% (292/1049)
回答No.8

No.2です。 改めて書きましょう。 >結論から言うと、設計からやり直した方が早いです。 >今まで質問した問題箇所「だけ」の回答をツギハギしているので、 >かえってややこしくて、わかりにくく、追加変更が困難なものができています。 さらに追加された理由。 No.4より >なのでこの5つがグローバル変数(cRegiTab[n])で宣言している配列に入りますよね?? >今は試験的に行っているので実際は何行あるか分からないので10行かもしれないし....100行という可能性もある。 可変であれば、動的にメモリ確保し制御できるように「リスト構造」を使用する形で再設計してからプログラムを組むことを考えてください。 今の状態では当然ながらMAX間までしか処理できません。 机上で設計もせずに「頭の中だけで」(言いかえれば「行き当たりばったりでいきなりソースを組む」)ことを行っていませんか? 自分で提示したソースの ・どこで何を行っているか ・それぞれの変数にどのようなタイミングでどんな値が入っているか ご自分で理解できていますか? 少なくとも、 ・わかりやすい変数名を使用する ・処理にコメントを記載していく 等を行えば、プログラムの問題点も把握しやすい見通しの良いソースになりますよ。 回答者がどれだけ短い処理で同じことを行っているかを考えれば理解できるでしょう。 No.5より >セミコロンだけの行があるんですけど、あれはどういう意味でしょうか?? 空行。No.5の場合ならforループだけを実行させるために使用されている。 >それと自分が作ったやつにあなたの作成したコードを組み込めば動く!?ということでしょうか?? ソースの内容を理解せずに組み込んだら、「また」今までと同じことを繰り返すことになりますよ。

lilhalileh
質問者

補足

そんなに簡単におっしゃるならコードを 提示していただけませんか?? 口だけで技術が伴っていない人のアドバイスを 聞いてもこちらはなんの意味もないですし。。 それだけ自身がおありならできますよね??

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.7

む、テキストファイルとか添付できないのか…… 仕方ないのでここに直接出しておきます。 可読性のためインデントに全角スペースを使ってます。 #include <stdio.h> #include <stdlib.h> #include <string.h> /* 一行の最大長 */ #define LINE_LEN 256 /* トークンの最大長 */ #define TOKEN_LEN 32 /* トークンの最大数 */ #define TOKEN_MAX 256 int get_token_list(FILE *infile, char token_list[TOKEN_MAX][TOKEN_LEN]); void write_header(FILE *outfile, char token_list[TOKEN_MAX][TOKEN_LEN], int token_num); int main() {  FILE *fp;  char token_list[TOKEN_MAX][TOKEN_LEN];  int token_num;  fp = fopen("test.txt","r");  if(!fp) return -1;  token_num = get_token_list(fp, token_list);  fclose(fp);    fp = fopen("test.h", "w");  if(!fp) return -1;  write_header(fp, token_list, token_num);  fclose(fp);  return 0; } /* 入力ファイルからトークンのリストを作成(戻り値:トークンリストのエントリー数) */ int get_token_list(FILE *infile, char token_list[TOKEN_MAX][TOKEN_LEN]) {  char line[LINE_LEN];  char token[TOKEN_LEN];  int token_num = 0;  int i;  char *ptr;  int len;  while(fgets(line, LINE_LEN, infile))  {   ptr = strchr(line, '=');   while(ptr != NULL)   {    /* 右辺の処理 */    if(ptr != NULL)    {     /* ダブルクォート(開き)を検索 */     ptr = strchr(ptr, '\"');     if(ptr != NULL)     {      /* ダブルクォートの隣にポインタを移動 */      ptr ++;      /* ダブルクォート(閉じ)までの長さを取得 */      len = strcspn(ptr, "\"");            strncpy(token, ptr, len);      token[len] = '\0';            /* ダブルクォート(閉じ)の後ろまでずらす */      ptr += len + 2;     }    }        /* 左辺の処理(右辺に処理する相手がいなくなった時点でptr==NULLになり動作する) */    /* strtok()でlineを破壊するので右辺のあとでの実行 */    if(ptr == NULL)    {     /* 左辺の場合 */     ptr = strtok(line, "=");     strcpy(token, ptr);          /* この処理が終わったらループアウトするので条件を設定しておく */     ptr = NULL;    }    /* 重複チェック */    for(i = 0; i < token_num; i ++){     /* 重複トークンがあったらとめる */     if(strcmp(token, token_list[i]) == 0){      break;     }    }    /* i == token_numなら重複がなかったことになるので新要素として追加 */    if(i == token_num){     strcpy(token_list[token_num], token);     token_num ++;    }   }  }  return token_num; } /* トークンリストをヘッダファイルに書き出し */ void write_header(FILE *outfile, char token_list[TOKEN_MAX][TOKEN_LEN], int token_num) {  int i;  for(i = 0; i < token_num; i ++)  {   fprintf(outfile, "#define %s 0\n", token_list[i]);  } }

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.6

つまり「右辺処理後のトークン総数が処理前にわからない」ということですか。それならわからなくても問題ありません。 そこを簡単に左辺処理へ引き継ぐために前回のQ/Aで「nをグローバル変数にする」と言ったのですから。 nは右辺処理中にトークンが追加されるたびに加算される、つまり右辺処理終了後には「右辺の重複しないトークン総数」が入っています。 nはグローバル変数なのでどの関数でも読み書きできますから、何も考えずにそのままnを使えばいいわけです。 あと暇に飽かせてコードを書いてみました。 POINT_A="POINT_B"+"POINT_C" POINT_B="POINT_C"*"POINT_A" KEN=("MMK2","MSX") KOL="HIMWARI"+1000000"OKL" から #define POINT_B 0 #define POINT_C 0 #define POINT_A 0 #define MMK2 0 #define MSX 0 #define KEN 0 #define HIMWARI 0 #define OKL 0 #define KOL 0 が生成されます。 若干トリッキーなことをしていたり異常構文(ダブルクォートの対応がとれてないとか""(空トークン)の処理とか)の対応はしてませんが、まぁ参考までに。

lilhalileh
質問者

補足

ありがとうございます。 え......と。 コードはいずこに(笑) 参考にさせていただこうと思ったんですけど.... ファイルの中身と結果はあるんですけど。。。。。。

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

わざわざ fputc を使うから面倒なのであって, 諦めて fprintf を使えば簡単なのでは? void printSymbols(char *buf, FILE *fout) { char *p = buf; char *q; /* Left hand side mode */ for (q = p; *q != '\0' && *q != '='; ++q) { ; } fprintf(fout, "#define %.*s 0\n", (int)(q-p), p); /* Right hand side mode */ while (*q != '\0') { for (p = q+1; *p != '\0' && *p != '"'; ++p) { ; } if (*p == '\0') { return; } for (q = ++p; *q != '\0' && *q != '"'; ++q) { ; } fprintf(fout, "#define %.*s 0\n", (int)(q-p), p); } でそれなりな動作になるかな?

lilhalileh
質問者

補足

ありがとうございます。 セミコロンだけの行があるんですけど、あれはどういう意味でしょうか?? それと自分が作ったやつにあなたの作成したコードを組み込めば動く!?ということでしょうか??

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.4

> ファイルの読み込み数によって違う 「ファイルの読み込み数によって違う」という言葉の意味がよくわからないのですが…… 複数ファイルがターゲットで、ファイルごとにnの値が変わるという意味でしょうか。 もうちょっと具体的にお願いします。 で、#2の補足に書いてあるコードですけど、これだと書式出力だけでなく重複チェックもできませんね。 一文字ずつ書くのではなく、いったん文字列に移し変えるようにしましょう。 あと、文字列関数にはこの手の処理に使える便利な関数がいくつか存在しますので、それを使って処理を書き換えてしまいましょう。 フラグやらループやらいろいろと消えて見通しがよくなります。 以下は「文字列bufの=より右にある""で囲まれた最初のトークンを切り出す」処理のサンプルです。 不明な関数はヘルプで調べてください。あとエラーチェックは端折ってます。 #define TOKEN_LEN 32 char token[TOKEN_LEN]; char *ptr; int token_len; /* =までポインタを移動 */ ptr = strchr(buf, '='); /* =より後の最初のダブルクォート(開き)を検索 */ ptr = strchr(ptr, '\"'); /* ダブルクォートはコピー対象に含まないので一つ隣に移動 */ ptr ++; /* ダブルクォート(閉じ)までの長さを取得 */ token_len = strcspn(ptr, "\""); /* tokenにptrからtoken_lenだけコピー */ strncpy(token, ptr, token_len); token[token_len] = '\0';

lilhalileh
質問者

補足

前に説明したんですけどファイルを読んで、.hファイルに書きこむん ですけどファイルの中身が AE="AO"+"AC" AE="AC"+"AE" AW="AD"*"AG" だとします。 今の僕が作ったやつでいくとまず右辺の値をとって 次に左辺の値をとります。このままファイルを読み込んで.hファイルに出力させると AO AC AE AD AG AE AW ですよね。 書き込むファイルの内容は重複しちゃいけないんで AO AC AE AD AG AW としたいわけですよ。 ここまではいいですよね?? 右辺と左辺を分けてるからまず右辺のクオート括りの文字を抽出。 その場合ファイルに書き込まれている文字は AO AC AE AD AG なのでこの5つがグローバル変数(cRegiTab[n])で宣言している配列に入りますよね??今は試験的に行っているので実際は何行あるか分からないので10行かもしれないし....100行という可能性もある。 それで右辺の切り取った文字の配列に入っている個数を 正確に調べるにはどうしたらいいかという質問です。

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.3

とりあえず#1ですが、それ以外にも。 > cPid[n] = cStoRegiAdd; > for(j = 0;j < MAX;j++){ > if(cPid[n] != cRegiTab[j]){ > iflag = 1; > } > } forループ脱出条件はj < n(cRegiTabへの登録数まで)にしましょう。でないと文字列の入っていない要素まで到達した瞬間にコケます。 あと、これではループのどこかで一回一致しなかったらその時点でiflagが立ったままになります(あとで一致しても一致したとみなされない)。 ループの外で1にセットしておき、同値が出たら0にセットしてbreakしましょう。 てなわけで、変更するならこんな感じになりますか。 iflag = 1; for(j = 0;j < n;j++){ if(strcmp(cPid[n],cRegiTab[j]) == 0){ iflag = 0; break; } }

lilhalileh
質問者

補足

ご返信どうもありがとうございます。 j < n(cRegiTabへの登録数)ですが ファイルの読み込み数によって違うんですけど どういう風に指定したらいいでしょうか??

  • arain
  • ベストアンサー率27% (292/1049)
回答No.2

前回の質問 http://okwave.jp/qa4506588.html の指摘箇所があまり反映されていないのは「ここでは」置いておくとして >下記のコードで実現したいんですけど、 下記のコードでは実現できません。 >の部分で何かおかしいとこはありますか?? あります。 で「(上記で)置いておいた」ことを蒸し返します。 結論から言うと、設計からやり直した方が早いです。 今まで質問した問題箇所「だけ」の回答をツギハギしているので、 かえってややこしくて、わかりにくく、追加変更が困難なものができています。 一応今回の問題箇所だけは指摘しときますが >if(cPid[n] != cRegiTab[j]){ 「文字列」はif文の比較演算子での比較はできません。

lilhalileh
質問者

補足

ご返信どうもです。 別のパターンは作っています。 ただ一つ書式付で出力できないんですよ。。。。。 そこを教えていただきたく思います。下にソースを載せます。 fputcの部分をどうすればいいでしょうか?? よろしくお願いします。 #include <stdio.h> #define MAX 256 int main() { FILE *in, *out; char *p, buf[MAX]; int lhs, in_quote; in = fopen("sample.txt", "r"); if (in == NULL) { printf("Cannot open sample.txt\n"); return 1; } out = fopen("sample.h", "w"); if (out == NULL) { printf("Cannot open sample.h\n"); return 1; } while (fgets(buf, MAX, in) != NULL) { lhs = 1; in_quote = 0; for (p = buf; *p != '\0'; p++) if (*p == '=') { lhs = 0; fputc('\n', out); } else if (*p == '"') if (in_quote) { in_quote = 0; fputc('\n', out); } else in_quote = 1; else if (lhs || in_quote) fputc(*p, out); } fclose(out); fclose(in); }

関連するQ&A

  • whileは2度呼べる!?

    質問させていただきます。。 何度か似たような質問をさせて頂いていますが、 今回もちょっと掘り下げた質問になっていますので。。。。 ファイルの内容を読み取って.hファイルに書き込むのですが。 ファイルの中身が POINT_A="POINT_B"+"POINT_C" POINT_B="POINT_C"*"POINT_A"   だとします。 狙いとしては POINT_A POINT_B POINT_C です。下記のソースでは右辺と左辺を分けているのですが.... 重複した場合.hファイルに書き込まないようにしています。 問題の場所は/* 右辺の値をとって.hファイルに書き込む関数 */の部分で2回while を使って読み込みをしているのですが何かおかしいとこは ありますでしょうか?? #include<stdio.h> #include<string.h> #include<stdlib.h> #define MAX 10000 int leftsidehfunction(); int rightsidehfunction(); int main(int argc ,char **argv) { if(argc != 2 ){ printf("引数の数があっていません。\n"); } rightsidehfunction(argv[1]); } /* 右辺の値をとって.hファイルに書き込む関数 */ int rightsidehfunction(char cfilename[MAX]) { FILE *ft; // 入力ファイルポインタ FILE *fh; // 出力ファイルポインタ int c; //読み込み文字 char buf[MAX]; //バッファ領域 char buf1[MAX]; char cPid[MAX]; // 採取したPID char *cWorkRegiAdd; // 採取文字列作業域アドレス char *cStoRegiAdd; // 文字列格納域アドレス char *cRegiTab[MAX]; // 文字列登録表 int iflag = 0; // 0/1; 右/左のクオート int ichs = 0; // chrの文字数 int istr = 0; // strの文字数 int k; // ntrの探索index int iOid; //OID char cgetfilename[MAX]; char *p; strcpy(cgetfilename,cfilename); ft = fopen(cgetfilename, "r"); strtok(cgetfilename,"."); strcat(cgetfilename,".h"); fh = fopen(cgetfilename, "a+"); if (ft == NULL || fh == NULL) { printf("%s ファイルを開けません。\n",cgetfilename); } while ((c = fgetc(ft)) != EOF) { switch (c) { case '"': iflag = 1 - iflag; /*右のクオート*/ while(fgets(buf1,sizeof buf1,fh) != NULL){ strtok(buf1," "); p = strtok(NULL," "); if (iflag == 0) { cPid[ichs] = '\0'; cWorkRegiAdd = cPid; for(k = 0;k < istr;k++){ if(*cRegiTab[k] != *cWorkRegiAdd) continue; if(strcmp(cRegiTab[k],cWorkRegiAdd) == 0) break; } if(k == istr){ //no hit in str[] cStoRegiAdd = malloc(strlen(cWorkRegiAdd) + 1); strcpy(cStoRegiAdd,cWorkRegiAdd); cRegiTab[istr] = cStoRegiAdd; istr++; db_obj_find_pid(cStoRegiAdd, &iOid); if(iOid <= 0 ){ if(p != cStoRegiAdd){ fprintf(fh, "#define %s 0\n", cStoRegiAdd); }else if(p == cStoRegiAdd){ break; } }else{ if(p != cStoRegiAdd){ fprintf(fh, "#define %s output[obj[%d].outputs + 2].Analog\n",cStoRegiAdd, iOid); }else if(p == cStoRegiAdd){ break; } } } ichs = 0; } iOid = 0; } break; case '\n': if (iflag == 1) { cPid[ichs] = '\0'; iflag = 0; } ichs = 0; break; default: if (iflag == 1) { cPid[ichs] = c; if (ichs < MAX - 1) { ichs++; } } break; } } if (ichs>0) { cPid[ichs]='\0'; } fclose(ft); fclose(fh); return 0; }

  • 重複文字を出力させない!!

    こんにちは!! ご質問させてください。 右辺値のダブルクオートくくりの 文字列をテキストから読み込みファイルに書き込む処理ですが..... うまく取れません。下記にソースコードを提示しましたので 一読の上アドバイスいただけたらと思います。 テキストファイルのないようは k="seikyo"-"himawari" k="north"+"seikyo" これを読み込んだ場合.tファイルに書き込む内容は seikyo himawari north seikyo ですが重複した場合は書き込まないようにプログラムしたつもりです。 seikyo himawari north としたいと思っています。 希望通りの形にならないので皆様どうか お力をお貸しください。よろしくお願いします。 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<syslog.h> #define MAX_REC_A 256 #define MAXFIELD 128 #define BUFFLEN 256 #define MAX 10000 #define MBF 1024 int makemoutputhrightside(); int main(int argc ,char **argv) { makemoutputhrightside(argv[1]); } /* 右辺の値をとって.tファイルに書き込む関数 */ int makemoutputhrightside(char sum[BUFFLEN]) { FILE *ft; FILE *fh; int c; char cPid[BUFFLEN]; char *p; char *q; char *str[BUFFLEN]; int flag = 0; int i = 0; int n = 0; int k; char filename[64]; char cdmy[MAX]; strcpy(filename,sum); strcat(filename,".txt"); ft = fopen(filename, "r"); fh = fopen("moutput.t", "a"); if (ft == NULL || fh == NULL) { syslog(LOG_ERR,"開けないファイルがあります。\n"); return 1; } //ファイルを1文字ずつ読み込む while ((c = fgetc(ft)) != EOF) { switch (c) { case '"': flag = 1 - flag; /*右のクオート*/ if (flag == 0) { cPid[i] = '\0'; p = strcpy(cdmy,cPid); for(k = 0;k < n;k++){ if(*str[k] != *p) continue; if(strcmp(str[k],p) == 0) break; } if(k < n) continue; q = malloc(strlen(p) + 1); strcpy(q,p); str[n] = q; fprintf(fh, "%s ",q); i = 0; } n++; break; case '\n': if (flag == 1) { cPid[i] = '\0'; fprintf(fh, "%s \n", cPid); } flag = 0; } i = 0; break; default: if (flag == 1) { cPid[i] = c; if (i < BUFFLEN - 1) { i++; } } break; } } /* ファイルの最後が改行じゃなかった場合 */ if (i>0) { cPid[i]='\0'; fprintf(fh,"%s\n",cPid); } fclose(ft); fclose(fh); return 0; }

  • ファイルを読み込んだ時に同じ文字が重複した場合.kファイルに書き込まない

    こんにちは。 テキストファイルの内容が KENIA=ナイル川 NORTH=小さな旅人 KENIA=せせらぎ 上記のファイルを読み込んだ際に下記のコードで実行すると .hファイルに書き込まれる内容は..... KENIA NORTH KENIA ですが同じ言葉が出現した場合(重複した場合)ファイルに書きまないようにしたいと思っています。すなわち KENIA NORTH   としたいと思っています。 この場合どうしたらいいでしょうか?? テキストファイルは例であり内容は不規則ですので。。。。 力をお貸しください。よろしくお願いします。 #include<stdio.h> int makemoutputhleftside(); int main(int argc,char **argv){ makemoutputhleftside(argv[1]); } int makemoutputhleftside(char sum[64]) { char buf[1024]; char cPid[256]; int iOid; FILE *ft; FILE *fh; char filename[64]; int i; strcpy(filename,sum); strcat(filename,".txt"); ft = fopen(filename,"r"); fh = fopen("moutput.h","w"); if (ft == NULL || fh == NULL) { printf("開けないファイルがあります。\n"); return 1; } /* ファイルを1行ずつ読み込む処理 */ while (fgets(buf, sizeof buf, ft) != NULL) { strcpy(cPid, strtok(buf, "=")); fprintf(fh, "#define %s \n", cPid); fclose(fh); fclose(ft); return 0; }

  • fgets関数を使用したときの文字あふれについて

    fgets関数を用いて文字列を入力し、その長さを測るプログラムを作っています。 #include <stdio.h> #include <string.h> #define MAX 256 int main ( int, char *[] ); int main ( argc, argv ) int argc; char *argv[]; { char buf[( MAX )]; while ( 1 ){ memset ( buf, 0, sizeof( buf )); fgets ( buf, MAX, stdin ); if( fgets == NULL ){ break; } printf("入力した文字列の長さは%dです\n" ,strlen( buf )); } return 0; } このプログラムでは、256までしか文字列の長さを測ることができません。 もしこのプログラムで256を超える文字列を入力してしまうと、文字のあふれが発生し、 「入力した文字列の長さは256です」 「入力した文字列の長さは(あふれた文字列の長さ)です」 とこのようになってしまいます。 このプログラムで256以上の文字を読み捨てて、 「入力した文字列の長さは(あふれた文字列の長さ)です」 を表示しないようにできるのでしょうか? また読み捨てた文字列の長さを知ることはできるのでしょうか? もしかしたらfgets関数を使用すると不可能なのではないか?と思っています。 分かる方が居ましたらどうか教えて下さい。 よろしくお願いします。

  • 文字列比較

    最長10文字の文字列を2件入力し、char型の配列にそれぞれ格納する。2つの文字列を比較し、文字列が同じだったら「equal」を表示し異なっていたら「Not equal」を表示するプログラムを作成せよという課題が出ました。 条件として、11文字以上の文字が入力されたら、先頭から10文字までを有効とし、11文字目以降を無視する。下記のプログラムで文字列1に11文字以上入力すると、うまく動きません。なぜ、うまくいかないかと、どうなおしたらよいかを教えてください。 #include<stdio.h> #include<string.h> #define max_length 10 void get_string (char *p_str, int size); int main() { char string1[max_length+2]; char string2[max_length+2]; printf("文字列1:"); get_string(string1,max_length+2); printf("文字列2:"); get_string(string2,max_length+2); if(!strncmp(string1,string2,max_length)) puts("equal"); else puts("Not equal"); } void get_string (char *p_str, int size) { fgets(p_str,size,stdin); }

  • 指定した文字列を探して・・・

        第1引数の文字列中に第2引数で指定した文字がある場合に、その     文字のあるアドレス(ポインタ)を返す関数doko()作成し、     プログラムを完成させよ。     指定した文字がない場合はNULL(ヌルポインタ)を返すものとする。     配列の[](カギカッコ)を利用しないで作る事     main内は変えないこと いろいろと模索したのですが、strcpyなどは使うのでしょうか? 参考サイトを見たりしたり、ほかの質問などを見たのですが なかなか理解できずに現在にいたってます 以下のコードのdokoは沢山やりすぎたので一番シンプルな間違い方をしています 何かご指摘あればお願いします #include <stdio.h> #define MAX 128 char* doko(char *,char); int main() { char buf[MAX]; char *p = "abcdef12345"; char *r; r = doko(p, 'f'); if (r == NULL) { printf("mojiretsu ni f toiu moji ha arimasen\n"); return 0; } printf("%s (= f12345)\n", r); scanf("%s", buf); r = doko(buf, 'x'); if (r == NULL) { printf("mojiretsu ni x toiu moji ha arimasen\n"); return 0; } printf("%s\n", r); return 0; } char* doko(char *p,char a) { while(*p){ if(*p == a){ return p; } if(*p != a){ return NULL; } ++p; } }

  • switch文で文字を比較することは出来ませんか?

    switch文で文字を比較することは出来ませんか? 例えば… int main(void){ char buf[5]; buf = 'b'; switch(buf){ case 'a': ・  ・  ・  break; case 'b': ・  ・  ・  break; }

  • 文字列の比較

    文字列の比較の仕方がよくわかりません。strcmpコマンドを使わずにできるだけ簡単にかく方法を教えてください。途中までは書きます。for分とかを使うんでしょうか? #include <stdio.h> int main(void) { char SpelA[] = "dog"; char SpelB[] = "dogfood" ; int long ; long = 1 ; if (long == 1) { printf("Good!\n") ; } ; return 0 ; } ;

  • プログラミング ポインタを使った文字列比較

    プログラミング ポインタを使った文字列比較 2つの文字列str1, str2を入力し,それらが等しければ0,等しくなければ1を返す関数str_compareを作り、返り値によって以下のように表示するプログラムを作れ。ただし,関数strcmpを使ってはならない。 文字列の入出力はmain関数で行い,関数str_compareの仮引数にはポインタ変数を宣言し,ポインタと間接演算子*を用いた処理を行うこと。 % ./a.out input str1 = Worldcup input str2 = Worldcup same strings % ./a.out input str1 = World input str2 = cup different strings この問題に私は次のようにプログラミングしました。 #include <stdio.h> #define MAX 100 int str_compare(char *, char *); main() { char str1[MAX], str2[MAX]; printf("input str1 = %s", str1); scanf("%s", str1); printf("input str2 = %s", str2); scanf("%s", str2); str_compare(str1, str2); if (str_compare(str1, str2) == 0) printf("same strings\n"); else if (str_compare(str1, str2) == 1) printf("different strings\n"); } int str_compare(char *s1, char *s2) { int i; for (i = 0; s1[i] != '\0'; i++) { if (s1[i] != s2[i]) { break; } } if (s1[i] == s2[i]) { return 0; } else { return 1; } } これで実行したところ、「input str1 =」の右のスペースが文字化け?してしまいます。(半角カタカナや記号が出る)ただ、その後に文字列を入力すると、正しく機能します。 これは何が悪いなのでしょうか、どなたか教えてください。

  • 文字列の比較

    このプログラムに問題はあるでしょうか? 2つの文字列に対して,同じ位置にある文字が一致する箇所をカウントするプログラムです. やはりwhile分の||を&&にしなければならないのでしょうか? #include <stdio.h> int main(void) { char mojiA[] = "Please Help Me!" ; char mojiC[] = "eeeeeeeeeeeeeeeee"; char mojiB[] = "Please give me some money" ; int count ; /* 一致した文字数 */ int i ; count = 0 ; i=0; do{ if (mojiA[i] == mojiB[i]) {          count++ ;        } i++; } while(mojiA[i]!=0 || mojiB[i]!=0); printf("%d\n", count) ; return 0 ; } ;

専門家に質問してみよう