2017-02-21 28 views
1
#include <stdio.h> 
#include <string.h> 

int in_mot(char *str) //check whether input from text file in mot table 
{ 
    FILE *fp_mot; 
    int i = 0, j = 0, r; 
    char check[300], first_field[7]; 

    fp_mot = fopen("mot.txt", "r"); 

    while (1) 
    { 
     if (fgets(check, sizeof(check), fp_mot) == NULL) 
     { 
      printf("EOF"); 
      return 0; 
     } 
     else 
     { 
      i = 0; 
      for (i = 0; i < 7; i++) 
       first_field[i] = 0; 

      i = 0; 
      while (check[i] != ' ') 
      { 
       first_field[i] = check[i]; 
       i++; 
      } 
      first_field[i] = '\0'; 

      if (strcmp((char*)str, (char*)first_field) == 0) 
      { 
       puts(first_field); 
       return 1; 
      } 
     } 
    } 
    if (j == 18) 
     return 0; 
} 

int main() 
{ 
    char temp[30], wc[10], str[4][10]; 
    int i = 0, j = 0, k = 0, z; 
    FILE *fp; 

    int LC = 0, RC = 0, STP = 1; 

    fp = fopen("ip.txt", "r"); 

    while (1) 
    { //1-break a line and store in array of strings(str) 
     if (fgets(temp, 30, fp) == NULL) 
      break; 
     else 
     { 
      j = 0; i = 0; 
      while (j < 3) 
      { 
       k = 0; 
       for (z = 0; z < 10; z++) 
        wc[z] = 0; 
       while (temp[i] != ' ' && temp[i] != ',') 
       { 
         wc[k] = temp[i]; 
         i++; 
         k++; 
       } 
       i++; 
       wc[k] = '\0'; 
       strcpy(str[j], wc); 
       j++; 
      } 
     } 

     //str[0][3] = '\0'; 
     if (in_mot(str[0])) 
     { 
      //printf("\n yesssssssss"); 
     } 
    } 

    return 0;  
} 

strおよびfirst_fieldは私の2つの文字列です。 puts()によって、両方の文字列が等しい場合、それらは同じ出力を出力しますが、strcmp()はゼロ以外の値を返しますか? strfirst_fieldは文字列と見なされますか? strlenで長さを印刷しようとしたところ、出力が表示されませんでした。Cの文字列比較関数

+5

その後、彼らは唯一の*外観*同じ:ここ

は、バッファオーバーフローをチェックし、報告したバージョンです。 –

+3

'strlen'を印刷してみてください。それは印刷できない文字のために異なる可能性があります – StoryTeller

+3

@ash /とあなたのテストデータを使って完全なテストプログラムを提供してください。さもなければ、あなたの観察は再現可能ではありません。 – Scheff

答えて

1

おそらく、文字列は一部の印刷できない文字では異なる場合があります。画面に表示されない\nまたは\rまたは(空白)

例えば:

char first_field[] = "Test\r"; 
char str[] = "Test\n"; 
puts(first_field); 
puts(str); 
if (!strcmp(str, first_field)) 
{ 
    puts(first_field); 
    return 1; 
} 

は同じ出力が得られますが、文字列が本当に異なっています。

UPDATE:チェックする

可能な方法:オプションとして

// check pointers 
if (str != NULL && first_field != NULL) 
{ 
    // check length 
    if (strlen(str) == strlen(first_field)) 
    { 
     // check content 
     if (!strcmp(str, first_field)) 
     { 
      //do something for equal strings 
      return 1; 
     } 
    } 
} 

、あなたは文字列を比較する際に一部の文字をスキップし、独自の比較を、書き込み、またはすべての非印字可能な文字を削除することができます文字列の末尾例えば、strcmp使用する前に:

void removeEmptyEnd(char * str) 
// removes insignificant endings (including space with code 32) 
{ 
    if (!str) 
    { 
     return; 
    } 
    // Start from the end 
    int i = strlen(str); 
    // and skip space and other non-printable chars 
    while (i >= 0 && str[i] <= 32) 
    { 
     i--; // move to next char 
    } 
    // put new null-termitator to the end of string 
    str[i+1] = '\0'; 
} 

UPDATE 2:

また、開封後のファイルポインタをチェック:

fp=fopen("ip.txt","r"); 
if(fp) 
{ 
    // use file - read data 
} 
+0

これを確認する方法はありますか? – ash

+0

@ash StoryTellerは次のように書いています。 'strlen()'は '\ r'と' \ n'を任意の文字として扱います!= 0 – Scheff

+0

はいエスケープ文字のために長さが異なるかもしれませんが、アルファベットと同じ文字を含みます。余分なエスケープシーケンス文字を見つけるのですか? – ash

2

は、各文字コードではなく、(印刷可能)のみ見える文字を印刷してみます。次に、2つの文字列の間で異なるものが見つかるはずです。

と同様に、

char* p = str; 
while (*p) 
{ 
    printf("%02x ", p++); 
} 
0

あなたのパーサは先の配列の長さを検証しません。 ip.txtに9文字以上の単語(1つのスペースまたはコンマで区切られた単語)が含まれている場合、またはファイルmot.txtのいずれかの行の最初の単語が6文字より長い場合は、未定義の動作。

ip.txt の行が少なくとも3枚のセパレータが含まれていない場合やmot.txtの行は、すべてのスペースが含まれていない場合にも、未定義の動作を持っています。

#include <stdio.h> 
#include <string.h> 

int copy_word(char *dest, int size, const char *src, int len, 
       const char *filename, int lineno) { 
    *dest = '\0'; 
    if (len >= size) { 
     fprintf(stderr, "%s:%d: word longer than %d characters: %.*s\n", 
       filename, lineno, size - 1, len, src); 
     return -1; 
    } 
    strncat(dest, src, len); 
    return len; 
} 

int in_mot(const char *str) { //check whether input from text file in mot table 
    FILE *fp_mot; 
    char check[300], first_field[7]; 
    int i, lineno = 0; 

    fp_mot = fopen("mot.txt", "r"); 
    if (fp_mot == NULL) { 
     perror("cannot open file mot.txt"); 
     return 0; 
    } 

    while (fgets(check, sizeof(check), fp_mot)) { 
     lineno++; 
     i = strcspn(check, " \n"); 
     copy_word(first_field, sizeof first_field, check, i, "mot.txt", lineno); 
     if (strcmp(str, first_field) == 0) { 
      puts(first_field); 
      return 1; 
     } 
    } 
    return 0; 
} 

int main(void) { 
    char temp[30], wc[10], str[4][10]; 
    int i, j, k; 
    int lineno = 0; 
    FILE *fp; 

    //int LC = 0, RC = 0, STP = 1; 

    fp = fopen("ip.txt", "r"); 
    if (fp == NULL) { 
     perror("cannot open file ip.txt"); 
     return 1; 
    } 

    while (fgets(temp, sizeof(temp), fp)) { 
     lineno++; 
     for (j = i = 0; j < 3; j++) { 
      k = strcspn(temp + i, " ,\n"); 
      copy_word(wc, sizeof(wc), temp + i, k, "ip.txt", lineno); 
      strcpy(str[j], wc); 
      i += k; 
      if (temp[i] != '\0') 
       i++; 
     } 
     if (in_mot(str[0])) { 
      printf("yes!\n"); 
     } 
    } 
    return 0; 
}