0

分析が必要なテキスト ファイルに大量のデータ セットがあります。しかし、私の問題は、私が望むようにデータを読み込むプログラムを書く方法がわからないことです。

私が持っているのは、次のように編成されたテキストファイルです。

     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-

したがって、私がやりたいことは、これらの変数のそれぞれを何らかの形で複数の配列 (変数ごとに 1 つの配列) に取得して、それらに対して計算できるようにすることです。

ああ、私はCでコーディングしています。

私はファイル入力の経験がないので、ほとんど無知です。チュートリアルを検索しましたが、あまり役に立ちませんでした。したがって、基本的にはテキスト ファイルをスキャンして数字を抽出する必要があります。

4

1 に答える 1

0

OK、これはきれいではありませんが、データを解析する 1 つの方法の例を次に示します。

// 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;
}
于 2013-04-10T04:29:04.017 に答える