【发布时间】:2020-06-26 21:24:32
【问题描述】:
我正在尝试让一个程序逐行解析文本文件以进行一些数据存储(我尝试过二进制文件存储,但文件中的混合数据类型似乎会搞砸)。
我正在尝试保存 hist[] 中包含的一些条目,它是 history 结构的数组,它基本上包含一个浮点数 (.value) 和一个 time_t (.event_Time)。在保存这些条目之前,应该保存条目的数量(当前是一个 int)。
到目前为止,我可以使用以下函数很好地编写文件:
void data_save(int node_Id, int sensor_Id, history *hist, int entries){
FILE *file;
char data_Dir[FILENAME_MAX] = "";
char directory[FILENAME_MAX] = "";
char fileName[FILENAME_MAX] = "";
int length = 0;
//define path of the file
_getcwd(data_Dir, FILENAME_MAX);
strcat(data_Dir, "\\Data");
strcat(directory,"\\Node_");
length = snprintf(NULL, 0,"%d",node_Id);
char str1[length];
sprintf(str1, "%d", node_Id);
strcat(directory,str1);
strcat(fileName,"\\Sensor_");
length = snprintf(NULL, 0,"%d",sensor_Id);
char str2[length];
sprintf(str2, "%d", sensor_Id);
strcat(fileName,str2);
strcat(fileName,".txt");
printf("%s\n", directory);
printf("%s\n", fileName);
//check if the Data directory exists, create it if not
if (directory_exists(data_Dir) == false) {
printf("Making directory\n");
_mkdir(data_Dir);
}
strcat(data_Dir, directory);
//check if the Node directory exists, create it if not
if (directory_exists(data_Dir) == false) {
printf("Making directory\n");
_mkdir(data_Dir);
}
strcat(data_Dir, fileName);
printf("%s\n", data_Dir);
//open the file
file = fopen(data_Dir, "w");
if(file == NULL){
printf("Error while opening file.\n");
exit (1);
}
//Save the number of entries
printf("Saving %d entries\n", entries);
fprintf(file, "%d\n", entries);
//Save each entry in the inverse chronological order
//(ie. latest event first)
for(int i=entries-1; i > -1; i--){
fprintf(file, "%f %ld\n", hist[i].value, hist[i].event_Time);
}
fclose(file);
free(data_Dir);
free(directory);
free(fileName);
printf("Node %d, sensor %d: Data saved Successfully (%d Entries)\n", node_Id, sensor_Id, entries);
return;
}
但是,我在尝试使用以下函数加载刚刚创建的文件时遇到问题:
history * data_load(int node_Id, int sensor_Id, int *entries){
FILE *file;
char data_Dir[FILENAME_MAX] = "";
char directory[FILENAME_MAX] = "";
char fileName[FILENAME_MAX] = "";
int length = 0;
int entries_Temp;
int maxChar = 1000;
char stream[maxChar];
//define path of the file
_getcwd(data_Dir, FILENAME_MAX);
strcat(data_Dir, "\\Data");
strcat(directory,"\\Node_");
length = snprintf(NULL, 0,"%d",node_Id);
char str1[length];
sprintf(str1, "%d", node_Id);
strcat(directory,str1);
strcat(fileName,"\\Sensor_");
length = snprintf(NULL, 0,"%d",sensor_Id);
char str2[length];
sprintf(str2, "%d", sensor_Id);
strcat(fileName,str2);
//check if the Data directory exists, exit if not
if (directory_exists(data_Dir) == false) {
printf("//Data does not exist\n");
*entries = 0;
return NULL;
}
strcat(data_Dir, directory);
//check if the Node directory exists, exit if not
if (directory_exists(data_Dir) == false) {
printf("//Data//Node%d does not exist\n", node_Id);
*entries = 0;
return NULL;
}
strcat(data_Dir, fileName);
printf("%s\n", data_Dir);
//check if file exists (ie. there has been no previous
//data for the given sensor) exit and return 0
//existing entries
file = fopen(data_Dir, "r");
if(file!=NULL){
printf("No file found for given sensor\n");
*entries = 0;
return NULL;
}
//Read the number of entries in the file
printf("Reading number of entries\n");
printf("%s", fgets(stream, sizeof(stream), file));
printf("%s\n", stream);
*entries = strtol(stream, NULL, 10);
printf("Entries : %d\n", *entries);
if(*entries > 100){
printf("Entries is NOK\n");
exit(1);
}
//create the array of structures containing the data
printf("Creating the data array\n");
history *hist = malloc(*entries * sizeof(history));
//Read the data and copy it to the array
//this has not been tackled yet
printf("Closing file\n");
fclose(file);
printf("Freeing memory (filenames...)\n");
free(data_Dir);
free(directory);
free(fileName);
printf("Node %d, sensor %d: Data loaded Successfully (%d Entries)", node_Id, sensor_Id, *entries);
return hist;
}
据我所知,fgets 似乎每次都返回NULL。我不确定文件是否被正确读取,但似乎程序设法打开文件,因为fopen 返回非NULL。我也怀疑我第一次尝试使用二进制文件可能会因为类似的原因而失败,但由于格式的原因,我无法检查在写入或读取文件期间是否发生错误。
我想了解fgets 失败的原因。我也很感激任何有关处理从文件保存和加载数据的更好方法的指导,因为我只是 C 的初学者,而且我很确定有一些更优化的方法可以实现我想要实现的目标。
【问题讨论】:
-
你检查过文件的内容吗?他们看起来还好吗?
-
minimal reproducible example,强调minmal。您能否使用 较小的 代码段重现错误,然后重新发布,突出显示您看到错误的确切位置?
-
您应该调用 fgets() 并进行错误/EOF 检查和报告: If ( NULL == fgets(...)){ if( ferror(){ perror( "fegts()" ); return NULL } fprintf( stderr, "fgets() EOF\n" ): return NULL } 如果在 EOF 之前没有换行, fgets() 可以返回一个空字符串,如果在输入中返回一个空行 "\n"。
-
FILENAME_MAX的价值是多少? -
@chux-ReinstateMonica,是 260,如果我没记错的话,它包含在 io.h 中
标签: c fgets data-management fileparsing