我在文本文件中有大量数据需要分析。但是,我的问题是我不知道如何编写程序来读取我想要的数据。
我所拥有的是一个如此组织的文本文件:
Event: 23365
line 2
Q1: x,y,z= 263.25 -25.112 0.68342
Q2: x,y,z= 263.25 -25.112 0.68342
(blank line)
-next entry organized the same begins-
所以我想做的是以某种方式将每个变量分别放入几个数组(每个变量一个数组),以便我可以对它们进行数学运算。
哦,我在C编码。
我没有文件输入的经验,所以我几乎无能为力。我已经搜索了教程,但它没有太多帮助。所以基本上我需要以某种方式扫描文本文件并选出数字。
答案 0 :(得分:0)
好的,这不是很好,但这里有一种解析数据的方法的例子:
// you cant't get away from pointers in C, so might as well as force yourself to use them
// till they make sense. Here are some examples:
// pointer of type data
// data* d;
// d is assigned the address of a memory space the size of a data container
// d = (data*)malloc(sizeof(data));
// d can be dereferenced with *d.
// (*d).identifier is the same as d->identifier
// the memory space you got earlier can (and should) be freed
// free(d);
// if you free d and malloced d->extra, d->extra must be freed first
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
// define a type to hold information for each event
typedef struct
{
char* identifier;
char* extra;
double var[6];
} data;
// returns a pointer to a new data
data*
new_data()
{
// You are going to eventually need to know how malloc works
// or at least what it does. Just google it. For now, it requests
// memory from the heap to use
data* d = (data*)malloc(sizeof(data)); // request memory the size of the type data
d->identifier = (char*)malloc(sizeof(char)*128); // request some space for the c string identifier
memset(d->identifier,'\0',sizeof(char)*128); // set identifier to all 0's (for null terminated
// strings this means that I can replace the first zero's
// and wherever I stop the c string ends)
d->extra = (char*)malloc(sizeof(char)*128); // request some space for the c string extra
memset(d->extra,'\0',sizeof(char)*128); // set extra to all 0's
return d; // return the pointer
}
int main(void)
{
FILE *fp; // pointer to file object
int c; // char could be used too. This is what holds whatever fgetc is assigned to
int count = 0; // This program is a state machine and count represents a state
char* word = malloc(sizeof(char)*128); // holds several chars
int wordPosition = 0; // position of the next char to be written in word
fp = fopen("datafile.txt", "r"); // fp is assigned the file datafile.txt in read-only mode
memset(word,'\0',sizeof(char)*128); // set word to all 0's
data* d = new_data(); // get a new data container to write information to
while(c = fgetc(fp)) // loops and gets a new char each loop
{
if(!isspace(c) && c != EOF) // if the char isn't white space or the End Of File
word[wordPosition++] = c; // add the char to word
else
{
if(strlen(word) != 0) // skip if word is empty (for example if there were two spaces in a row)
{
switch(count) // determine the state
{
case(0):
// for case 0, you want the word that isn't "Event:", so
// count will stay at 0 and add every word that isn't "Event:"
// as long as there is only one other word then this will result
// in what you want
if(!(strcmp(word, "Event:") == 0))
strcpy(d->identifier, word);
// when there is a new line then go to state 1
// '\n' is a white space
if(c=='\n')
count++;
break;
case(1):
// for case 1 you just want the words on the line, so every word just add
// to extra with a space after it. Not the neatest way to do it.
strcat(d->extra, word);
strcat(d->extra, " ");
if(c=='\n')
count++;
break;
case(2): // for case 2 - 7 you just want the numbers so you can do something with them
case(3): // so if the first character of the word is a digit or '-' (negative) then
case(4): // add it to var[]. An easy way to know which one is just count-2.
case(5): // When a new number is added, go to the next state.
case(6): // Then test if count == 8. If so, you want to reset.
case(7): // skipping case 2-6 is simply saying for each of these go to case 7.
// that's why you need to break after a case you don't want to continue.
if(isdigit(word[0]) || word[0]=='-')
{
d->var[count-2] = atof(word);
count++;
}
if (count == 8)
{
// here is where you would do something different with the data you have.
// I imagine you would want an array of data's that you would just add this to
// for example, at the beginning of main have
// data* events[MAX_EVENTS];
// int eventCount = 0;
// and here do something like
// events[eventCount++] = d;
// remember that eventCount++ gets the value first and then increments
// after the instruction is over
printf("%s\n",d->identifier);
printf("%s\n",d->extra);
printf("%f\n",d->var[0]);
printf("%f\n",d->var[1]);
printf("%f\n",d->var[2]);
printf("%f\n",d->var[3]);
printf("%f\n",d->var[4]);
printf("%f\n",d->var[5]);
// set the state back to the beginning
count = 0;
// if you were doing something with the data, then don't free yet.
free(d->identifier);
free(d->extra);
free(d);
// make a new data and start over for the next event.
d = new_data();
}
break;
}
// clear the word and set wordPosition to the beginning
memset(word,'\0',sizeof(char)*128);
wordPosition = 0;
}
}
// check if the end of the file is reached and if so then exit the loop
if(c == EOF)
break;
}
fclose(fp);
// here you would do something like
// for(i = 0; i < eventCount; i++)
// total1 += events[i]->var[1];
// printf("The total of var1 is: %f\n",total1);
return 0;
}