5

単語間に複数のスペースがあるかどうかを検出するコードがあります。その場合、それらを1つに変更します。そして、文の間に2つのスペースを作成する関数を追加する必要があります。
(文の最後の記号は . )

例えば。

テキスト付きのファイルがある場合:

これは私の最初のプログラムです。こんにちは世界

プログラムは私を印刷するはずです:

これは私の最初のプログラムです。こんにちは世界

コード:

# include <stdio.h>
# include <stdlib.h>

int main()
{
FILE *in;
char myStr[100],newStr[100];
int ch;
int j,i,k,z=0;

in=fopen("duom.txt","r");

if(in){
while(EOF != ch){
ch=fgetc(in);
myStr[z] = ch;
z++;
k=0;
for(i=0; myStr[i] != '\0'; i++) {     
    if(myStr[i-1] != '.' && myStr[i] == ' ' && myStr[i+1] == ' ' ) 
      continue;          
   newStr[k]= myStr[i]; 
   k++;      
}   
}
}

for(j=0;j<k;j++){       

     printf("%c",newStr[j]);                               
    }
printf("\n");

fclose(in);

system("pause");
return 0;
}

コード全体を書くように頼むのではなく、いくつかのアイデアを教えてください。

私の悪い英語でごめんなさい:/

4

2 に答える 2

5

このループは、ファイルをブロックで処理する一般的なアプローチに従います。

アプローチの修正:

# include <stdio.h>
# include <stdlib.h>

int main() {
  FILE *in;
  char myStr[100],newStr[100];
  int ch;
  int j,i,k,z=0;

  in=fopen("duom.txt","r");

  if(!(in)) { fprintf(stderr,"Error opening file!\n"); }
  else {        //the file was opened
    int go = 1; //master loop control
    while(go) { //master loop
      z  = 0;   //set sub loop
      ch = '\0';//control variables
      while(z < 100 && EOF != ch){ //process file in 99 character blocks
        ch=fgetc(in);              //getting one character at a time 
        if(EOF == ch) { go = 0; }  //break master loop
        else { myStr[z++] = ch; }  //or process char
      }
      myStr[z] = '\0';             //null terminate the string
      for(i=0; myStr[i] != '\0'; i++) {
        //i=99='\0' <-- assumed is highest string size

        //if i=0; Do you really want that leading space?
        if(i== 0 && myStr[i] == ' ' ) { continue; }

        //if i=98 it is the last char in the string i=99 should be '\0'
        //So do you really want that trailing space?
        if(i==98 && myStr[i] == ' ' ) { continue; }

        //Same rational as above.
        //So do you really want those trailing 2 spaces?
        if(i==97 && myStr[i] == ' ' && myStr[i+1] == ' ') { continue; }

        //if i=0; myStr[i-1] will likely cause a segmentation fault
        if(i > 0 && myStr[i] == ' ' && myStr[i+1] == ' ' && myStr[i-1] != '.') { continue; }
        newStr[k] = myStr[i]; 
        k++;      
      }
      for(j=0;j<k;j++){ printf("%c",newStr[j]); } //print the 99 char block
    }
    printf("\n"); //print a newline for good measure
    fclose(in);   //close file
  }
  return 0;
}

サイズが 99 文字を超えるファイルの場合、コードは誤動作することに注意してください。これは、1 つの 99 文字ブロックの終わりから別のブロックの始まりまでのスペーシング形式の比較が行われないためです。前のブロックの i=1 & i=2 の値を i=97 & i=98 の最後の 2 文字と比較して、先頭/末尾のスペースを削除しないことで、これを実装できます。

これは別のより良いループです。他のアプローチのブロックバリアの問題を解決し、メモリの使用量を大幅に削減

より良いアプローチ:

# include <stdio.h>
# include <stdlib.h>
int main() {
  FILE *in;
  in=fopen("duom.txt","r");

  if(!(in)) { fprintf(stderr,"Error opening file!\n"); return -1; }
           //the file was opened
  int x; //stores current  char
  int y; //stores previous char
  for(y='\0'; (x=fgetc(in)) != EOF; y=x) { //read in 'x' until end of file
// The following conditions cover all cases:
// is 'x' not a space? Then print 'x'
// is 'x' a space but 'y' a period? Then print two spaces
// is 'x' a space and 'y' not a period but also not a space? Then print a space
// Otherwise 'x' is part of extra spacing, do nothing
         if(x != ' ')                         { printf("%c",x); }
    else if(x == ' ' && y == '.')             { printf("  ");   }
    else if(x == ' ' && y != '.' && y != ' ') { printf(" ");    }
    else { ; }  //do nothing
  }   
  printf("\n"); //print a newline for good measure
  fclose(in);   //close file
  return 0;
}
于 2013-02-17T20:26:17.520 に答える
2

strtok()正しい数のスペースで区切られたトークンを使用して連結することをお勧めします。トークンがピリオドで終わる場合は、2 つのスペースを使用します。それ以外の場合は、1 つだけ使用してください。この方法では、単語間にいくつのスペースがあるかを確認する必要さえありません。

于 2013-02-17T20:54:54.030 に答える