2016-08-07 13 views
-2

Das Programm wird in die Blase geschrieben, um die vom Benutzer eingegebenen Daten im Format dd/mm/yyyy zu sortieren, wobei der Monat eine Zeichenfolge oder eine ganze Zahl sein kann. Nach der Kompilierung wird kein Fehler angezeigt, aber nach der Eingabe der Daten während der Ausführung tritt ein Fehler bei der Segmentierung auf. Ich kann den Fehler nicht erkennen. Außerdem bin ich relativ neu im Programmieren. Bitte helfen Sie.Segmentierungsfehler im c-Programm beim Sortieren von Strings

#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

Ihr Code nicht eingerückt ist, ist es sehr schwer zu folgen. – SurvivalMachine

+5

String Vergleich mit '==' Operator funktioniert nicht in C, wie Sie erwarten können. Es vergleicht Speicheradressen, keine Zeichen und liefert daher immer 'false' zurück, stattdessen' strcmp'. – buc

+4

'char * sub1, * sub2, * sub3, * sub4;' muss dafür reserviert werden. – BLUEPIXY

Antwort

1

Die segfault ist auf nicht initialisierten Speicher. Wenn ich dieses Programm kompiliere, um nach Warnungen zu suchen, werden zwei Hauptkategorien von Problemen angezeigt: die nicht initialisierten Speicherzugriffe und die Zeichenfolgenvergleiche.

$ 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") { 
      ^~~~~~~~~~~ 

... ausgelassen wiederholt ...

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

Ich habe die empfohlenen Änderungen in mein Programm-verwendet strcmp, initialisiert * sub1, * sub2 ... etc = NULL, und geändert void main zu int main und fügte eine Rückkehr 0 hinzu. Kein Fehler beim Kompilieren. Eingestellt am 01/01/2018,01/01/2015,01/01/2020 und bekam einen Segmentierungsfehler bei der Ausführung. – geedee

+0

@geedee, es ist gut, dass 'subN'-Variablen initialisiert werden - jetzt würde ich erwarten, dass es jedes Mal segfault statt abhängig von was auch immer im nicht initialisierten Speicher ist. (Übrigens müssen Sie so viele NULL-Werte eingeben, wie es N-SubN-Variablen gibt). Außerdem muss "subN" zugewiesen werden, bevor Sie sie verwenden können. Sie haben sie so initialisiert, dass sie nirgendwohin zeigen, indem Sie 'NULL' zuweisen. –

+0

Ich habe den SubN-Variablen Speicher zugewiesen (kein Segmentierungsfehler mehr), ein paar andere Fehler korrigiert und das Programm funktioniert! – geedee

0

Ändern Sie Code aus,

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); 
}} 

zu,

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); 
    }} 

Dies funktioniert ..

Verwandte Themen