2013-12-13 110 views
0

該程序基於鏈接列表。讀取一個字符串,提取所有由換行符分隔的子字符串。當找到換行符時,讀取一個字符串並將每個字符串存儲在數組中

輸入應該是:

hello world\ngood bye\nWhat a nice day!\n\0 

然後,預期輸出應該是:

[hello world]->[good bye]->[What a nice day]-> 

但是,當我運行該程序,然後鍵入:

hello world\ngood bye\nWhat a nice day!\n\0 

我的輸出:

[hello world\ngood bye\nWhat a nice day!\n\0]-> 

我嘗試將NULL字符分別讀作'\'和'n',但無法處理它。我怎樣才能修復它,打印出預期的輸出?


newTB(char text []); //函數說明

函數newTB分配一個新的文本緩衝區,並用數組中給出的文本初始化它的內容。輸入數組中的行全部以'\ n'結尾。整個文本以'\ 0'結尾。


char * dumpTB(TB tb);

以下函數不會改變它們的文本緩衝參數。分配並返回包含給定文本緩衝區中文本的數組。文本緩衝區中的每一行都需要以'\ n'結尾(這包括最後一行)。整個文本必須以'\ 0'結尾。調用者有責任釋放由返回數組佔用的內存。如果文本緩衝區中沒有行,則返回NULL。


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

typedef struct textbuffer *TB; 

typedef struct textbuffer { 
    char *texts; 
    TB next; 
} textbuffer; 

char *dumpTB (TB tb) {       // my version of dumpTB 
    TB temp = malloc(sizeof(struct textbuffer)); 
    temp->texts = tb->texts; 
    temp->next = NULL; 

    return (temp->texts); 
}   

TB newTB (char text[]){        // get the array from main function 
    TB newText = malloc(sizeof(struct textbuffer)); // return the node 
    newText->texts = text; 
    //strcpy(newText->texts,text); 
    newText->next = NULL; 
    return (newText); 
} 
void printList(TB tb){     //print entire list 
    TB curr = tb; 
    while(curr != NULL){ 
     printf("[%s]-> ",curr->texts); 
     curr = curr->next; 
    } 
    printf("\n"); 
} 

int main(int argc, char * argv[]) { 
    int i=0; 
    int j=0; 
    char str[MAX_TEXT]; 
    char cpy[MAX_TEXT]; 
    char tmp[MAX_TEXT]; 
    TB textList = NULL; 
    TB list = NULL; 
    list = textList; 

    fgets(str, MAX_TEXT, stdin);   // input should be like 
              // hello\nworld\ngood\nbye\n\0 
    while(str[i] != '\0') { 
     if(str[i] == '\n') { 
      cpy[i] = '\0'; 
      strcpy(tmp,cpy); 
      textList = newTB(tmp); 
      list = textList; 
      textList->texts = dumpTB(textList); 
      //TB newList = malloc(sizeof(struct textbuffer)); 
      //list = textList; 
      // newList->texts = textList->texts; 
      textList = textList->next; 
      j=0; 
     } 
     cpy[j++] = str[i++]; 
    } 
    printList(list); 

    return 0; 
} 
+1

你想'CPY [J] = '\ 0'' – chux

+1

'' \ n''是一個換行符,而你輸入兩個字符,一個反斜線\和字母 'N',那麼你的比賽從未成功。即使你輸入了真正的換行符,你的程序也不會做你想要的,因爲'fgets'將停止在第一個換行符處讀取,產生「hello」。 – codnodder

+0

我嘗試了兩個,但仍然無法正常工作..所以我應該改變哪一部分? –

回答

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

#define MAX_TEXT 256 

typedef struct textbuffer *TB; 

typedef struct textbuffer { 
    char *texts; 
    TB next; 
} textbuffer; 

TB newTB (char text[]){ 
    TB newText = malloc(sizeof(struct textbuffer)); 
    newText->texts = strdup(text); 
    newText->next = NULL; 
    return newText; 
} 
void printList(TB tb){ 
    TB curr = tb; 
    while(curr != NULL){ 
     printf("[%s]-> ",curr->texts); 
     curr = curr->next; 
    } 
    printf("\n"); 
} 

int main(int argc, char * argv[]) { 
    int i=0; 
    int j=0; 
    char str[MAX_TEXT]; 
    char cpy[MAX_TEXT]; 
// char tmp[MAX_TEXT]; 
    TB list = NULL; 
    TB textlist = NULL; 

    fgets(str, MAX_TEXT, stdin);//E.g. hello\nworld\ngood\nbye\n\0 -> "hello\\nworld\\ngood\\nbye\\n\\0\n" 

    while(str[i] != '\n' && str[i] != '\0') { 
     if(str[i] == '\\'){ 
      if(str[i+1] == 'n') { 
       cpy[j] = '\0'; 
       //strcpy(tmp,cpy); 
       TB newList = newTB(cpy); 
       if(textlist == NULL) 
        textlist = newList; 
       else { 
        textlist->next = newList; 
        textlist = textlist->next; 
       } 
       if(list == NULL) 
        list = newList; 
       j=0; 
       i += 2; 
      } else if(str[i+1] == '0') { 
       break; 
      } 
     } 
     cpy[j++] = str[i++]; 
    } 
    printList(list); 
    //deallocate 
    return 0; 
} 
+0

哇..它似乎正常工作。 :)順便說一下,newTB函數中的strdup()是什麼? –

+0

newText-> texts = strdup(text);所以是一樣的,newText-> texts =(char *)malloc((strlen(text)+1)* sizeof(char));那麼newText-> texts = text; ?? –

+0

@BrianSon newText-> texts = strdup(text);所以是一樣的,newText-> texts =(char *)malloc((strlen(text)+1)* sizeof(char));然後strcpy(newText-> texts,text); – BLUEPIXY

0

我改變了你這樣的主要功能:

int main(int argc, char * argv[]) { 
    int i=0; 
    int j=0; 
    char str[MAX_TEXT]; 
    char cpy[MAX_TEXT]; 
    //char tmp[MAX_TEXT]; 
    char* tmp = cpy; 
    TB textList = NULL; 
    TB list = NULL; 
    TB newList = NULL; 
    //list = textList; 

    //fgets(str, MAX_TEXT, stdin);   // input should be like 
              // hello\nworld\ngood\nbye\n\0 
    strcpy(str, "hello\nworld\ngood\nbye\n"); 

    // ... or use a file instead of the line above: 
    /* 
    FILE* f = NULL; 
    *str = '\0'; 
    f = fopen("Sample.txt", "r"); 
    if (!f) 
     return -1; 
    (void)fread(str, MAX_TEXT, 1, f); 
    fclose(f); 
    */ 

    while(str[i] != '\0') { 
     if(str[i] == '\n') { 
      //cpy[i] = '\0'; 
      //strcpy(tmp,cpy); 
      //textList = newTB(tmp); 
      //TB newList = malloc(sizeof(struct textbuffer)); 
      //list = textList; 
      //newList->texts = textList->texts; 
      //textList = textList->next; 
      //j=0; 

      cpy[j] = '\0'; 
      newList = newTB(tmp); 
      if (textList) { 
       textList->next = newList; 
       textList = newList; 
      } 
      else 
       list = textList = newList; 

      tmp = &cpy[j+1]; 
     } 
     else 
     cpy[j] = str[i]; 

     j++; 
     i++; 
    } 
    cpy[j] = '\0'; 
    printList(list); 

    // cleanup 
    for (textList=list;NULL != textList;) { 
     list = textList; 
     textList = textList->next; 
     free(list); 
    } 

    return 0; 
} 

cpy是原始字符串機智的副本h將換行符('\ n')替換爲換行符('\ 0'),tmp指向cpy中的最後一個令牌。 list是您的列表的頭,textList被用作列表的隊列(新元素的插入點)。此外,我將fgets替換爲strcpy,因爲您無法使用fgets獲取多個文本行,或者可以使用文件替代更多文本。

我試着儘可能保留原始代碼。

+0

也許'newList = newTB(cpy);'? – chux

+0

@chux不,tmp始終指向cpy內部。 – Liviu

+0

看起來不錯! :)但是,應該有一些東西可以讓我輸入..後來,我應該輸入相當長的文本文件,並且每個節點都應該包含一個由換行符分隔的字符串。 –

相關問題