2017-01-30 7 views
-2
#include <stdio.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <unistd.h> 
#include <string.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <limits.h> 
#include <stdlib.h> 


#define BUFSIZ 6 

ここで私は3文字コードのファイルを検索し、コードがトークンと一致すれば、入力したコードを出力するはずです。2回目にファイルを検索すると、セグメンテーションフォールトエラーが発生するのはなぜですか?

void country_search(char code[6], FILE *dir, FILE *BAC_ptr){ 

    char *token_off; 
    char *token; 
    char buf[512]; 

    while (!feof(dir)){ 
     if (fgets(buf, 512 , dir)){ 
      token = strtok(buf,"1234567890"); 
      while (token != NULL){ 
       token = strtok(NULL,"1234567890"); 
       code = strtok(code,"\n"); 
       if ((strcmp(code,token)) == 0){ 
       printf("token: %s\n", token); 
       } 
      } 
     } 
    } 
} 

int main(int argc, const char **argv) { 

    char code[6]; 

    FILE *BAC_ptr; 
    BAC_ptr = fopen("BinaryAllCountries.dat", "r"); 
    FILE *D_ptr; 
    D_ptr = fopen("directory.dat", "r"); 

    fprintf(stdout, "Hello! welcome to the country database press type in: quit[enter] to quit at anytime\n"); 
    fprintf(stdout, "enter character code of the country you want:\n "); 
    fgets(code, BUFSIZ, stdin); 

私が使用している場合、それは最初の入力を要求し、whileループはその後、戻ってくると、2回目は、それは私に、セグメンテーションフォールトエラーを与え、私はできませんcountry_search()メソッドを介して実行される、それを取ります理由を見つけてください。ここ

 while (strcmp(code, "quit\n") != 0) { 
     fprintf(stdout, "enter another character code of the country you want: \n"); 
      country_search(code, D_ptr, BAC_ptr); 
      fgets(code, BUFSIZ, stdin); 
     } 
} 

は私directory.datファイル

ABW3739AFG1511AGO43AIA3690ALB2635AND2654ANT4227ARE2547ARG5281ARM1532ASM4607ATA1336ATF1392ATG3721AUS4631AUT2675AZE1556BDI170BEL2717BEN62BFA149BGD1600BGR2775BHR1574BHS3759BIH2753BLR2695BLZ3797BMU3816BOL5302BRA5324BRB3778BRN1639BTN1620BVT1357BWA84CAF252CAN3837CCK4691CHE3597CHL5344CHN1684CIV355CMR193COD327COG307COK4715COL5367COM288CPV216CRI3887CUB3906CXR4658CYM3863CYP1703CZE2825DEU2956DJI376DMA3926DNK2846DOM3958DZA22ECU5389EGY396ERI447ESH1275ESP3519EST2867ETH470FIN2913FJI4740FLK5416FRA2934FRO2892FSM4857GAB489GBR3646GEO1745GHA529GIB2975GIN549GLP4044GMB509GNB574GNQ426GRC2996GRD4023GRL4004GTM4068GUF5442GUM4786GUY5459HKG1768HMD1433HND4109HRV2796HTI4087HUN3058IDN1813IND1790IOT122IRL3099IRN1832IRQ1851ISL3078ISR1871ITA3117JAM4130JOR1912JPN1892KAZ1936KEN592KGZ1980KHM1662KIR4806KNA4328KOR2356KWT1956LAO1998LBN2019LBR632LBY668LCA4352LIE3162LKA2380LSO613LTU3185LUX3208LVA3137MAC2037MAR818MCO3288MDA3270MDG691MDV2081MEX4174MHL4834MKD3231MLI731MLT3249MMR2125MNG2103MNP5001MOZ843MRT755MSR4194MTQ4153MUS776MWI712MYS2060MYT796NAM864NCL4900NER884NFK4965NGA907NIC4250NIU4940NLD3314NOR3334NPL2145NRU4874NZL4925OMN2189PAK2213PAN4270PCN5065PER5498PHL2262PLW5018PNG5048POL3355PRI4295PRK2171PRT3377PRY5481PSE2236PYF4769QAT2280REU927ROM3399RUS3433RWA947SAU2307SDN1142SEN1025SGP2330SGS1485SHN970SJM3552SLB5111SLE1073SLV3983SMR3455SOM1095SPM4388STP1004SUR5519SVK3477SVN3499SWE3572SWZ1165SYC1047SYR2400TCA4500TCD270TGO1206THA2468TJK2445TKL5129TKM2513TMP1724TON5146TTO4464TUN1227TUR2487TUV5164TWN2421TZA1188UGA1248UKR3617UMI5208URY5540USA4529UZB2572VAT3036VCT4433VEN5564VGB4555VIR4581VNM2594VUT5228WLF5257WSM5083YEM2614YUG3671ZAF1122ZMB1295 
+2

[なぜ「しばらく(!feofを(ファイル))」は常に間違っている?](http://stackoverflow.com/q/5431941/1606345) –

+0

あなたの入力と出力 – KevinDTimm

+0

が、それはあなたが入力することもできることを示します5文字の国コード? –

答えて

0

で次の行でプログラムがクラッシュ(valgrindはすぐに私に言った):

if ((strcmp(code,token)) == 0){ 

なぜ?あなたがNULLのためにあまりにも早くをテストするため:

while (token != NULL){ 
     token = strtok(NULL,"1234567890"); <- right here TOKEN can be set to NULL! 
     /* code = strtok(code,"\n"); MUST be moved elsewhere*/ 
     if ((strcmp(code,token)) == 0){ 
      printf("token: %s\n", token); 
     } 

を解決するためには、単に適切な場所でNULLチェックを挿入します。

while (token != NULL) { 
    token = strtok(NULL,"1234567890"); 
    if (token) 
    { 
     if (strcmp(code,token) == 0){ /* no need for extra parens here */ 
      printf("token: %s\n", token); 
     } 
    } 
} 

いくつかの余分な発言:

  1. BAC_PTR使用されていません。
  2. \nを削除する行をcodeから安全な場所に移動します。ループの外側で行うことが好ましい...しかし、さらに良い場合は、
  3. と入力するとこのクラッシュも発生します。したがって、入力後に直接\nを削除し、空の行をテストしてください。
  4. あなたの512のバッファは良くありません。 directory.datファイル全体では小さすぎ、3文字コードの1つが半分になります。
+1

BAC_ptrはまだ使われていませんが、ちょうど512の乱数を入れて、今すぐに変更していただきます。私はvalgrindを使用します。私はそれを見ていただきありがとうございます。 – jhowe

+0

@jhowe:それはあなたに害を及ぼすことはありませんが、私は 'valgrind'を時折秘密のメッセージとして解釈する方法を学びました。良いデバッガを見つける - 'gdb'はあなたにはうってつけのように聞こえるので、コードを一度に1行ずつ進めることができます。 – usr2564301

関連する問題