2016-08-07 21 views
-2

プログラムは、ユーザが入力した日付をdd/mm/yyyy形式でバブリングするように書かれています。月は文字列または整数です。コンパイル後にエラーは表示されませんが、実行中に日付を入力した後にセグメンテーションフォールトエラーが表示されます。私は間違いを理解することができません。また、私はプログラミングに比較的新しいです。助けてください。コード文字列のソート中にcプログラムでセグメンテーションエラーが発生する

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

void readElements(char **date, int n) { 
    printf("enter the dates in dd/mm/yyyy format where month can be a string or " 
      "an integer\n"); 
    for (int i = 0; i < n; i++) { 
     date[i] = (char *)malloc(50); 
     scanf("%s", date[i]); 
    } 
} 

char strcompare(char *a, char *b, int n, int length1, int length2) { 
    char *sub1, *sub2, *sub3, *sub4; 
    int c = 0, d = 0, e = 0, f = 0; 
    // comparing year 
    while (c < 4) { 
     sub1[c] = a[length1 - 4 + c]; 
     c++; 
    } 
    while (d < 4) { 
     sub2[d] = b[length2 - 4 + c]; 
     d++; 
    } 
    if (strcmp(sub1, sub2) > 0) { 
     return 'o'; 
    } else if (strcmp(sub1, sub2) < 0) { 
     return 'z'; 
    } else 
     // comparing month 
    { 
     for (int i = length1 - 6; i > 2; i--) { 
      sub3[e] = a[i]; 
      e++; 
     } 
     for (int i = length2 - 6; i > 2; i--) { 
      sub4[f] = b[i]; 
      f++; 
     } 
     if (strcmp(sub3, sub4) == 0) { 
      int g = 0, h = 0; 
      // comparing day 
      char *sub5, *sub6; 
      while (g < 2) { 
       sub5[g] = a[g]; 
       g++; 
      } 
      while (h < 2) { 
       sub6[h] = b[h]; 
       h++; 
      } 
      if (strcmp(sub5, sub6) > 0) { 
       return 'o'; 
      } else { 
       return 'z'; 
      } 
     } else { 
      if (sub3 == "january") { 
       strcpy(sub3, "01"); 
      } 
      if (sub4 == "january") { 
       strcpy(sub4, "01"); 
      } 
      if (sub3 == "february") { 
       strcpy(sub3, "02"); 
      } 
      if (sub4 == "february") { 
       strcpy(sub4, "02"); 
      } 
      if (sub3 == "march") { 
       strcpy(sub3, "03"); 
      } 
      if (sub4 == "march") { 
       strcpy(sub4, "03"); 
      } 
      if (sub3 == "april") { 
       strcpy(sub3, "04"); 
      } 
      if (sub4 == "april") { 
       strcpy(sub4, "04"); 
      } 
      if (sub3 == "may") { 
       strcpy(sub3, "05"); 
      } 
      if (sub4 == "may") { 
       strcpy(sub4, "05"); 
      } 
      if (sub3 == "june") { 
       strcpy(sub3, "06"); 
      } 
      if (sub4 == "june") { 
       strcpy(sub4, "06"); 
      } 
      if (sub3 == "july") { 
       strcpy(sub3, "07"); 
      } 
      if (sub4 == "july") { 
       strcpy(sub4, "07"); 
      } 
      if (sub3 == "august") { 
       strcpy(sub3, "08"); 
      } 
      if (sub4 == "august") { 
       strcpy(sub4, "08"); 
      } 
      if (sub3 == "september") { 
       strcpy(sub3, "09"); 
      } 
      if (sub4 == "september") { 
       strcpy(sub4, "09"); 
      } 
      if (sub3 == "october") { 
       strcpy(sub3, "10"); 
      } 
      if (sub4 == "october") { 
       strcpy(sub4, "10"); 
      } 
      if (sub3 == "november") { 
       strcpy(sub3, "11"); 
      } 
      if (sub4 == "november") { 
       strcpy(sub4, "11"); 
      } 
      if (sub3 == "december") { 
       strcpy(sub3, "12"); 
      } 
      if (sub4 == "december") { 
       strcpy(sub4, "12"); 
      } 
      if (strcmp(sub3, sub4) > 0) { 
       return 'o'; 
      } else { 
       return 'z'; 
      } 
     } 
    } 
} 

void Bubblesort(char **date, int n) { 
    int i, j; 
    char *t; 
    for (i = 0; i < n - 1; i++) { 
     for (j = 0; j < n - i - 1; j++) { 
      int length1 = strlen(date[j]); 
      int length2 = strlen(date[j + 1]); 
      if (strcompare(date[j], date[j + 1], n, length1, length2) == 'o') { 
       t = date[j]; 
       date[j] = date[j + 1]; 
       date[j + 1] = t; 
      } 
     } 
    } 
} 

void printarray(char **date, int n) { 
    printf("Sorted array:\n"); 
    for (int i = 0; i < n; i++) { 
     printf("%s\n", date[i]); 
    } 
} 

void main() { 
    int n; 
    char *date[50]; 
    printf("enter the number of elements that are to be sorted\n"); 
    scanf("%d", &n); 
    readElements(date, n); 
    Bubblesort(date, n); 
    printarray(date, n); 
} 
+2

あなたのコードは、インデントされていない、それは従うことが非常に難しい...の繰り返しを省略しました。 – SurvivalMachine

+5

'=='演算子との文字列比較は期待通りにCでは動作しません。これは文字ではなくメモリアドレスを比較し、常に 'false'を返します。代わりに' strcmp'を使います。 – buc

+4

'char * sub1、* sub2、* sub3、* sub4;'はこれに割り当てる必要があります。 – BLUEPIXY

答えて

1

セグメンテーション違反が初期化されていないメモリを使用したためです。このプログラムをコンパイルして警告を探すと、初期化されていないメモリアクセスと文字列比較の2つの主要なカテゴリが示されます。

$ clang-3.8 -c -Wall -fPIE -fsanitize=memory sorting_.c -o sorting.o 
sorting_.c:59:16: warning: result of comparison against a string literal is unspecified (use strncmp instead) [-Wstring-compare] 
     if (sub3 == "january") { 
      ^~~~~~~~~~ 
sorting_.c:62:16: warning: result of comparison against a string literal is unspecified (use strncmp instead) [-Wstring-compare] 
     if (sub4 == "january") { 
      ^~~~~~~~~~ 
sorting_.c:65:16: warning: result of comparison against a string literal is unspecified (use strncmp instead) [-Wstring-compare] 
     if (sub3 == "february") { 
      ^~~~~~~~~~~ 

は...

sorting_.c:38:7: warning: variable 'sub4' is uninitialized when used here [-Wuninitialized] 
     sub4[f] = b[i]; 
     ^~~~ 
sorting_.c:15:34: note: initialize the variable 'sub4' to silence this warning 
    char *sub1, *sub2, *sub3, *sub4; 
           ^
            = NULL 
sorting_.c:34:7: warning: variable 'sub3' is uninitialized when used here [-Wuninitialized] 
     sub3[e] = a[i]; 
     ^~~~ 
sorting_.c:15:27: note: initialize the variable 'sub3' to silence this warning 
    char *sub1, *sub2, *sub3, *sub4; 
         ^
          = NULL 
sorting_.c:50:9: warning: variable 'sub6' is uninitialized when used here [-Wuninitialized] 
     sub6[h] = b[h]; 
     ^~~~ 
sorting_.c:44:24: note: initialize the variable 'sub6' to silence this warning 
     char *sub5, *sub6; 
        ^
         = NULL 
sorting_.c:46:9: warning: variable 'sub5' is uninitialized when used here [-Wuninitialized] 
     sub5[g] = a[g]; 
     ^~~~ 
sorting_.c:44:17: note: initialize the variable 'sub5' to silence this warning 
     char *sub5, *sub6; 
       ^
       = NULL 
sorting_.c:23:5: warning: variable 'sub2' is uninitialized when used here [-Wuninitialized] 
    sub2[d] = b[length2 - 4 + c]; 
    ^~~~ 
sorting_.c:15:20: note: initialize the variable 'sub2' to silence this warning 
    char *sub1, *sub2, *sub3, *sub4; 
       ^
        = NULL 
sorting_.c:19:5: warning: variable 'sub1' is uninitialized when used here [-Wuninitialized] 
    sub1[c] = a[length1 - 4 + c]; 
    ^~~~ 
sorting_.c:15:13: note: initialize the variable 'sub1' to silence this warning 
    char *sub1, *sub2, *sub3, *sub4; 
      ^
      = NULL 
sorting_.c:163:1: warning: return type of 'main' is not 'int' [-Wmain-return-type] 
void main() { 
^ 
sorting_.c:163:1: note: change return type to 'int' 
void main() { 
^~~~ 
int 
+0

私はプログラムの使用strcmp、initialised * sub1、* sub2 ... etc = NULLに推奨変更を組み込み、mainをint mainに変更し、戻り値0を追加しました。 01/01/2018,01/01/2015,01/01/2020を入力し、実行時にセグメント化エラーが発生しました。 – geedee

+0

@geedee、 'subN'変数が初期化されているのは良いことです。初期化されていないメモリに依存するのではなく、毎回segfaultすると思います。 (BTWではN個の 'subN'変数と同じくらい多くの' NULL'を入れなければなりません)。また、 'subN'はそれらを使う前に割り当てなければなりません。 'NULL'を代入することでどこにもポインタを置かないように初期化しました。 –

+0

私はsubN変数にメモリを割り当てました(それ以上のセグメンテーションフォールトはありません)、いくつかの他のエラーを修正し、プログラムが動作します! – geedee

0

変更し、あなたに、

void readElements(char **date,int n) 
{printf("enter the dates in dd/mm/yyyy format where month can be a string or an integer\n"); 
for(int i=0;i<n;i++) 
{date[i]=(char*)malloc(50); 
scanf("%s",date[i]); 
printf("%d %s \n",i, str); 
}} 

に、

void readElements(char **date,int n) 
{printf("enter the dates in dd/mm/yyyy format where month can be a string or an integer\n"); 

for(int i=0;i<n;i++)  
{ 
     char *str ; 
     str = (char*)malloc(60); 

     date[i]= str; 

scanf("%s",str); 

printf("%d %s \n",i, str); 
    }} 

これは動作します。..

関連する問題