• 締切済み

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

こんにちは!! ご質問させてください。 右辺値のダブルクオートくくりの 文字列をテキストから読み込みファイルに書き込む処理ですが..... うまく取れません。下記にソースコードを提示しましたので 一読の上アドバイスいただけたらと思います。 テキストファイルのないようは 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; }

みんなの回答

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

ぱっと見た感じ, n をインクリメントするタイミングが間違ってるような気がする. あと, 「ファイルの最後が開業じゃなかった場合」も微妙におかしい. それにしても, 「意味のわかる変数を使おう」という気にはならないものなんだろうか....

lilhalileh
質問者

補足

ご返信ありがとうございます。 具体的にどうしたらいいでしょうか?? 詳しく教えていただけないでしょうか?? かなり困っていまして(・ ・")。。。。。 どうぞよろしくお願いします。

関連するQ&A

  • 文字列を比較

    文字列を比較して 一つでも一致したらファイルに書き込まず抜ける 一つも一致しなかった場合一度書き込んで抜けるという操作を 下記のコードで実現したいんですけど、 "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; }

  • ファイルを読み込んだ時に同じ文字が重複した場合.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; }

  • 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; }

  • 大文字を小文字に、小文字を大文字にするプログラム

    問題は、 ファイルにあるアルファベットの大文字を小文字に変換し、小文字は大文字に変換して、ファイルに保存するプログラムを作りなさい というものです。 色々考えて、 #include <stdio.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> #include <unistd.h> #include <ctype.h> int main(int argc,char **argv){ int fd,flag1,flag2; int i,n; char buffer[512],x; fd = open(argv[1],O_RDWR); if(fd == -1) perror("open"); while((n = read(fd,buffer,sizeof(buffer)))>0){ x = buffer[i]; flag1 = islower(x); flag2 = isupper(x); for(i=0;i<n;++i) if(flag1 == 1){ buffer[i] = toupper(buffer[i]); }else if(flag2 == 1){ buffer[i] = tolower(buffer[i]); } write(fd,buffer,n); } close(fd); exit(0); } のようなプログラムを考えましたが、うまくいきません。 toupperのような関数を使ったのは初めてなのでよく使い方が分からずこのようなプログラムになってしまいました。 どうか正しく動くようなプログラムを教えてください。お願いします。

  • ファイルを読み込みテキストファイルに分割後特定の文字を抽出

    sample1.txtというファイルがあり中身が "JAPAN" = "USA" + "BOLD" "CHINA" = "UAE" * "KENIA" - "KOREA" というファイルが存在した場合なのですが..... これを読み込んでかつ.hファイルに書き込むのですが.. 左辺とダブルクオートくくりの文字を抽出するんですけど とりあえずはいくつか案を考えまして #include <stdio.h> int main(int argc, char **argv) { FILE *fp; FILE *ft int c, flag=0; fp=fopen("sample1.txt","r"); ft =fopen("sample1.h","w"); while ((c=fgetc(fp))!=EOF) { switch (c) { case '"': flag=1-flag; if (flag==0) putchar('\n'); break; case '\n': flag=0; default: if (flag) putchar(c); break; } } fclose(fp); fclose(ft); return 0; } これが第一の案なんですけど標準出力は出来ましたが ダブルクオートくくりの文字しか取れてないんですよ。 .hファイルに書き込むために文字列に入れてから fprintfを使って出力する方法と左辺の値も一緒にとる方法 どなたかわかりますでしょうか??困っておりまして ご教授お願いします。

  • ソート

    読み込むファイル(sample.txt)は、 2,jirou 5,gorou 4,shirou 1,tarou 6,mutsuo 3,saburou 下記の処理をします。 #include<stdio.h> #include<string.h> #define N 6 int sort1[N]; char sort2[N][30]; int BubbleSort(int data[N]) { int i,j,flag; do{ flag=0; for(i=0;i<N-1;i++) { if(data[i]>data[i+1]) { flag=1; j=data[i]; data[i]=data[i+1]; data[i+1]=j; } } } while(flag==1); return 0; } int main(void) { FILE *fpin; int id,h,k; printf("\n"); fpin=fopen("sample.txt","r"); if(fpin==NULL){ printf("ファイルをオープンできず!\n"); return 1; } for(k=0;k<N;k++) { h=fscanf(fpin,"%d,%s",&sort1[k],sort2[k]); if(h==EOF) break; printf("%d %s\n",sort1[k],sort2[k]); } printf("\n"); BubbleSort(sort1); for(k=0;k<N;k++) printf("%d %s\n",sort1[k],sort2[k]); return 0; } 実行結果は、 2 jirou 5 gorou 4 shirou 1 tarou 6 mutsuo 3 saburou 1 jirou 2 gorou 3 shirou 4 tarou 5 mutsuo 6 saburou 名前(sort2)もソートさせるには、どうすればいいか手ほどきをお願いします…

  • 一部コマンドでエラー

    以下のプログラムにパス検索機能を追加しろ。 /bin/lsと入力していたものを、lsだけで実行できるようにする。 そのほかにもdata -Iやgcc -o test test.c、./testを実行可能にする。 と言う課題で、 if(execv(argv[0],argv[])==(-1)){をif(execvp(argv[0],argv)==(-1)){とする方法を聞いたのですが、 gcc -o test test.cを入力すると長文のエラーが出力されます。 どうしたら良いでしょうか? #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> main(int argc, char *argv[]){ int len, pid, st; char *p; int i, sp_flag; static char prompt[64]="> "; char command[256]; printf("%s",prompt); while (fgets(command, 256, stdin) != NULL){ if((len = strlen(command)) == 1)break; command[len-1] = '\0'; p=(char *)&command; sp_flag=0; for(i=0; *p!='\0';p++){ if(sp_flag == 0 && *p!=' '){ argv[i]=p; sp_flag=1; i++; }else if(*p==' '){ *p='\0'; sp_flag=0; } } argv[i]=(char *)0; for(i=0; argv[i]!=(char *)0; i++){ printf("%s\n",argv[i]); } if((pid = fork()) == 0){ if(execv(argv[0],argv)==(-1)){ printf("%s", "exec error.\n"); exit(1);} } else if(pid >= 1){ wait(&st); printf("%s", prompt); } else { perror("fork"); exit(1); } } exit(0); }

  • ファイルの出力

    コマンドラインで指定したファイルの内容を一行ずつ表示するプログラムです。一行表示するごとに次の行も表示するか尋ねます。 #include<stdio.h> #include<stdlib.h> #include<ctype.h> int main(int argc, char *argv[]) {  FILE *fp;  char str[80];  char ch;  if (argc != 2){   printf("コマンドライン引数が違います\n");   exit(1);  }  if ((fp = fopen(argv[1],"r")) == NULL){   printf("ファイルが開けません");   exit(1);  }  while(!feof(fp)){   fgets(str, 79, fp);   if (!feof(fp)) printf("%s",str);   printf("追加しますか?(y/n)");   gets(str);   if ( toupper(*str) == 'N') break;   printf("\n");  }     if (fclose(fp) == EOF){   printf("ファイルを閉じれません\n");   exit(1);  }  return 0; } while文の   gets(str);  if ( toupper(*str) == 'N') break; この部分を  ch = getchar();  if ( toupper(ch) == 'N') break; でやると上手く実行できないのですが、なぜでずか?

  • 0と1のファイルへの書き込み、出力

    c言語で0と1の乱数を生成し、ファイルに出力したいのですが、出力がおかしくなってしまいます。 正しく0と1をファイルに書き込み、出力するにはどうしたらいいでしょうか。 わかる方いらっしゃいましたら教えてください。 お願い致します。 #include<stdio.h> #include <stdlib.h> #include <time.h> #define max 3000000 #define nrand(n) (int)((double)n*rand()/RAND_MAX) /* 0以上n未満の整数を返す */ int main() {   FILE *Wf;   char W_filename[20];   int *W=(int *)malloc(sizeof(int) * max);   printf("入力ファイル名 : "); scanf("%s",W_filename);   if( ( Wf=fopen(W_filename,"w") ) == NULL ) printf("ファイルを開けません\n");   else   {     for(i=0;i<max;i++)     {     W[i]=nrand(2);     fprintf(Wf,"%d ",W[i]);    }   }   fclose(Wf);   free(W); } 出力が ‰‱‱‰‱‱‰‱‱‰‰‰‰‱‰‱‰‱‰‰ のようになってしまいます。 Wにはちゃんと0か1が入っているみたいなのですが・・・

  • cygwinを使ってcsvファイルを読み込み、出力させようとしています

    cygwinを使ってcsvファイルを読み込み、出力させようとしています。 とりあえず、読み込みのみのプログラムを作成し、 実行させてみたのですが(run ファイル名.csv と入力) 「Error: could not start C:\cygwin\home\ユーザー名ファイル名.csv」 と出力され、読み込みができず、困っています。 プログラム初心者です。 恐縮ですがご回答よろしくお願いします。 以下に、読み込みプログラムとcsvファイルを記載します。 (プログラムは拾い物です。) <プログラム> #include <stdio.h> #define MAX_ITEM_SIZE 100 #define MAX_LINE_SIZE 1024 char *GetCSVItem(char *wp, char *buff, int size); void main(int argc, char *argv[]) { FILE *fp; char buff[MAX_LINE_SIZE], *wp, item[3][MAX_ITEM_SIZE]; int i1, len; if(argc != 2){ printf("comand error nyuuryoku keishiki\n"); return; } fp = fopen(argv[1], "r"); if(fp == NULL){ printf("can not open file[%s].\n", argv[1]); return; } for(;;){ if(fgets(buff, MAX_LINE_SIZE, fp) == NULL) break; len = strlen(buff); if(len == 0 || buff[len-1] != '\n'){ if(feof(fp) == 0){ printf("data error[%s].\n", buff); return; } } buff[len-1] = '\0'; wp = buff; if((wp = GetCSVItem(wp, item[0], MAX_ITEM_SIZE)) == NULL){ printf("error(1)\n"); break; } if((wp = GetCSVItem(wp, item[1], MAX_ITEM_SIZE)) == NULL){ printf("error(2)\n"); break; } if((wp = GetCSVItem(wp, item[2], MAX_ITEM_SIZE)) == NULL){ printf("error(3)\n"); break; } if(*wp != '\0'){ printf("error(4)\n"); break; } for(i1 = 0; i1 < 3; i1++){ printf("%d:%s\n", i1+1, item[i1]); } } fclose(fp); } char *GetCSVItem(char *wp, char *buff, int size) { int i1; buff[0] = '\0'; while(*wp == ' ' || *wp == '\t') wp++; if(*wp == '\0'){ return(NULL); } for(i1 = 0; i1 < MAX_ITEM_SIZE; i1++, wp++){ if(i1 >= size) return(NULL); buff[i1] = *wp; if(*wp == '\0'){ buff[i1] = '\0'; return(wp); } if(*wp == ','){ wp++; buff[i1] = '\0'; break; } } return(wp); } <csvファイル> 1,2,3 11,12,13 21,22,23

専門家に質問してみよう