2014-04-28 70 views
0

工作的地方我試圖讓程序運行,基本上需要輸入字符串,並通過一些代碼發送它,並按字母順序使用鏈接列表。我已經想出瞭如何使用手動(在實際代碼中)文本輸入來完成這項工作,但是當我嘗試從用戶那裏獲取輸入時,我無法使其工作。無法從用戶輸入代碼輸入代碼

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

struct llist { 
    char *value; 
    struct llist *next; 
}; 

int compare (struct llist *one , struct llist *two) 
{ 
return strcmp(one->value, two->value); 
} 

void add(struct llist **pp, char *value, int (*cmp)(struct llist *l, struct llist *r)) { 

    struct llist *new; 
    new = malloc(sizeof(*new)); 
    new->value = value; 

    for (; *pp != NULL; pp = &(*pp)->next) { 
     if (cmp(*pp, new) > 0) break; 
     } 

    new->next = *pp; 
    *pp = new; 
} 

void display(struct llist *ptr) { 

    for (; ptr != NULL; ptr = ptr->next) { 
     printf("%s\n", ptr->value); 
    } 
} 

int main(void) { 
    struct llist *root = NULL; 
    char string; 

    printf("Please enter a string to be sorted alphabetically and displayed with a character count: "); 
    string = getchar(); 

    while (string != 10){ 
    add(&root,&string, compare); 
    string = getchar(); 

    } 

    display(root); 

    return 0; 
} 

尋找在主函數中,我相當肯定它有事情做在使用getchar和事實,即它作爲整數讀取字符,但我無法弄清楚如何解決這個問題,輸出只是一堆空行。但是當while循環被刪除並且字符串像下面的main一樣輸入時,它工作正常嗎?爲什麼這樣呢?現在

int main(void) { 
    struct llist *root = NULL; 
    char string; 

    printf("Please enter a string to be sorted alphabetically and displayed with a character count: "); 

    add(&root,"t", compare); 
    add(&root,"h", compare); 
    add(&root,"i", compare); 
    add(&root,"s", compare); 
    add(&root,"m", compare); 
    add(&root,"y", compare); 
    add(&root,"t", compare); 
    add(&root,"e", compare); 
    add(&root,"x", compare); 
    add(&root,"t", compare); 

    display(root); 

    return 0; 
} 

輸出 Ë ^ h 我 米 小號 牛逼 牛逼 牛逼 X Ÿ

這是正確的, 誰能幫助我?

+0

注意:爲什麼用'string!= 10'而不是'string!='\ n''? – chux

+0

我原來使用的是,我不知道爲什麼我改變了它,但我把它切換回來,因爲它確實更有意義 – scarlso9

+0

代碼是通過需要字符串的'strcmp()'進行「比較」。字段'value'是'&string'的副本,指向'char'的指針,但沒有''\ 0''終止符。 – chux

回答

1

當您在示例中編寫"t"時,您將獲得數組的地址。該地址與您傳遞給add的每個值不同。但是,字符串的地址不會改變,並且您每次撥打add時都將new->value設置爲相同的值。而不是new->value = value,請嘗試new->value = *value(以及所有相關的必要更改)。

沒有太多需要的更改。請注意,在單個字符串輸入後終止並不是很好的行爲。一個很好的練習就是編寫一個析構函數,在第一行之後撕下字符串,然後對下一行進行排序。另一個很好的練習是對參數進行排序,如果沒有參數給出,則讀取stdin。

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

struct llist { 
     char value; /* CHANGE */ 
     struct llist *next; 
}; 


typedef int (*compar)(struct llist *one , struct llist *two); 


int 
compare(struct llist *one , struct llist *two) 
{ 
     return tolower(one->value) > tolower(two->value); /* CHANGE */ 
} 


void * 
xmalloc(size_t s) 
{ 
     void *v = malloc(s); 
     if(v == NULL) { 
       perror("malloc"); 
       exit(EXIT_FAILURE); 
     } 
     return v; 
} 


void 
add(struct llist **pp, char value, compar cmp) /* CHANGE */ 
{ 

     struct llist *new; 
     new = xmalloc(sizeof *new); /* Check for errors */ 
     new->value = value; /* CHANGE the type of value above */ 

     for(; *pp != NULL; pp = &(*pp)->next) { 
       if(cmp(*pp, new) > 0) 
         break; 
     } 

     new->next = *pp; 
     *pp = new; 
} 

void 
display(struct llist *ptr) 
{ 
     for(; ptr != NULL; ptr = ptr->next) { 
       putchar(ptr->value); /* CHANGE */ 
     } 
     putchar('\n'); 
} 

int 
main(void) 
{ 
     struct llist *root = NULL; 
     char string; 

     while((string = getchar()) != '\n') { /* Optional CHANGE (1) */ 
       add(&root,string, compare); 
     } 

     display(root); 
     return 0; 
} 

/* 
* (1) Using "'\n'" instead of 10 is necessary for readability, 
* portability, and sanity of future maintainers. 
* 
* Writing getchar() only once is cleaner. 
*/ 
+0

我不知道我是否跟着你,我不應該看到相同的字符打印出來,但只是如果是這種情況,請重複我的字符串中的其他字符的位置? – scarlso9

+0

不可以。您正在將字符的地址傳遞給strcmp,該字符需要一個字符串(一個以null結尾的char數組),所以您有u.b. –

0

與您的硬編碼的入口代碼要傳遞的字符串對add而在用戶輸入的代碼,你只傳遞一個指向一個字符。 A char*不一定是C中的字符串,它可能指向一個字符串,但它不必。

在C中,一個字符串是以零結尾的字符緩衝區,字符爲'\0'(通常只是值0)。當你使用getchar時,你正在傳遞一個指向一個字符的指針 - 並且該字符後面沒有空零,所以它不是有效的C字符串。

如果您想保留使用getchar的代碼,您需要使用一個緩衝區,該緩衝區將在該字符後面存儲空零。你可以將一小陣如下:

int main(void) { 
    struct llist *root = NULL; 
    char string[2]; 

    string[1] = '\0'; // Ensure that we have a null terminated string 

    printf("Please enter a string to be sorted alphabetically and displayed with a character count: "); 
    string[0] = getchar(); 

    while (string != '\n'){ 
    add(&root,string, compare); 
    string[0] = getchar(); 

    } 

    display(root); 

    return 0; 
} 
+0

好吧我明白你在說什麼,但現在字符串將是一個字符指針,我將它與'while(string!='\ n')'中的整數值進行比較,所以我將它改爲'while字符串[0]!='\ n')'並編譯它,但仍然遇到了空白區域只有相同的錯誤。 – scarlso9

0

清理的幾件事情

1)作爲@ shf301西亞德,需要不只是一個指針傳遞一個字符串,以一個單一的char

2)需要創建字符串的副本 - 通知strdup

3)雖然循環應該在'\nEO以及也許'\0中斷。 getchar()返回int原因爲:EOF0UCHAR_MAX(例如255)。

4)應該在free()資源末端 - 未顯示。

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

// In case you library does not have strdup() ... 
char *strdup(const char *s) { 
    if (s == NULL) return NULL; 
    size_t siz = strlen(s) + 1; 
    char *y = malloc(siz); 
    if (y != NULL) { 
    memcpy(y, s, siz); 
    } 
    return y; 
} 

struct llist { 
    char *value; 
    struct llist *next; 
}; 

int compare(struct llist *one, struct llist *two) { 
    return strcmp(one->value, two->value); 
} 

void add(struct llist **pp, char *value, 
     int(*cmp)(struct llist *l, struct llist *r)) { 

    struct llist *new; 
    new = malloc(sizeof(*new)); 
    new->value = strdup(value); 

    for (; *pp != NULL; pp = &(*pp)->next) { 
    if (cmp(*pp, new) > 0) 
     break; 
    } 

    new->next = *pp; 
    *pp = new; 
} 

void display(const struct llist *ptr) { 

    for (; ptr != NULL; ptr = ptr->next) { 
    printf("%s\n", ptr->value); 
    } 
} 

int main(void) { 
    struct llist *root = NULL; 
    char string[2]; 
    string[1] = '\0'; 

    printf("Please enter a string to be sorted alphabetically" 
      " and displayed with a character count: "); 

    int ch; 
    while ((ch = getchar()) != EOF && ch != '\n' && ch != '\0') { 
    string[0] = ch; 
    add(&root, string, compare); 
    } 

    display(root); 

    return 0; 
} 
+0

聖莫爾它工作....所有這一切都歸結爲stdup?我現在從未聽說過它。你用ch做的事情是有道理的,我從來沒想過要把它變成一個整數,這是有道理的,我猜。非常感謝你Chux! – scarlso9

+0

經過一段時間(幾分鐘到幾天)後,如果答案能很好地滿足您的需求,請接受它。一旦你獲得15+分,一定要對任何幫助你的答案進行投票。 – chux