在c中读取文件

时间:2018-05-07 13:21:59

标签: c

我试图从C中的文件中读取数据,并使用空格作为分隔符将数据提供到结构的5个不同字段中。我列出了70多个不同的患者,每个患者的格式都是这样,

Mark Cruz 5627 193.0 3.0

Joseph Feminella 4328 194.0 3.5

Eriverto Lopez 7899 195.0 7.9

Austin Duarte 3056 196.0 12.4

Jacob England 1453 197.0 6.7

每条线之间没有新线,它们都在接着另一条线上。当我运行这个程序时,它似乎每次都在文件的中间开始,打印一个')'之前'名字:'每次,并以每个领域都有零的患者结束。

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

typedef struct node{
    char pln[30];
    char pfn[20];
    int pid;
    float pwt;
    float phgnum;
    struct node* next;
    struct node* back;
}node;

int main(){

    FILE *fp;
    char c;
    node* newptr;
     fp = fopen("info.txt","r");

    if(fp == NULL){
        printf("ERROR File Doesn't exist\n");
    }

    while(c != EOF){

        newptr = (node*)malloc(sizeof(node));
        newptr->back = NULL;
        newptr->next = NULL;
        newptr->phgnum = 0;
        newptr->pid = 0;
        newptr->pwt = 0;
        fscanf(fp,"%s %s %i %f %f",newptr->pfn,newptr->pln,&newptr->pid,&newptr->pwt,&newptr->phgnum);
        c = getc(fp);
        printf("First Name: %s\n",newptr->pfn);
        printf("Last Name: %s\n",newptr->pln);
        printf("PID: %i\n",newptr->pid);
        printf("Weight: %f\n",newptr->pwt);
        printf("HG1AC: %f\n",newptr->phgnum);

        printf("\n\n\n)");
    }
}

2 个答案:

答案 0 :(得分:4)

额外的paren来自printf本身。

    printf("\n\n\n)");
                  ^ right here!  :)

另外,如评论中所述:您有一个未初始化的变量:

$ clang -Wall rfic.c 
rfic.c:18:8: warning: variable 'c' is used uninitialized whenever function 'main' is called
      [-Wsometimes-uninitialized]
  char c;
  ~~~~~^
rfic.c:26:10: note: uninitialized use occurs here
  while (c != EOF) {
         ^
rfic.c:18:9: note: initialize the variable 'c' to silence this warning
  char c;
        ^
         = '\0'
1 warning generated.

你也有内存泄漏。 newptr被赋予分配的结果,并且该循环的每次迭代都会覆盖此指针。

答案 1 :(得分:3)

这里有很多问题。

  • 您始终为每一行分配一个新节点,并立即泄漏指针:这就是所谓的内存泄漏。您是否想使用双向链表,node假设您应该:

    • 保留指向第一个和最后一个节点的指针
    • 始终如一地管理这些指针以及每个节点的nextback成员
  • while (c != EOF)是完全错误的(对于您当前的问题而言)。首先,是SO中的常见问题:Why is “while ( !feof (file) )” always wrong?,所以你应该避免这种模式。即使在你的情况下,你在每行之后读取了一个额外的字符,最后一行可能会以行尾结束,因此fgetc将成功返回'\n',而下一个scanf将失败。由于您未测试其返回值,因此您将处理未指定的值。此外,如果您应使用fgetc来区分EOF和任何可能的char,则可以将int的返回值存储在char中。坚持正常模式:

    for(;;) {         // infinite loop
        ...
        if (5 != fscanf(...)) {
            // process error
            ...
            break;    // exit loop
        }
    }
    
  • 按照Brian Cain的说明打印额外的paren

    printf("\n\n\n)");
                  ^