読者です 読者をやめる 読者になる 読者になる

C言語 字句解析

/*
英文のデータファイルを読み込み、英文中の単語を抽出後、文字コード順に並び替えを行い、頻度とともに一覧表ファイルに出力する。
・英文中の単語のうち、英単語は英文字、ハイフンで構成されており、数字データは数字、及びピリオドで構成されている。
・単語の長さは20文字以内、単語の種類は300種以内とする。
・単語が2行にまたがるときはその行の終わりに継続行を示すハイフンがある。
・ただし、ハイフンの後は通常の行と同じく改行\nがある。
・単語の区切りは空白、',', '.', '(', ')', とする。
・ただし、ピリオドの後が英字の場合は'.'も単語の一部とする。
・入力確認のため、英文ファイルのデータを編集せずにそのまま英文確認ファイルに出力を行う。
・英文ファイルはenglish.txtと言う名前で別途用意する。
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#define  COUNT_MAX 300                                  /*最大単語種類数*/
#define  STRING_MAX 500                                 /*一行の最大文字数*/
#define  WORD_MAX 20                                 /*一単語の最大文字数*/

int GetWord( void);
int UpdateWord( void);
int SortWord( void );
int WriteWord( void );

typedef struct WordFrequency_T{
  int   count;
  char    word[ COUNT_MAX ];
}WordFrequency_t;

static WordFrequency_t wordfrequency[ COUNT_MAX ];/*単語格納用 static*/

char  buf[ STRING_MAX ],work[STRING_MAX];                         /*一行データバッファ*/
char word_string[WORD_MAX];
int flag = 0;
/*********************************main********************************************/
int main(void)
{
  FILE *fp1,*fp2;
  fp1=fopen("english.txt","r");
   fp2=fopen("check.txt","a");

  if( fp1 == NULL ){
    fprintf( stderr, "ファイルが見つかりません\n");
    exit( EXIT_FAILURE );
  }
   if( fp2 == NULL ){
     fprintf( stderr, "ファイル作成エラー\n");
     return -1;
   }
  while( fgets( buf, STRING_MAX, fp1 ) != NULL ){
    fprintf(fp2,"%s",buf);
    if(flag==1){
      strcpy(work,word_string);
      strcat(work,buf);
      strcpy(buf,work);
      flag=0;
    }
    while(1){
      GetWord();
      UpdateWord( );
      if(  *buf =='\0'  ){
        break;
      }
    }
  }

  if( fclose( fp1 ) ){
    fprintf( stderr, "クローズに失敗しました\n");
    exit( EXIT_FAILURE );
  }
  if( fclose( fp2 ) ){
    fprintf( stderr, "クローズに失敗しました\n");
    exit( EXIT_FAILURE );
  }

  SortWord();
  WriteWord();
}
/************単語抽出*********************************************/
int GetWord( void )
{
  char *pbuf, *pstr;

  pstr = word_string;
  pbuf = buf;
  while( *pbuf == ' ' ){/*空白と,と”を読み飛ばす*/
    pbuf++;
  }
  if( *pbuf == '\0' ) { /*バッファが空,改行がきたときは終わる*/
        return 0;
  }
  if( isdigit( *pbuf ) ){                                       /*数字のときの処理*/
    while( isdigit( *pbuf ) || *pbuf == '.' ){                  /*ピリオドを数字データに含める*/
      *pstr++ = *pbuf++;
    }
    *pstr = '\0';
  }else if( isalpha( *pbuf ) ){                               /*英文字のときの処理*/
    while( isalpha( *pbuf ) ||  ( *pbuf == '\'' ) ){          /*'を含めて格納する'*/
      *pstr++ = *pbuf++;
    }
    if(*pbuf=='-'&&*(pbuf+1)=='\n'){
      flag=1;
    }else if(*pbuf=='.'&&isalpha(*(pbuf+1))){
      *pstr++ = *pbuf++;
      while(isalpha(*pbuf)){
        *pstr++ = *pbuf++;
      }
    }

  *pstr='\0';
  pbuf++;
  }else{
    pbuf++;      /*その他を飛ばす*/
    if(flag!=1)*pstr='\0';
  }
  strcpy( buf, pbuf );    /*残りの文字列をコピー*/
  return 0;
}
/************************************/
int UpdateWord( void )
{
  int i, j;
  if(flag==1)return 0;
  for( i=0; i < COUNT_MAX; i++ ){
    if( wordfrequency[i].count <= 0){
      strcpy( wordfrequency[ i ].word, word_string );
      wordfrequency[i].count = 1;
      break;
    }
    if( !strcmp( wordfrequency[i].word, word_string ) ){
      wordfrequency[ i ].count++;
      break;
    }
  }
  return 0;
}
/***********************************/
int SortWord( void )
{
  WordFrequency_t tmp;
  int i,j;
  for(i=0;wordfrequency[i].count!=0;i++){
    for(j=i+1;wordfrequency[j].count!=0;j++){
      if(strcmp(wordfrequency[i].word,wordfrequency[j].word)>0){
        tmp=wordfrequency[i];
        wordfrequency[i]=wordfrequency[j];
        wordfrequency[j]=tmp;
      }
    } }
  return 0;
}
/**********************************/
int WriteWord( void )
{
  int i;
  FILE *fp;

  fp = fopen( "result.txt", "w");
  if( fp == NULL ){
    fprintf( stderr, "ファイルが作成できません\n");
    return -1;
  }
  fprintf( fp, "***単語と頻度の一覧表****\n");
  fprintf( fp, "***-----------------****\n");
  for( i = 1; i < COUNT_MAX; i++){
     if( strlen( wordfrequency[ i ].word ) <= 0){
       break;
     }
    fprintf( fp, "%2d %s %4d\n", i, wordfrequency[ i ].word, wordfrequency[ i ].count );
  }
  if( fclose( fp ) ){
    fprintf( stderr, "クローズに失敗しました\n" );
    exit( EXIT_FAILURE );
  }
  return 0;
}