簡體   English   中英

處理數組並讀取文本文件

[英]Working with arrays and reading text files

嘿,我一直在研究這個問題,以從文本文件中讀取數字並將其存儲在數組中,但是由於某種原因無法使它正常工作。 任何幫助,將不勝感激。 任務是實現馬爾可夫鏈算法。 我做了閱讀部分,並在主要fun()中分配了數組,但是我一直在獲取未聲明的標識符作為錯誤。 這是代碼:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "eprintf.h"

enum {
    NPREF   = 2,    /* number of prefix words */
    NHASH   = 4093, /* size of state hash table array */
    MAXGEN  = 10000 /* maximum words generated */
};

typedef struct State State;
typedef struct Suffix Suffix;

struct State {  /* prefix + suffix list */
    char    *pref[NPREF];   /* prefix words */
    Suffix  *suf;           /* list of suffixes */
    State   *next;          /* next in hash table */
};

struct Suffix { /* list of suffixes */
    char    *word;          /* suffix */
    Suffix  *next;          /* next in list of suffixes */
};

State   *lookup(char *prefix[], int create);
void    build(char *prefix[], FILE*);
void    generate(int nwords);
void    add(char *prefix[], char *word);

State   *statetab[NHASH];   /* hash table of states */

char NONWORD[] = "\n";  /* cannot appear as real word */

//FILE* random_reader;
//FILE* myfile;


/* markov main: markov-chain random text generation */
int main(void)
{
    int i, nwords = MAXGEN;
    char *prefix[NPREF];        /* current input prefix */

    FILE* random_reader;
    FILE* myfile;

    int c;
    //long seed;

    setprogname("markov");
    //seed = time(NULL);

    //srand(seed);
    random_reader = fopen("../random_num.txt","r");
    myfile = fopen("../alice30.txt","r");
    int element;
    int random_num[10000];
    char line; //each number
    int i=0;
    while(fgets(line, 20, random_reader)!=NULL)  // update the array
    {
        sscanf(line,"%o",&element);
        random_num[i]=element;
        i++;
    }

    for (i = 0; i < NPREF; i++) /* set up initial prefix */
        prefix[i] = NONWORD;
    build(prefix, stdin);
    add(prefix, NONWORD);
    generate(nwords);
    return 0;
}   

const int MULTIPLIER = 31;  /* for hash() */

/* hash: compute hash value for array of NPREF strings */
unsigned int hash(char *s[NPREF])
{
    unsigned int h;
    unsigned char *p;
    int i;

    h = 0;
    for (i = 0; i < NPREF; i++)
        for (p = (unsigned char *) s[i]; *p != '\0'; p++)
            h = MULTIPLIER * h + *p;
    return h % NHASH;
}

/* lookup: search for prefix; create if requested. */
/*  returns pointer if present or created; NULL if not. */
/*  creation doesn't strdup so strings mustn't change later. */
State* lookup(char *prefix[NPREF], int create)
{
    int i, h;
    State *sp;

    h = hash(prefix);
    for (sp = statetab[h]; sp != NULL; sp = sp->next) {
        for (i = 0; i < NPREF; i++)
            if (strcmp(prefix[i], sp->pref[i]) != 0)
                break;
        if (i == NPREF)     /* found it */
            return sp;
    }
    if (create) {
        sp = (State *) emalloc(sizeof(State));
        for (i = 0; i < NPREF; i++)
            sp->pref[i] = prefix[i];
        sp->suf = NULL;
        sp->next = statetab[h];
        statetab[h] = sp;
    }
    return sp;
}

/* addsuffix: add to state. suffix must not change later */
void addsuffix(State *sp, char *suffix)
{
    Suffix *suf;

    suf = (Suffix *) emalloc(sizeof(Suffix));
    suf->word = suffix;
    suf->next = sp->suf;
    sp->suf = suf;
}

/* add: add word to suffix list, update prefix */
void add(char *prefix[NPREF], char *suffix)
{
    State *sp;

    sp = lookup(prefix, 1);  /* create if not found */
    addsuffix(sp, suffix);
    /* move the words down the prefix */
    memmove(prefix, prefix+1, (NPREF-1)*sizeof(prefix[0]));
    prefix[NPREF-1] = suffix;
}

/* build: read input, build prefix table */
void build(char *prefix[NPREF], FILE *f)
{
    char buf[100], fmt[10];

    /* create a format string; %s could overflow buf */
    sprintf(fmt, "%%%ds", sizeof(buf)-1);
    while (fscanf(f, fmt, buf) != EOF)
        add(prefix, estrdup(buf));
}

/* generate: produce output, one word per line */
void generate(int nwords)
{
    State *sp;
    Suffix *suf;
    char *prefix[NPREF], *w;
    int i, nmatch;

    for (i = 0; i < NPREF; i++) /* reset initial prefix */
        prefix[i] = NONWORD;

    for (i = 0; i < nwords; i++) {
        sp = lookup(prefix, 0);
        if (sp == NULL)
            eprintf("internal error: lookup failed");
        nmatch = 0;
        for (suf = sp->suf; suf != NULL; suf = suf->next)
            if (rand() % ++nmatch == 0) /* prob = 1/nmatch */
                w = suf->word;
        if (nmatch == 0)
            eprintf("internal error: no suffix %d %s", i, prefix[0]);
        if (strcmp(w, NONWORD) == 0)
            break;
        printf("%s\n", w);
        memmove(prefix, prefix+1, (NPREF-1)*sizeof(prefix[0]));
        prefix[NPREF-1] = w;
    }
}

******* Here are the eprintf header file**************

/* eprintf.h: error wrapper functions */
extern  void    eprintf(char *, ...);
extern  void    weprintf(char *, ...);
extern  char    *estrdup(char *);
extern  void    *emalloc(size_t);
extern  void    *erealloc(void *, size_t);
extern  char    *progname(void);
extern  void    setprogname(char *);

#define NELEMS(a)   (sizeof(a) / sizeof(a[0]))


*******here is the eprintf source file*********
#include <stdio.h>
#include <stdlib.h>
#include "eprintf.h"
#include <stdarg.h>
#include <string.h>
#include <errno.h>

static char *name = NULL;  /* program name for messages */

/* eprintf: print error message and exit */
void eprintf(char *fmt, ...)
{
    va_list args;

    fflush(stdout);
    if (progname() != NULL)
        fprintf(stderr, "%s: ", progname());

    va_start(args, fmt);
    vfprintf(stderr, fmt, args);
    va_end(args);

    if (fmt[0] != '\0' && fmt[strlen(fmt)-1] == ':')
        fprintf(stderr, " %s", strerror(errno));
    fprintf(stderr, "\n");
    exit(2); /* conventional value for failed execution */
}

/* weprintf: print warning message */
void weprintf(char *fmt, ...)
{
    va_list args;

    fflush(stdout);
    fprintf(stderr, "warning: ");
    if (progname() != NULL)
        fprintf(stderr, "%s: ", progname());
    va_start(args, fmt);
    vfprintf(stderr, fmt, args);
    va_end(args);
    if (fmt[0] != '\0' && fmt[strlen(fmt)-1] == ':')
        fprintf(stderr, " %s\n", strerror(errno));
    else
        fprintf(stderr, "\n");
}

/* emalloc: malloc and report if error */
void *emalloc(size_t n)
{
    void *p;

    p = malloc(n);
    if (p == NULL)
        eprintf("malloc of %u bytes failed:", n);
    return p;
}

/* erealloc: realloc and report if error */
void *erealloc(void *vp, size_t n)
{
    void *p;

    p = realloc(vp, n);
    if (p == NULL)
        eprintf("realloc of %u bytes failed:", n);
    return p;
}

/* estrdup: duplicate a string, report if error */
char *estrdup(char *s)
{
    char *t;

    t = (char *) malloc(strlen(s)+1);
    if (t == NULL)
        eprintf("estrdup(\"%.20s\") failed:", s);
    strcpy(t, s);
    return t;
}

/* progname: return stored name of program */
char *progname(void)
{
    return name;
}

/* setprogname: set stored name of program */
void setprogname(char *str)
{
    name = estrdup(str);
}

從上至下閱讀編譯器錯誤消息非常重要。 在出現C2065錯誤之前,您遇到了3個C2143錯誤。 錯誤消息的准確性和信息性通常很差,較早的錯誤可能會產生許多其他錯誤。 第一條消息抱怨元素變量聲明。 然后,對於包含元素的任何行,您都會遇到其他錯誤,因為編譯器無法正確解析聲明。

您的編譯器要求您將所有變量聲明放在使用它們的代碼之前

還要注意,您對i變量有兩個聲明。 必須是一個char數組: char line[20]; 將文件讀取代碼移動到單獨的函數中將是一個不錯的主意。

main()中,代碼后面會出現變量定義。 這在C99中是允許的,但在C89中是不允許的,因此,如果您使用的是舊的C89編譯器,或類似MSVC的工具仍不支持C99,則將無法編譯。 移動此塊:

int element;
int random_num[10000];
char line; //each number
int i=0;

在它之前的代碼上方,因此您的變量定義在任何實際代碼之前。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM