2017-08-28 53 views
2

我寫了下面的代碼來獲得在2 d字符數組字符數組排序

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

void swap(char *,char *); 

void main() { 
    char a[20][20]; 
    int Pass = 0, i = 0, j = 0, n; 

    printf("\nHow many elements you want to sort ? >> "); 
    scanf("%d", &n); 
    printf("\n\nEnter the elements to be sorted :\n"); 
    for (i = 0; i < n; i++) 
     scanf("%s", a[i]); 
    for (Pass = 1; Pass < n; Pass++) { 
     for (j = 0; j < n - Pass; j++) 
      if (strcmp(a[j], a[j + 1]) < 0) 
       swap(a[j], a[j + 1]); 
     printf("\n\nPass = %d\n", Pass); 
     for (i = 0; i < n; i++) 
      printf(" %s ", a[i]); 
    } 
} 

void swap(char *a, char *b) { 
    char *t; 
    *t = *a; 
    *a = *b; 
    *b = *t; 
} 

排序字符串,但是,我得到的輸出

How many elements you want to sort ? >> 5 
Enter the elements to be sorted : 
1 2 3 4 5 
Pass = 1 
2 3 4 5 1 
Pass = 2 
3 4 5 2 1 
Pass = 3 
4 5 3 2 1 
Pass = 4 
Segmentation fault (core dumped) 

爲什麼我遇到的分割故障? (相同的代碼正常工作,如果我使用一個整數數組,而不是一個字符數組的)

+0

主必須返回'INT ' –

+0

你的'swap'功能是錯誤的。 1)'char * t; * t = * a;':使用未初始化的變量。 2)應該交換的是一個數組而不是一個指針(或一個「char」)。 – BLUEPIXY

+0

節省時間,啓用所有編譯器警告:'char * t; * t = * a;'應警告在初始化之前使用't'。 – chux

回答

1

入口點main被定義爲

int main() 

或(帶參數)

int main(int argc, char* argv[]) 

但可能會或可能不會返回一些價值。


在功能swap要訪問未初始化的指針導致undefined behavior。沒有必要使用指針。使用普通的char

void swap(char *a,char *b) 
{ 
    char t; 
    t=*a; 
    *a=*b; 
    *b=t; 
} 

同時,爲了避免緩衝區溢出,你應該告訴scanf()多少個字符從輸入緩衝器

scanf("%19s",a[i]); 

掃描和檢查,如果掃描成功。

現在你應該得到正確的結果。 Here is fixed code.

+0

C規範與您可接受的'main()'簽名的有限樣本不一致,因爲定義了其他實現,而不是UB簽名是可能的。 – chux

+0

感謝您的信息。有人告訴我'虛空主'有UB,因爲我的生活是謊言。 –

+2

@FilipKočica大多數情況下'void main()'無論如何都會工作。這裏的問題顯然是未初始化的指針。 –

1

你搞砸了你的指針在swap方法。目前你正在做的:

void swap(char *a,char *b) 
{ 
    char *t; 
    *t=*a; 
    *a=*b; 
    *b=*t; 
} 

此行*t = *a似乎是SEGV一個非常可能的候選人,因爲t是一個字符指針是未初始化。我通過GDB跑到你的代碼和gdb也說同樣的話:

Reading symbols from a.out...done. 
(gdb) run 
Starting program: /home/rohan/Documents/src/a.out 

How many elements you want to sort ? >> 5 


Enter the elements to be sorted : 
1 2 3 4 5 

Program received signal SIGSEGV, Segmentation fault. 
0x0000555555554a21 in swap (a=0x7fffffffdce0 "1", b=0x7fffffffdcf4 "2") at testBubble.c:26 
26  *t=*a; 
(gdb) 

你不需要T作爲一個指針變量。這只是交換所需的臨時變量。因此,改變你的方法是這樣,其固定段錯誤在我的情況:

void swap(char *a,char *b) 
{ 
    char t; 
    t=*a; 
    *a=*b; 
    *b=t; 
} 
0

的交換功能是不正確的:你提領該未初始化的指針t,導致未定義的行爲:在你的情況下分割故障。

而應該定義tchar

void swap(char *a, char *b) { 
    char t; 
    t = *a; 
    *a = *b; 
    *b = t; 
} 

但是這隻能使用單個字符單詞工作。

要交換的多達19個字節的話,使用這個:

void swap(char *a, char *b) { 
    char t[20]; 
    strcpy(t, a); 
    strcpy(a, b); 
    strcpy(b, t); 
} 

,並添加一些額外的測試和保護在main功能,以避免發生不可預料的行爲:

int main(void) { 
    char a[20][20]; 
    int Pass = 0, i = 0, j = 0, n; 

    printf("\nHow many elements you want to sort ? >> "); 
    if (scanf("%d", &n) != 1 || n < 0 || n > 20) 
     return 1; 
    printf("\n\nEnter the elements to be sorted :\n"); 
    for (i = 0; i < n; i++) { 
     if (scanf("%19s", a[i]) != 1) 
      return 1; 
    } 
    for (Pass = 1; Pass < n; Pass++) { 
     for (j = 0; j < n - Pass; j++) { 
      if (strcmp(a[j], a[j + 1]) < 0) 
       swap(a[j], a[j + 1]); 
     } 
     printf("\nPass = %d\n", Pass); 
     for (i = 0; i < n; i++) 
      printf(" %s", a[i]); 
     printf("\n"); 
    } 
    return 0; 
}