2012-10-18 111 views
2

可能重複:
C, reading from file into structure讀取文本文件到數據結構用C

我需要閱讀大量文本文件,然後填寫的數據結構的郵件列表。

的數據結構如下:

typedef struct mentry { 
    char *surname; 
    int house_number; 
    char *postcode; 
    char *full_address; 
} MEntry; 

和文本文件格式是:

Bloggs, Joe 
1 Street Name, City 
M53 3JK 
Surname, Firstname 
University of Nowhere, City 
G44 3GB 

而且我對數據結構構造:

/* me_get returns the next file entry, or NULL if end of file*/ 
MEntry *me_get(FILE *fd); 

Whi ch返回一個指向包含郵件列表條目的MEntry結構的指針。

到目前爲止,我只設法逐行閱讀文件。

#define MAXLINE 1024 

int main(){ 
    char line[MAXLINE]; 
    FILE *fp = fopen("S.txt","r"); 

    while(fgets(line,MAXLINE,fp)) 
     { 
     printf("%s %d",line,linecount); 
    } 

    fclose(fp); 
    return 0; 
} 

我目前的主要問題是,我不知道如何分割我的行,以便我可以正確填充我的數據結構。我想知道如果在一段時間內使用fgetc來讀取一個字符比在整行中讀取然後嘗試分割它更容易?

+0

你可能想使用'regex'和/或腳本語言一樣'Python'。 – Ken

+1

這是一個非常普遍的問題,所以我試圖將你的標題應用到搜索中,並且它吐出來了http://stackoverflow.com/questions/6014045 http://stackoverflow.com/questions/2556629 http://stackoverflow.com/questions/11280523等等。當你在「提問」頁面中輸入標題時,大多數情況可能會出現,那麼爲什麼你不看他們呢? – dmckee

+0

@Ken只有當他(1)知道如何與c語言接口(沒有保證,因爲這是一個初學者的問題)並且(2)希望整個事情變得非常脆弱。 – dmckee

回答

0

在你的例子中,第二個地址沒有任何house_number

這意味着您不能依賴數據格式來盲目讀取文件。你不得不讀取數據然後解析它。

如果地址在指定postcode之前有2行文字,則可能會發生其他問題。

您是唯一知道您的輸入文件的可靠程度的人,因此必須應用哪些規則來無誤地解析它。

關於該方法,我會逐行讀取文件並通過解析每行文本來解釋它,直到找到每個記錄的postcode(因爲這似乎是您的結束) - 記錄標記)。

解析意味着查看line[]字符並在讀取數據時對數據進行分類(例如:逗號是首字母/尾名的分隔符,街道號碼是數字,郵政編碼遵循特定格式等) 。

這將需要一些工作,但這是可行的。按照品味,你明白我不會在RegEx區域冒險(而C有一個專用的運行時庫)。

Goog luck!

2

也許你應該使用的strtok

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

int main() 
{ 
    char str[] ="Elizarraras, Salvador, UG"; 
    char *token = NULL; 
    int n_tokens = 0; 

    printf ("Get tokens from string \"%s\"\n",str); 
    printf("%s\n", "*********************************************"); 

    // Split the string into tokens delimited by spaces and commas 
    token = strtok (str," ,"); 
    while (token != NULL) 
    { 
     printf("%s\n", token); 
     // Different call 
     token = strtok (NULL, " ,"); 
     n_tokens++; 
    } 

    return 0; 
} 

輸出:

Get tokens from string "Elizarraras, Salvador, UG" 

********************************************* 
Elizarraras 

Salvador 

UG 

有關於這個話題,Finding Tokens in a String一個有趣的文章。

0

這是我會怎麼做:

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

// It is easyer for the memory allocator to have all in the struct 
// It is a bit more wasteful on memory though if you set those too large 
#define MAX_SURNAME_LENGTH 32 
#define MAX_POSTCODE_LENGTH 32 
#define MAX_FULL_ADDRESS_LENGTH (256 - MAX_SURNAME_LENGTH - MAX_POSTCODE_LENGTH - sizeof(int)) 

typedef struct mentry { 
    char surname[MAX_SURNAME_LENGTH]; 
    char postcode[MAX_POSTCODE_LENGTH]; 
    int house_number; 
    char full_address[MAX_FULL_ADDRESS_LENGTH]; 
} MEntry; 

MEntry *me_get(FILE *fp) { 
    MEntry *mentry = calloc(sizeof(MEntry), 1); 

    // get name 
    char * name = fgets(mentry->surname, sizeof(mentry->surname), fp); 
    if (!name) { //failure 
     free(mentry); 
     return NULL; 
    } 

    char * comma = strchr(name, ','); // find the first comma appearance 
    if (comma) *comma = '\0'; // If name has a comma in it, terminate the string there 

    char * address = fgets(mentry->full_address, sizeof(mentry->full_address), fp); 
    if (!address) { //failure 
     free(mentry); 
     return NULL; 
    } 

    char * restaddress; 
    int housenumber = strtol(address, &restaddress, 10); 

    if (restaddress != address) // there was a valid number at the start of address 
     mentry->house_number = housenumber; 

    char * postcode = fgets(mentry->postcode, sizeof(mentry->postcode), fp); 
    if (!postcode) { //failure 
     free(mentry); 
     return NULL; 
    } 

    return mentry; 
} 

int main() { 
    FILE *fp = fopen("S.txt","r"); 

    MEntry *mentry; 
    while ((mentry = me_get(fp))) { 
     // do something useful with mentry 
    } 

    fclose(fp); 
    return 0; 
} 
相關問題