2016-01-29 56 views
0

我真的用C新手,我想創建一個程序,讀取其中兩個是隻包含字符串輸入文件。我已經創建了它的相關文件的字符串。我已經處理了一些問題,但我無法弄清楚,那裏有一些分段錯誤。 (由-UA問)閱讀串

這裏是我的代碼:

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

typedef struct linked_list { 
    char my_data[256]; 
    struct linked_list *next_it; 
} node_t; 

int main(int argc, char *argv[]) { 
    /* 
    if(argc != 4) { 
     fprintf(stderr, "Requiring 2 input 1 output file name to start!\n"); 
     exit(EXIT_FAILURE); 
    }*/ 

    FILE *my_s; 
    FILE *my_f; 
    // FILE *my_o; 
    bool mybool = true; 
    int my_ch; // our char to read 
    char my_buffer[256]; 
    bool check_all = true; 

    node_t *set_a = malloc(sizeof(node_t)); 
    node_t *set_b = malloc(sizeof(node_t)); 
    my_f = fopen(argv[1], "r"); // first textfile to read 
    my_s = fopen(argv[2], "r"); // second textfile to read 

    if (my_f != NULL && my_s != NULL) { 
     while (fgetc(my_f) != EOF && mybool != false && check_all != false) { 
      my_ch = fgetc(my_f); 
      int i = 0; 
      while (my_ch >= 0) { 
       my_buffer[i++] = my_ch; 
       my_ch = fgetc(my_f); 
      } 
      strcpy(set_a->my_data, my_buffer); 
      if (feof(my_f)) { 
       mybool = false; 
      } else { 
       set_a->next_it = malloc(sizeof(node_t)); 
       set_a = set_a->next_it; 
      } 
     } 
     mybool = false; 
     printf("First File Copy Done!\n"); 
     while (fgetc(my_s) != EOF && mybool != true && check_all != false) { 
      my_ch = fgetc(my_s); 
      int i = 0; 
      while (my_ch >= 0) { 
       my_buffer[i++] = my_ch; 
       my_ch = fgetc(my_s); 
      } 
      strcpy(set_b->my_data, my_buffer); 
      if (feof(my_s)) { 
       check_all = false; 
      } else { 
       set_b->next_it = malloc(sizeof(node_t)); 
       set_b = set_b->next_it; 
      } 
     } 
     printf("Second File Copy Done!\n"); 
    } else { 
     fprintf(stderr, "Cannot read from %s and %s\n", argv[1], argv[2]); 
    } 

    while (set_a != NULL) { 
     int j = 0; 
     printf("No: %d, Var: %s",j++, set_a->my_data); 
     node_t *set_c = set_a; 
     set_a = set_a->next_it; 
     free(set_c); 
    } 
    while (set_b != NULL) { 
     int j = 0; 
     printf("No: %d, Var: %s",j++, set_b->my_data); 
     node_t *set_c = set_b; 
     set_b = set_b->next_it; 
     free(set_c); 
    } 
    return 0; 
} 
+1

你的代碼沒有縮進。學習縮進代碼並使用空格使代碼可讀。研究我重新格式化的方式,並在鍵入時執行此操作,這將幫助您避免許多愚蠢的錯誤。 – chqrlie

回答

0

你的代碼中有幾個問題:

  • 您未初始化的第一個節點初始化列表。沒有辦法測試這個節點中的任何東西......爲什麼不初始化一個空列表爲NULL
  • 您測試通過讀取每個文件的下一個字節的文件的末尾,但你沒有保存該字節...所以它會丟失。稍後,您檢查feof(my_s),但此功能不會做你認爲它的作用。檢查的好處是fgetc()返回EOF,但存儲它讀取的字節。
  • 你爲什麼用mymy_,這是沒有幫助啓動每個局部變量的名稱,只是用短名稱,他們不應該反正指定任何全球性的。
  • 您不保留指向每個列表頭部的指針,您將set_aset_b設置爲指向下一個節點,則無法再找到列表的頭部。
  • 您在打印和免費循環的每個迭代復位j0,所有節點都將與數0打印。
  • 您應該使用功能加載,打印和免費名單,以避免重複相同的代碼兩次。

這裏是一個改進版本:

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

typedef struct linked_list { 
    char *data; 
    struct linked_list *next; 
} node_t; 

node_t *load_lines(const char *filename) { 
    node_t *head = NULL; 
    FILE *fp = fopen(filename, "r"); 
    if (fp != NULL) { 
     char buffer[256]; 
     size_t i = 0; 
     int c; 
     node_t **tailp = &head; 

     for (;;) { 
      c = fgetc(fp); 
      if (c != EOF && c != '\n') { 
       if (i < sizeof(buffer) - 1) { 
        buffer[i++] = c; 
       } 
       continue; 
      } 
      if (i > 0) { 
       buffer[i] = '\0'; 
       /* allocate a new node */ 
       *tailp = malloc(sizeof(**tailp)); 
       (*tailp)->next = NULL; 
       (*tailp)->data = strdup(buffer); 
       tailp = &(*tailp)->next; 
       i = 0; 
      } 
      if (c == EOF) { 
       break; 
      } 
     } 
     fclose(fp); 
    } 
    return head; 
} 

void print_word(node_t *np) { 
    int j = 0; 
    while (np != NULL) { 
     printf("No: %d, Var: %s", j++, np->data); 
     np = np->next; 
    } 
} 

void free_words(node_t *np) { 
    while (np != NULL) { 
     node_t *next = np->next; 
     free(np->data); 
     free(np); 
     np = next; 
    } 
} 

int main(int argc, char *argv[]) { 
    /* 
    if (argc != 4) { 
     fprintf(stderr, "Requiring 2 input 1 output file name to start!\n"); 
     exit(EXIT_FAILURE); 
    }*/ 

    node_t *set_a, *set_b; 

    if ((set_a = load_words(argv[1])) != NULL) { 
     printf("First File Copy Done!\n"); 
    } 
    if ((set_b = load_words(argv[2])) != NULL) { 
     printf("Second File Copy Done!\n"); 
    } 
    if (!set_a && !set_b) { 
     fprintf(stderr, "Cannot read from %s and %s\n", argv[1], argv[2]); 
    } 

    print_words(set_a); 
    free_words(set_a); 
    print_words(set_b); 
    free_words(set_b); 
    return 0; 
} 
+0

非常感謝,先生。我也覆蓋了你的筆記。最好,-ua –

+0

實際上,這個工作非常好,但是從我自己的示例輸入文件中,代碼不輸出字符串的最後一行。 (即打印出25箇中的24個,沒有最後一行)。我認爲字符串的最後一行不在我們的鏈表中,因爲在print_word部分,它在到達NULL變量後終止 –

+0

上面的代碼假定文件以換行結束。如果文件的最後一行沒有最終的'\ n',則不會將其添加到鏈接列表中。我將修改代碼來處理這種情況,但最好是所有文本文件都有最終換行符。 – chqrlie

0

你沒有達到文件結束後,指着兩個鏈表到「NULL」的尾巴,你是不是永葆頭的每個鏈接列表。每次讀取字符串時都要更改頭部。因此,在最後階段「SET_A」和「set_b」成爲最後一個節點不包括NULL尾