简体   繁体   English

处理数组并读取文本文件

[英]Working with arrays and reading text files

Hey, I've been working on this problem to read numbers from a text file and store them in an array but for some reason can't get it to work. 嘿,我一直在研究这个问题,以从文本文件中读取数字并将其存储在数组中,但是由于某种原因无法使它正常工作。 Any help would be appreciated. 任何帮助,将不胜感激。 the assignment is to implement the markov chain algorithm. 任务是实现马尔可夫链算法。 I've made the reading part and assigning the array in the main fun() but i keep getting undeclared identifier as an error. 我做了阅读部分,并在主要fun()中分配了数组,但是我一直在获取未声明的标识符作为错误。 Here is the code: 这是代码:

#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);
}

It is very important that you read compiler error message from the top down. 从上至下阅读编译器错误消息非常重要。 You got 3 C2143 errors before you got the C2065 error. 在出现C2065错误之前,您遇到了3个C2143错误。 It is typical that error messages get less accurate and informative, an earlier error may produce a slew of additional errors. 错误消息的准确性和信息性通常很差,较早的错误可能会产生许多其他错误。 The first message complains about the element variable declaration. 第一条消息抱怨元素变量声明。 Then you get additional errors for any line that contains element since the compiler couldn't properly parse the declaration. 然后,对于包含元素的任何行,您都会遇到其他错误,因为编译器无法正确解析声明。

Your compiler requires you to put all variable declarations before the code that uses them. 您的编译器要求您将所有变量声明放在使用它们的代码之前

Also note that you've got two declarations for the i variable. 还要注意,您对i变量有两个声明。 And that line needs to be an array of char: char line[20]; 必须是一个char数组: char line[20]; Moving the file reading code into a separate function would be a rather good idea. 将文件读取代码移动到单独的函数中将是一个不错的主意。

In main() you have variable definitions appearing after code. main()中,代码后面会出现变量定义。 This is permissible in C99 but not in C89, so if you're using an old C89 compiler, or something like MSVC which still doesn't support C99, then this is not going to compile. 这在C99中是允许的,但在C89中是不允许的,因此,如果您使用的是旧的C89编译器,或类似MSVC的工具仍不支持C99,则将无法编译。 Move this block: 移动此块:

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

up above the code before it so that your variable definitions precede any actual code. 在它之前的代码上方,因此您的变量定义在任何实际代码之前。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM