2013-02-15 27 views
1

我试图实现的代码是读取.txt文件并将字符串转换为节点的方法。基本上,当我读取.txt文件时,首先检查非字母(单词不能以数字开头,单词的任何索引中也不能有非字母数字)。一旦找到第一个字母,程序退出循环并进入另一个循环,直到看到一个空格。当我成功发表一个单词时(当发现有空格时,单词“结束”),我将该单词输入到链接列表中。总线错误:10从C中输入文本从.txt文件到节点

当我运行这个,我得到一个总线错误:10.我认为这将是由于单词[b]数组,但是当我malloc它,我仍然得到相同的错误。

预先感谢您!

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

#define TRUE 1 
#define FALSE 0 


struct Node{ 
    char value[100]; 
    int numOccur; 
    int numVariance; 
    struct Node *next; 
}; 

void testprint(struct Node * head){ 
    int data; 
    data = head->value; 
    strcpy(data,head->value); 
    while(head != NULL){ 

     printf("%s\n", data); 
     head = head->next; 
    } 

} 

int main() 
{ 
    struct Node *curr; 
    struct Node *n; 
    struct Node *head =0; 
    struct Node *tail =0; 
    struct Node *next; 
    char word[100]; 
    int a; 
    int x; 



    FILE *file1; 
    file1 = fopen("test1.txt", "r");   //opens text file 

    if(file1 == NULL){ 
     fprintf(stderr,"Error: Could not open file");  //if file1 has error, returns error message 
    exit(1); 
    } 
    a = fgetc(file1); 
    int b = 0; 
    while(a != EOF){ 
     while(!isalpha(a)){ 
      a = fgetc(file1); 
      continue; 
     } 

     n = (struct Node *) malloc(sizeof(struct Node)); 
     while(isalnum(a)){ 
      while(a != ' ' && a != EOF){ 
       word[b] = a; 
       a = fgetc(file1); 
       b++; 
      } 
      word[b] = '\0'; 
     } 
     n->next = 0; 
     if(head == 0){ 
      head = n; 
      tail = n; 
     } 
     else{ 
      tail->next = n; 
      tail = n; 
     } 
    } 
    testprint(head); 
    fclose(file1); 
} 
+1

你的代码甚至没有编译。有很多错误。当期望Node *时,您可以使用FILE *调用testprint()。此外,当您执行word [b] =(char *)malloc(sizeof(char)* 30)时,数据类型不匹配。您正在分配一个动态字符数组(lhs)并将其分配给char(rhs)。 – Barney 2013-02-15 04:25:26

+0

在这段代码中错误的东西中,'/ 0'不是终止的空字符; '\ 0'是。事实上,为了避免*再次出现问题,请不要使用* *。改用'0'。另外,当你到达你的第一个单词时,你的意图是分配一个新的30字符缓冲区*为永远的字符*?似乎有点矫枉过正,不是吗?特别是考虑到你将配置保存在一个无效的内存区域(类型错误)并且在过程中像筛子一样泄漏。把这个[codereview.stackexchange.com](http://codereview.stackexchange.com)并修复* real *问题。 – WhozCraig 2013-02-15 04:28:31

回答

3

您应该注意编译器的警告。 (最好总是用-Wall -Wextra进行编译以获得更多警告。)

正如Barney Hsiao指出的,testprint()是用FILE指针调用的,而不是节点指针。


无关,但如果你需要真正常量,有一个标准的头文件,它会给你这些(小写,即truefalse)。

#include <stdbool.h> 

我编译此代码时,遇到下列编译器警告:

$ CFLAGS="-Wall -Wextra" make bus10 
cc -Wall -Wextra bus10.c -o bus10 
bus10.c: In function ‘testprint’: 
bus10.c:20:14: warning: assignment from incompatible pointer type 
bus10.c: In function ‘main’: 
bus10.c:48:8: warning: array subscript has type ‘char’ 
bus10.c:54:8: warning: array subscript has type ‘char’ 
bus10.c:68:23: warning: assignment from incompatible pointer type 
bus10.c:34:8: warning: unused variable ‘x’ 
bus10.c:31:17: warning: unused variable ‘next’ 
bus10.c:27:17: warning: unused variable ‘curr’ 
bus10.c:74:1: warning: control reaches end of non-void function 

现在,其中的一些人比其他人更严重。 “数组下标具有类型'char'”对我来说听起来不是一个问题(说实话,我不知道它甚至意味着什么)。 “未使用的变量”意味着:你已经创建(声明)了一个变量,然后你永远不会使用它。 “控制到达非空函数结束”意味着你有一个被声明为返回一个值的函数,但是代码在没有返回语句的情况下脱离底部。

但是“从不兼容的指针类型分配”是不好的。单词不兼容是不好的。 20行显示:68

 head = head->next; 

行写着:

 tail->next = n; 

这是因为

struct Node{ 
    ... 
    struct node *next; 
}; 

看到了吗? *next不是struct Node而是struct node。大写/小写计数。


好的。这是一个很大的问题。编译器也没有说什么。那么,公平就是这样。但我们不知道这意味着什么。第33行:

char a; 

你说什么错?这是一个拥有角色的类型,对吧?问题在这里:

a = fgetc(file1); 

你看到它吗?这里怎么样?

while(a != EOF){ 

EOF是一个哨兵值过大,可安装在char。这应该是这样的。为了使fgetc函数告诉你文件结束条件已经发生,而不是文件中的另一个字节,它必须返回一个超出char范围的值(0..255无符号,-128..127有符号)。 while条件将永远不会失败,因为没有char值可以比较等于EOF。

所以声明aint而不是char

+0

冰山一角。 – WhozCraig 2013-02-15 04:33:59

+0

同意。但是,首先*首先*。 – 2013-02-15 04:35:14

+1

那么在这种情况下,'struct node * next;',然后是'int a'而不是'char a',最多在while循环中,while(a!=''){'不测试EOF所以它超过了字符缓冲区与EOF(这就是总线错误,顺便说一句)。等。 – WhozCraig 2013-02-15 04:36:18