【问题标题】:Reading data from a file into a structure array (C)将文件中的数据读入结构数组 (C)
【发布时间】:2016-04-18 12:38:10
【问题描述】:

我正在尝试构建一个简单的函数,该函数将接收一个数据文件,并将数据文件中的各种值分配到一个全局结构数组中。但是,我无法让它正常工作。我已经编写了我认为大部分需要的代码,但我的测试行printf("time is %d\n", BP[i].time); 只是读出“时间为 0”。 10 次,让我相信这些值并没有像我想象的那样被分配给结构数组。

我该如何继续?

示例数据文件 (.txt):

0001    553    200
0002    552    100
....    ...   ...

当前代码:

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

// Function Prototype
void readFileBP(char fileName[1000]);

// Definition of BP Structure
struct bloodPressure
{
    int *time;
    int *sys;
    int *dia;
}BP[50]; // end struct BP

int main()
{
    char fileName[1000] = "C:\\Users\\User\\Desktop\\DataFiles\\BP_1.txt";
    readFileBP(fileName);

    int i = 0;

    for (i; i<10; i++)
    {
        printf("Time is %d\n", BP[i].time);
    }
} // end int main()

void readFileBP(char fileName[1000])
{
    FILE *filePtr; // declare file pointer
    int time;
    int sys;
    int dia;
    int position = 0;


    if (filePtr = fopen(fileName, "r") == NULL) // error check opening file
    {
        printf("Opening file failed. Please reenter filename.");
        exit(1); 
    } // end if

    while (fscanf(filePtr, "%d, %d, %d", &time, &sys, &dia) != EOF) // read in BP values
    {
        BP[position].time = time;
        BP[position].sys = sys;
        BP[position].dia = dia;
        position++;

    } // end while

    fclose(filePtr);



} // end void readFile()

【问题讨论】:

  • 现在是学习使用调试器的绝佳机会。逐步检查所有相关变量的代码以查看真正发生了什么! :-)
  • 看这个(filePtr = fopen(fileName, "r") == NULL)两次。这里发生了什么?
  • 作为最小的调试支持,您希望打印出在循环中读取的值inside。有什么被阅读的吗?
  • @alk 感谢您帮助识别违规行。正如你所说,我真的应该读出循环中的值。我是初学者,所以我不理解编译器向我抛出的大部分警告(例如expecting an argument of type int but argument has type int *),但我设法看到错误的东西可能被分配给了filePtr。因此,我将开头移到 if 语句上方的一行。它不太干净,但我认为可以完成相同的工作!

标签: c if-statement struct file-management


【解决方案1】:

编译时启用警告。你应该得到类似的东西:

gsamaras@gsamaras-A15:~$ gcc -Wall -o px px.c
px.c: In function ‘main’:
px.c:22:5: warning: statement with no effect [-Wunused-value]
     for (i; i<10; i++)
     ^
px.c:24:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
         printf("Time is %d\n", BP[i].time);
         ^
px.c: In function ‘readFileBP’:
px.c:37:17: warning: assignment makes pointer from integer without a cast [enabled by default]
     if (filePtr = fopen(fileName, "r") == NULL) // error check opening file
                 ^
px.c:37:5: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
     if (filePtr = fopen(fileName, "r") == NULL) // error check opening file
     ^
px.c:45:27: warning: assignment makes pointer from integer without a cast [enabled by default]
         BP[position].time = time;
                           ^
px.c:46:26: warning: assignment makes pointer from integer without a cast [enabled by default]
         BP[position].sys = sys;
                          ^
px.c:47:26: warning: assignment makes pointer from integer without a cast [enabled by default]
         BP[position].dia = dia;
                          ^
px.c: In function ‘main’:
px.c:26:1: warning: control reaches end of non-void function [-Wreturn-type]
 } // end int main()
 ^

这还不足以让您入门吗?是给我的! :)

【讨论】:

  • 这应该是一条评论,但显然太长了。所以得到一个1+。 ;-)
  • 经验教训:将编译器的警告级别推到最大并修复代码,直到不再发出警告。如果仍有问题,请回到这里...
  • @alk 老实说,我展示了你的 cmets,并认为我应该把它留给你。但后来我想我可以展示编译器对您的评论的看法并将其作为评论发布。原来这是一个相当广泛的问题,所以我认为这应该触发 OP 的调试体验,结合 gdb 以获得最大的乐趣! :)
  • "...为了最大的乐趣!" 很棒的措辞!-)
【解决方案2】:

我做了一些更改并刚刚运行它。

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

// Function Prototype
void readFileBP(char fileName[1000]);

// Definition of BP Structure
struct bloodPressure
{
    int time;
    int sys;
    int dia;
}; // end struct BP
struct bloodPressure BP[50];

int main()
{
    char *fileName = "file.txt";
    readFileBP(fileName);
    int i = 0;
    for (i; i<10; i++)
    {
        printf("Time is %d\n", BP[i].time);
    }
    getch();
}

void readFileBP(char fileName[1000])
{
    FILE *filePtr; // declare file pointer
    int time=0;
    int sys=0;
    int dia=0;
    int position = 0;
    filePtr= fopen(fileName,"r");
    while (fscanf(filePtr, "%d, %d, %d", &time, &sys, &dia) != EOF) // read in BP values
    {
        BP[position].time = time;
        BP[position].sys = sys;
        BP[position].dia = dia;
        position++;

    } // end while

    fclose(filePtr);
} // end void readFile()

现在的输出是:

Time is 1
Time is 553
Time is 200
Time is 2
Time is 552
Time is 100
Time is 0
Time is 0
Time is 0
Time is 0

【讨论】:

  • 您不想通过像这里BP[position].time = (int *)time; 那样盲目地转换来修复警告,只需更正struct bloodPressure 的成员的定义以适应正确的类型。目前它将所有成员定义为指向int 的指针,这是您似乎不想要的。只需通过移除星号使它们成为int,因此int * time 变为int time
  • @alk 当我第一次看到代码时我实际上正在考虑这一点,但后来我认为他们需要它为int * time。但是,感谢您的建议……不要再盲目施法了。
  • @alk 答案现在已编辑为int time 而不是int * time
【解决方案3】:

尝试换行:

while (fscanf(filePtr, "%d, %d, %d", &time, &sys, &dia) != EOF)

while (fscanf(filePtr, "%d%d%d", &time, &sys, &dia) != EOF)

这也是我尝试过的,它似乎根据我所做的测试工作

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

#define MAX_ARRAY_SIZE 50

typedef struct BloodPressure
{
    int time;
    int sys;
    int dia;
}BloodPressure;

BloodPressure bloodPressure[MAX_ARRAY_SIZE];

void ReadFile(char *fileName);

int main(int argc, char *argv[])
{
    char *fileName = "BP_1.txt";

    ReadFile(fileName);

    int i = 0;

    for (i = 0; i < MAX_ARRAY_SIZE; i++)
    {
        printf("Dia is : %d\n", bloodPressure[i].dia);
        printf("Sys is : %d\n", bloodPressure[i].sys);
        printf("Time is : %d\n", bloodPressure[i].time);
        printf("\n");
    }

    exit(EXIT_SUCCESS);
}

void ReadFile(char *fileName)
{
    FILE *filePtr = NULL;
    int  i = 0;

    if ((filePtr = fopen(fileName, "r")) == NULL)
    {
        printf("Error : Unable to open %s for reading\n");
        exit(EXIT_FAILURE);
    }

    while (fscanf(filePtr, "%d%d%d", &bloodPressure[i].dia, &bloodPressure[i].sys, &bloodPressure[i].time) != EOF)
    {
        i++;
    }

    fclose(filePtr);
}

【讨论】:

  • 是的——毕竟我有一个括号错误(在 if 语句中,而不是 while 语句中)。您的代码:if((filePtr = fopen(fileName, "r")) == NULL) 与我的代码:if (filePtr = fopen(fileName, "r") == NULL)
  • 别太担心,我也遇到过几次这样的情况:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 2013-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-11
  • 1970-01-01
相关资源
最近更新 更多