2015-06-18 122 views
-2

爲什麼我的程序崩潰時,我將一個數字作爲字符串的第一個字符?
但是,如果我把字符串作爲字符串的第一個字符,我的程序不會崩潰。
感謝您的幫助!
這裏是我的源代碼:C - 程序崩潰

/* 
************ FT SPLIT WHITESPACES ************ 
** Coded by Linsap pour 42 - J-M W 
** Dernière modification le 18/06/15 
************ FT SPLIT WHITESPACES ************ 
*/ 

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

int  ft_is_alpha(char const c) 
{ 
    return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); 
} 

int  ft_is_equal_to(char const *str, int const i) 
{ 
    return (i == 0 && ft_is_alpha(str[i])) || ((str[i - 1] == '\n' || str[i - 1] == '\t' || str[i - 1] == ' ') && ft_is_alpha(str[i])); 
} 

void  letter_count(char const *str, int *letter, int *word) 
{ 
    int  i; 
    int  length; 
    int  count; 

    count = 0; 
    length = 0; 
    for (i = 0; str[i]; ++i) 
    { 
     if (ft_is_equal_to(str, i)) 
     { 
      ++count; 
      int  j; 

      j = i - 1; 
      while (str[++j] != '\0' && ft_is_alpha(str[j])) 
      { 
       ++length; 
      } 
     } 
    } 

    *letter = length + 1; 
    *word = count; 
} 

char **set_buffer(char **buffer, int const set, int const length) 
{ 
    int  i; 

    for (i = 0; i < length; ++i) 
    { 
     if ((buffer[i] = malloc(sizeof(char) * (set))) == NULL) 
      return (0); 
    } 

    return (buffer); 
} 

char **ft_split_whitespaces(char const *str) 
{ 
    char **buffer; 
    int  word; 
    int  letter; 
    int  i; 
    int  j; 
    int  colonne; 

    letter_count(str, &letter, &word); 

    if ((buffer = malloc(sizeof(char *) * (word))) == NULL) 
     return (0); 

    set_buffer(buffer, letter, word); 

    i = 0; 
    j = 0; 
    colonne = 0; 
    while(str[i] != '\0') 
    { 
     if (str[i] != ' ' && str[i] != '\t' && str[i] != '\n') 
     { 
      if (ft_is_alpha(str[i])) 
       buffer[colonne][j] = str[i]; 
      else 
       buffer[colonne][j] = '@'; 
     } 
     else 
     { 
      buffer[colonne][j] = 0; 
      j = 0; 
      ++colonne; 
     } 
     ++j; 
     ++i; 
    } 

    buffer[colonne][j] = 0; 
    return (buffer); 
} 

int  main(void) 
{ 
    char **buffer; 
    char sentence[] = "1n\nDeuxieme\tMot"; 
    int  i; 

    buffer = ft_split_whitespaces(sentence); 
    for(i = 0; i < 3; ++i) 
     printf("%s", buffer[i]); 

    for (i = 0; i < 3; ++i) 
     free(buffer[i]); 

    return (0); 
} 
+0

你是否用'ft_is_alpha()'用法檢查邏輯? –

+4

使用調試器。 – cubrr

+0

用所有的警告和調試信息('gcc -Wall -Wextra -g')編譯,然後使用調試器('gdb')和[valgrind](http://valgrind.org/)(如果可用)... –

回答

1

如果調用int ft_is_equal_to()(其中有一個可怕的名字......)在一個字符串,它不以英文字母不開始,在開始i將爲零和

i == 0 && ft_is_alpha(str[i]) 

會是假的,所以||的下一部分將被評估:

str[i - 1] == '\n' || str[i - 1] == '\t' || str[i - 1] == ' ' 

其中訪問str[-1],這不是字符串的有效部分。您因此執行未定義的行爲,在這個幸運的情況下會導致崩潰。

+0

You只是把我給它! –

1

當你通過i = 0

int ft_is_equal_to(char const *str, int const i) 
{ 
    return (i == 0 && ft_is_alpha(str[i])) || ((str[i - 1] == '\n' 
        || str[i - 1] == '\t' || str[i - 1] == ' ') && ft_is_alpha(str[i])); 
} 

在字母字符在str[0]的話,那麼ft_is_alpha(str[i]))將是真實的,而編譯器不需要評估任何其他||測試中有此功能的問題。

但在標號的str[0]然後ft_is_alpha(str[i]))的情況下將是錯誤的,並且表達str[i - 1] == '\n'將被評估,導致超出範圍的索引和一個可能的SEG-故障。