使用数组和读取文本文件

时间:2010-12-05 08:06:35

标签: c

嘿,我一直在研究这个问题,从文本文件中读取数字并将它们存储在数组中,但由于某种原因无法使其工作。任何帮助,将不胜感激。赋值是实现马尔可夫链算法。我已经制作了阅读部分并在主要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);
}

2 个答案:

答案 0 :(得分:1)

从上到下读取编译器错误消息非常非常重要。在得到C2065错误之前,您遇到了3个C2143错误。通常,错误消息的准确性和信息性较低,较早的错误可能会产生大量额外错误。第一条消息抱怨元素变量声明。然后,对于包含元素的任何行,您会收到其他错误,因为编译器无法正确解析声明。

您的编译器要求您在使用它们的代码之前放置所有变量声明

另请注意,您有 i 变量的两个声明。那个需要是一个char数组:char line[20];将文件读取代码移动到一个单独的函数中将是一个相当不错的主意。

答案 1 :(得分:0)

main()中,您在代码后面出现了变量定义。这在C99中是允许的,但在C89中是不允许的,所以如果你使用的是旧的C89编译器,或者像MSVC这样仍然不支持C99的东西,那么这不会编译。移动此块:

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

在它之前的代码之上,以便你的变量定义在任何实际代码之前。