带有struct 2d数组的strcmp

时间:2014-01-29 00:27:08

标签: c arrays struct

我必须进行字典模拟器的二进制搜索,现在这是我的功能,我不知道为什么它会崩溃,如果有人可以帮助我,我会很开心..! ^^

这是我的结构:

typedef struct
{
    char *world;
    char *meaning;
} par;

这里的代码不起作用。 我会为我的英语和变量的意大利名字感到抱歉,但我是意大利人...... ^^ 如果你需要一些建议,请告诉我..! 附: 我尽力评论,再次抱歉..!

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

#define MAX 40
typedef struct
{
    char *Parola;
    char *Significato;
} par;

int Ricerca(par Dizionario[MAX][21], char Richiesta[20], int Min, int Max, int Iniziale);

int main()
{
   par Dizionario[MAX][21] =
   {
       { 
          /////////////////////load my 2d array////////////////////
           //seconda riga
           {"Accendere", "Trasmettere energia elettrica a un apparecchio o dispositivo per farlo funzionare"},
           {"Bellezza","Qualita' di ciò che è bello"},
           {"Comune","Che e' di tutti, o che appartiene a piu' persone o cose"},
           {NULL, NULL},
           {"Elenco", "Nota, registro ordinato"},
           {NULL, NULL},
           {NULL, NULL},
           {NULL, NULL},
           {"Impetuoso","Che si muove con impeto [anche in senso figurato]; che si lascia vincere dall'impeto"},
           {"Lancio","Atto, effetto del lanciare o del lanciarsi"},
           {NULL, NULL},
           {NULL, NULL},
           {NULL, NULL},
           {"Produrre","Presentare, allegare, citare"},
           {NULL, NULL},
           {NULL, NULL},
           {"Saccone","Grosso sacco, imbottito generalmente di paglia, che si mette sotto il materasso o si usa talvolta in sua vece"},
           {NULL, NULL},
           {NULL, NULL},
           {"Verticale","Perpendicolare a un piano orizzontale; che sta ritto con la parte superiore in alto e l'inferiore in basso"},
           {NULL, NULL}
        }
    };  


    int i, j, flag, Iniziale = 0;
    par temp;
    char Richiesta[20], Rtemp[20];

    /////////////////////bubble sort/////////////////////
    for(j=0; j<21;j++)
    { 
        for(i=0; i<MAX && Dizionario[i+1][j].Parola != NULL; i++)
        { 
           if(strcmp(Dizionario[i][j].Parola, Dizionario[i+1][j].Parola) == 1) 
           { 
               temp=Dizionario[i][j];
               Dizionario[i][j] = Dizionario[i+1][j];
               Dizionario[i+1][j] = temp;
           }
        }
    }
//i'm gonna ask to the user what word he want
    printf("Che parola vuole cercare?");
    gets (Richiesta);
    strcpy(Rtemp, Richiesta);
    printf("%s", Rtemp);
    Rtemp[0] = toupper(Rtemp[0]);
    printf("\n%s", Rtemp);
//I'm checking what's the first char, if it's a, i'm gonna assign 0 so it's
//it's gonna to the 'n' column and shifting there
    switch(Rtemp[0])
    {
        case 'A': Iniziale = 0;
                  break;
        case 'B': Iniziale = 1;
                  break;
        case 'C': Iniziale = 2;
                  break;
        case 'D': Iniziale = 3;
                  break;
        case 'E': Iniziale = 4;
                  break;
        case 'F': Iniziale = 5;
                  break;
        case 'G': Iniziale = 6;
                  break;
        case 'H': Iniziale = 7;
                  break;
        case 'I': Iniziale = 8;
                  break;
        case 'L': Iniziale = 9;
                  break;
        case 'M': Iniziale = 10;
                  break;
        case 'N': Iniziale = 11;
                  break;
        case 'O': Iniziale = 12;
                  break;
        case 'P': Iniziale = 13;
                  break;
        case 'Q': Iniziale = 14;
                  break;
        case 'R': Iniziale = 15;
                  break;
        case 'S': Iniziale = 16;
                  break;
        case 'T': Iniziale = 17;
                  break;
        case 'U': Iniziale = 18;
                  break;
        case 'V': Iniziale = 19;
                  break;
        case 'Z': Iniziale = 20;
                  break;
    } 
    flag = Search(Dizionario, Rtemp, 0, MAX, Iniziale);
    printf("%d", flag);

    system("PAUSE");    
    return 0;
}
int Search(par Dictionary[MAX][21], char Request[20], int Min, int Max, int init)
{
    int Median; 
    Median = (Min+Max)/2;

    if(strcmp(Request, Dizionario[Median][Init].world) == 0) 
    return Median;
    else if(Max <= Min) // elemento non trovato
    {
         return -1;
    }

    else if(strcmp(Request, Dictionary[Median][Init].world)>= 1)
    {
         return Search(Dictionary, Request, Median+1, Max, Init);
         printf("ok");
    }else{
         return Search(Dictionary, Request, Min, Median-1, Init);
         printf("ok");
    }
} 

@ john3136 如果我要这样做(Iniziale = Rtemp [0] - 'A'),我可以知道我必须去哪里。 我解释得更好,rwason为什么这个转换是如果我有'A',我知道所有以'A'开头的世界都在posizion [x] [0] 对于B相同,但[x] [1]等等...我不知道我是否说出了我的观点,让我知道.. ^^ 附: 我也有问题&lt ;, ==或&gt;比0至少1 ..

@UliKöhler 他会在函数中崩溃,正如我通过调试所理解的那样,问题出在“strcmp()”调用中 特地在这里

if(strcmp(Request, Dizionario[Median][Init].world) == 0) 

在这里

else if(strcmp(Request, Dictionary[Median][Init].world)>= 1)

@cnicutar 添加了null的控件,它崩溃了 我这样编辑了

if(strcmp(Richiesta, Dizionario[Mediano][Iniziale].Parola) == 0 && Dizionario[Mediano][Iniziale].Parola != NULL) // elemento trovato
if(strcmp(Richiesta, Dizionario[Mediano][Iniziale].Parola)> 0 && Dizionario[Mediano][Iniziale].Parola != NULL)

这些是我现在的2控制......

@BLUEPIXY 我不能使用bsearch,我必须自己使用二进制搜索...

2 个答案:

答案 0 :(得分:1)

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

typedef struct {
    char *Parola;
    char *Significato;
} par;

par *Ricerca(par *Dizionario, char Richiesta[20], int num);

int main(){
   par Dizionario[] = {
        {"Accendere", "Trasmettere energia elettrica a un apparecchio o dispositivo per farlo funzionare"},
        {"Bellezza","Qualita' di cio che e bello"},
        {"Comune","Che e' di tutti, o che appartiene a piu' persone o cose"},
        {"Elenco", "Nota, registro ordinato"},
        {"Impetuoso","Che si muove con impeto [anche in senso figurato]; che si lascia vincere dall'impeto"},
        {"Lancio","Atto, effetto del lanciare o del lanciarsi"},
        {"Produrre","Presentare, allegare, citare"},
        {"Saccone","Grosso sacco, imbottito generalmente di paglia, che si mette sotto il materasso o si usa talvolta in sua vece"},
        {"Verticale","Perpendicolare a un piano orizzontale; che sta ritto con la parte superiore in alto e l'inferiore in basso"},
    };

    char Richiesta[20], Rtemp[20];
    int numOfData = sizeof(Dizionario)/sizeof(*Dizionario);

    par *temp;

    printf("Che parola vuole cercare? :");
    gets (Richiesta);
    strcpy(Rtemp, Richiesta);
    printf("%s\n", Rtemp);
    Rtemp[0] = toupper(Rtemp[0]);
    //printf("%s\n", Rtemp);
    temp = Ricerca(Dizionario, Rtemp, numOfData);
    if(temp != NULL)
        printf("%s\n", temp->Significato);
    else,
        printf("not found\n");

    system("PAUSE");    
    return 0;
}

int cmp(const void *a, const void *b){
    const par *x = a;
    const par *y = b;
    return strcmp(x->Parola, y->Parola);
}

par *Ricerca(par *Dizionario, char Richiesta[20], int num){
    par key = { Richiesta, NULL };
    //replaced by the binary search function that your implements
    return  bsearch(&key, Dizionario, num, sizeof(key), cmp);
}

答案 1 :(得分:0)

经过大量的代码研究,我发现你正在尝试将字典组织成2D数组,这样你就可以从正确的第一个字母开始。不幸的是,这会使您的代码变得更加复杂 - 并且会导致致命的错误。

例如,在行

if(strcmp(Request, Dictionary[Median][init].word) == 0)

您正在访问可能从未初始化的字典元素的元素.word - 事实上,因为每个字母的字母只有一个条目,并且您硬编码MAX,它是一个肯定。所以你发现自己有一个空指针 - 不是一个好的字符串来比较。您必须知道每行数据的长度。要想出来,你的二进制搜索需要从搜索字典的结尾开始。这导致以下(工作)代码:

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

#define MAX 40
typedef struct
{
    char *word;
    char *meaning;
} par;

int Ricerca(par Dizionario[MAX][21], char Richiesta[20], int Min, int Max, int Iniziale, int depth);

int main()
{
   par Dizionario[MAX][21] =
   {
       {
          /////////////////////load my 2d array////////////////////
           //seconda riga
           {"Accendere", "Trasmettere energia elettrica a un apparecchio o dispositivo per farlo funzionare"},
           {"Bellezza","Qualita' di ciò che è bello"},
           {"Comune","Che e' di tutti, o che appartiene a piu' persone o cose"},
           {NULL, NULL},
           {"Elenco", "Nota, registro ordinato"},
           {NULL, NULL},
           {NULL, NULL},
           {NULL, NULL},
           {"Impetuoso","Che si muove con impeto [anche in senso figurato]; che si lascia vincere dall'impeto"},
           {"Lancio","Atto, effetto del lanciare o del lanciarsi"},
           {NULL, NULL},
           {NULL, NULL},
           {NULL, NULL},
           {"Produrre","Presentare, allegare, citare"},
           {NULL, NULL},
           {NULL, NULL},
           {"Saccone","Grosso sacco, imbottito generalmente di paglia, che si mette sotto il materasso o si usa talvolta in sua vece"},
           {NULL, NULL},
           {NULL, NULL},
           {"Verticale","Perpendicolare a un piano orizzontale; che sta ritto con la parte superiore in alto e l'inferiore in basso"},
           {NULL, NULL}
        }
    };


    int i, j, flag, Iniziale = 0;
    par temp;
    char Richiesta[20], Rtemp[20];

    /////////////////////bubble sort/////////////////////
    printf("unsorted array:\n");
    for(j=0; j<21;j++)
    {
      if (Dizionario[0][j].word != NULL) printf("%d: %s\n", j, Dizionario[0][j].word);
      for(i=0; i<MAX && Dizionario[i+1][j].word != NULL; i++)
        {
           if(strcmp(Dizionario[i][j].word, Dizionario[i+1][j].word) < 0)
           {
               temp=Dizionario[i][j];
               Dizionario[i][j] = Dizionario[i+1][j];
               Dizionario[i+1][j] = temp;
           }
        }
    }

//i'm gonna ask to the user what word he want
    printf("Che parola vuole cercare?\n");
    fgets (Richiesta, sizeof(Richiesta)-1, stdin);
    strncpy(Rtemp, Richiesta, strlen(Richiesta)-1); // do not copy newline
    Rtemp[0] = toupper(Rtemp[0]);
    printf("\nLooking for '%s'\n", Rtemp);
//I'm checking what's the first char, if it's a, i'm gonna assign 0 so it's
//it's gonna to the 'n' column and shifting there
// changed from lengthy switch() to more compact array:
    char firstLetter[] = {0,1,2,3,4,5,6,7,8,-1,-1,9,10,11,12,13,14,15,16,17,18,19,-1,-1,-1,20};
    Iniziale = firstLetter[Rtemp[0] - 'A'];
#if 0
    switch(Rtemp[0])
    {
        case 'A': Iniziale = 0;
                  break;
        case 'B': Iniziale = 1;
                  break;
        case 'C': Iniziale = 2;
                  break;
        case 'D': Iniziale = 3;
                  break;
        case 'E': Iniziale = 4;
                  break;
        case 'F': Iniziale = 5;
                  break;
        case 'G': Iniziale = 6;
                  break;
        case 'H': Iniziale = 7;
                  break;
        case 'I': Iniziale = 8;
                  break;
        case 'L': Iniziale = 9;
                  break;
        case 'M': Iniziale = 10;
                  break;
        case 'N': Iniziale = 11;
                  break;
        case 'O': Iniziale = 12;
                  break;
        case 'P': Iniziale = 13;
                  break;
        case 'Q': Iniziale = 14;
                  break;
        case 'R': Iniziale = 15;
                  break;
        case 'S': Iniziale = 16;
                  break;
        case 'T': Iniziale = 17;
                  break;
        case 'U': Iniziale = 18;
                  break;
        case 'V': Iniziale = 19;
                  break;
        case 'Z': Iniziale = 20;
                  break;
    }
#endif
    if (Iniziale == -1) {
      printf("no word with that first letter!\n");
      return 0;
    }
    printf("Iniziale = %d\n", Iniziale);
    flag = Search(Dizionario, Rtemp, 0, MAX, Iniziale, 0);
    printf("result of search was flag = %d\n", flag);

    //system("PAUSE");
    return 0;
}
int Search(par Dictionary[MAX][21], char Request[20], int Min, int Max, int init, int depth)
{
    int Median;
    Median = (Min+Max)/2;
    //printf("calling Search with min =%d, max = %d, median = %d, depth = %d\n", Min, Max, Median, depth);
    depth++;
    if (depth > 10) return 0; // trap an infinite loop - with MAX of 40, binary search should take only 6 iterations
    par *temp;

    if(Max <= Min) // elemento non trovato
    {
         printf("element not found!\n");
         return -1;
    }

    if(Dictionary[Median][init].word==NULL) {
       // out of bounds in the dictionary
       return Search(Dictionary, Request, Min, Median, init, depth);
    }
    if(strcmp(Dictionary[Median][init].word, Request) == 0) {
      printf("Word was found!\nDefinition = %s\n", Dictionary[Median][init].meaning);
      return 1;
    }

    if(strcmp(Request, Dictionary[Median][init].word) > 0 )
    {
         return Search(Dictionary, Request, Median+1, Max, init, depth);
    } else {
         return Search(Dictionary, Request, Min, Median-1, init, depth);
    }
}

我做了很多改变!为了帮助您弄清楚我做了什么,这里是原始代码和最终编译的代码之间的diff。注意 - 我用一对switch ... #if 0语句包围了你的巨大#endif语句;并用数组替换它们。这实际上并没有“破坏”(除了缺少default声明),但仍然非常难看。我相信您知道如何阅读diff - >表示“添加了某些内容”,<表示“删除了某些内容”。

我略微更改了Search的签名,包括depth因素。事实证明,您的分段错误是通过对Search函数的64k递归调用来调用的......在调试期间我添加了此参数以查看早期迭代中发生的情况。

现在看看这是否有意义。

2a3
> #include <string.h>
7,8c8,9
<     char *Parola;
<     char *Significato;
---
>     char *word;
>     char *meaning;
11c12
< int Ricerca(par Dizionario[MAX][21], char Richiesta[20], int Min, int Max, int Iniziale);
---
> int Ricerca(par Dizionario[MAX][21], char Richiesta[20], int Min, int Max, int Iniziale, int depth);
49a51
>     printf("unsorted array:\n");
52c54,55
<         for(i=0; i<MAX && Dizionario[i+1][j].Parola != NULL; i++)
---
>       if (Dizionario[0][j].word != NULL) printf("%d: %s\n", j, Dizionario[0][j].word);
>       for(i=0; i<MAX && Dizionario[i+1][j].word != NULL; i++)
54c57
<            if(strcmp(Dizionario[i][j].Parola, Dizionario[i+1][j].Parola) == 1) 
---
>            if(strcmp(Dizionario[i][j].word, Dizionario[i+1][j].word) < 0) 
61a65
> 
63,66c67,69
<     printf("Che parola vuole cercare?");
<     gets (Richiesta);
<     strcpy(Rtemp, Richiesta);
<     printf("%s", Rtemp);
---
>     printf("Che parola vuole cercare?\n");
>     fgets (Richiesta, sizeof(Richiesta)-1, stdin);
>     strncpy(Rtemp, Richiesta, strlen(Richiesta)-1); // do not copy newline
68c71
<     printf("\n%s", Rtemp);
---
>     printf("\nLooking for '%s'\n", Rtemp);
70a74,77
> // changed from lengthy switch() to more compact array:
>     char firstLetter[] = {0,1,2,3,4,5,6,7,8,-1,-1,9,10,11,12,13,14,15,16,17,18,19,-1,-1,-1,20};
>     Iniziale = firstLetter[Rtemp[0] - 'A'];
> #if 0
116,119c123,132
<     flag = Search(Dizionario, Rtemp, 0, MAX, Iniziale);
<     printf("%d", flag);
< 
<     system("PAUSE");    
---
> #endif
>     if (Iniziale == -1) {
>       printf("no word with that first letter!\n");
>       return 0;
>     }
>     printf("Iniziale = %d\n", Iniziale);
>     flag = Search(Dizionario, Rtemp, 0, MAX, Iniziale, 0);
>     printf("result of search was flag = %d\n", flag);
>     
>     //system("PAUSE");    
122c135
< int Search(par Dictionary[MAX][21], char Request[20], int Min, int Max, int init)
---
> int Search(par Dictionary[MAX][21], char Request[20], int Min, int Max, int init, int depth)
125a139,142
>     //printf("calling Search with min =%d, max = %d, median = %d, depth = %d\n", Min, Max, Median, depth); 
>     depth++;
>     if (depth > 10) return 0; // trap an infinite loop - with MAX of 40, binary search should take only 6 iterations
>     par *temp;
127,129c144
<     if(strcmp(Request, Dizionario[Median][Init].world) == 0) 
<     return Median;
<     else if(Max <= Min) // elemento non trovato
---
>     if(Max <= Min) // elemento non trovato
130a146
>          printf("element not found!\n");
134c150,159
<     else if(strcmp(Request, Dictionary[Median][Init].world)>= 1)
---
>     if(Dictionary[Median][init].word==NULL) {
>        // out of bounds in the dictionary
>        return Search(Dictionary, Request, Min, Median, init, depth);
>     }
>     if(strcmp(Dictionary[Median][init].word, Request) == 0) {
>       printf("Word was found!\nDefinition = %s\n", Dictionary[Median][init].meaning);
>       return 1;
>     }
> 
>     if(strcmp(Request, Dictionary[Median][init].word) > 0 )
136,140c161,163
<          return Search(Dictionary, Request, Median+1, Max, Init);
<          printf("ok");
<     }else{
<          return Search(Dictionary, Request, Min, Median-1, Init);
<          printf("ok");
---
>          return Search(Dictionary, Request, Median+1, Max, init, depth);
>     } else {
>          return Search(Dictionary, Request, Min, Median-1, init, depth);