How to insert strings into buffer? - c

I'm new to C programming. I want to create circular buffer which writes strings into text file.
#include <stdio.h>
#include <malloc.h>
// Buffer writer header files
#include <stdlib.h>
typedef struct { char value; } ElemType;
/* Circular buffer object */
typedef struct {
int size; /* maximum number of elements */
int start; /* index of oldest element */
int end; /* index at which to write new element */
ElemType *elems; /* vector of elements */
} CircularBuffer;
void cbInit(CircularBuffer *cb, int size);
void cbFree(CircularBuffer *cb);
int cbIsFull(CircularBuffer *cb);
int cbIsEmpty(CircularBuffer *cb);
void cbWrite(CircularBuffer *cb, ElemType *elem);
void cbRead(CircularBuffer *cb, ElemType *elem);
void writeFile();
void cbInit(CircularBuffer *cb, int size) {
cb->size = size + 1; /* include empty elem */
cb->start = 0;
cb->end = 0;
cb->elems = (ElemType *)calloc(cb->size, sizeof(ElemType));
}
void cbFree(CircularBuffer *cb) {
free(cb->elems); /* OK if null */ }
int cbIsFull(CircularBuffer *cb) {
return (cb->end + 1) % cb->size == cb->start; }
int cbIsEmpty(CircularBuffer *cb) {
return cb->end == cb->start; }
/* Write an element, overwriting oldest element if buffer is full. App can
choose to avoid the overwrite by checking cbIsFull(). */
void cbWrite(CircularBuffer *cb, ElemType *elem) {
cb->elems[cb->end] = *elem;
cb->end = (cb->end + 1) % cb->size;
if (cb->end == cb->start)
cb->start = (cb->start + 1) % cb->size; /* full, overwrite */
}
/* Read oldest element. App must ensure !cbIsEmpty() first. */
void cbRead(CircularBuffer *cb, ElemType *elem) {
*elem = cb->elems[cb->start];
cb->start = (cb->start + 1) % cb->size;
}
int mainSecond(int argc, char **argv) {
CircularBuffer cb;
ElemType elem = {0};
int testBufferSize = 10; /* arbitrary size */
cbInit(&cb, testBufferSize);
/* Fill buffer with test elements 3 times */
for (elem.value = 0; elem.value < 3 * testBufferSize; ++ elem.value)
cbWrite(&cb, "AC");
/* Remove and print all elements */
while (!cbIsEmpty(&cb)) {
cbRead(&cb, &elem);
printf("%d\n", elem.value);
}
cbFree(&cb);
return 0;
}
int main(int argc, char** argv) {
writeFile();
return 0;
}
// write to file function
void writeFile() {
FILE *file;
file = fopen("file.txt", "a+"); /* apend file (add text to a file or create a file if it does not exist.*/
CircularBuffer cb;
ElemType elem = {0};
int testBufferSize = 10; /* arbitrary size */
cbInit(&cb, testBufferSize);
/* Fill buffer with test elements 3 times */
for (elem.value = 0; elem.value < 3 * testBufferSize; ++ elem.value)
cbWrite(&cb, "test");
/* Remove and print all elements */
while (!cbIsEmpty(&cb)) {
cbRead(&cb, &elem);
fprintf(file, "%d\n", elem.value);
// printf("%d\n", elem.value);
}
// write something into the file
fprintf(file, "%s", "Test!\n");
// close the file
fclose(file);
//getchar(); /* pause and wait for key */
cbFree(&cb);
}
The question is how I can insert Strings into the circular buffer and after that write them into text file? This implementation only works with numbers.

There are two ways:
Insert pointers in the circular buffer. You would store your string somewhere in memory. Then you have a pointer to that place in memory, that you store in your circular buffer.
Store characters in your circular buffer, in such a way that concatenating them results in strings. This means that the strings are copied into your buffer, and you need some way to read enough characters out of the buffer to make up a string.

Related

Hash table to store the frequency of names in list in C

I'm trying to implement a hash table in C. I have a csv file, which only consists of a list of surnames on separate lines each. e.g.
Synott
O Neill
Potter
that I am to read from. I then use a hash function, called hash1, to convert these strings into an integer which would give me my index for my hash table. I am then to store the frequency of the occurrence of each name. However, I am getting a segmentation fault which I have deduced is coming from my
void insert(struct individual *p)
function. I'm clueless as to how to solve this and have only started practising C.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define maxSize 500
/* Hash function that returns my key as an integer, giving me my index */
int hash1(char *s){
int hash = 0;
while(*s){
hash = hash + *s;
s++;
}
return hash;
}
/* Item to be stored */
struct individual{
int frequency; /* Value to be stored */
char name[50]; /* This is will be my key */
};
/* The hash table */
struct individual *hashArray[maxSize];
/* Initialising hash table */
void initArray(){
for (int i = 0; i < maxSize; i++){
hashArray[i]->frequency = 0;
hashArray[i]->name[i] = 0;
}
}
/* Function to load the names */
int next_field(FILE *f, char *buffer, int max){
int i = 0, end = 0;
for(;;){
buffer[i] = fgetc(f);
if(buffer[i] == '\n' || feof(f)){ end = 1; break; }
}
buffer[i] = 0;
return end;
};
/* Loading the names into structs - Done */
void reader(FILE *f, struct individual *n){
char buf[50];
next_field(f, n->name, maxSize);
};
/* Adding to the hash table */
void insert(struct individual *p){
struct individual *person = malloc(sizeof(struct individual));
int index = hash1(p->name) % maxSize;
// The issue is coming from this line here:
int primaryIndex = hash1(hashArray[index]->name) % maxSize;
/* Linear Probing */
printf("Do I get to here\n");
while(hashArray[index] != NULL){
if(primaryIndex == index){
hashArray[primaryIndex]->frequency++;
} else{
++index; /* Going to next block */
}
index %= maxSize; /* Looping through the hash table */
}
hashArray[index] = person;
};
void display(struct individual *duine){
printf("%s\n", duine->name);
};
int main(int argc, char *argv[]){
FILE *list;
struct individual in;
//initArray();
/* Opening file */
if( argc < 2 ) {
printf("Also include csv file name.\n");
return EXIT_FAILURE;
}
/* Checking if file is found */
list = fopen(argv[1], "r");
if(!list) {
printf("File not found. %s\n", argv[1]);
return EXIT_FAILURE;
}
while(!feof(list)){
reader(list, &in);
insert(&in);
display(&in);
}
fclose(list);
return EXIT_SUCCESS;
}
What I'm trying to do here is to compare two indices, one from the struct p being passed into this function and one from the hash table at this index. If they are the same, I wish to increase the frequency count stored there by 1. If I do remove this line, the rest of my code runs fine.
Thank you very much

Getting "Segmentation Fault(core dumped)" on Ubuntu in C for a hash table

I'm trying to implement a hash table in C. I have a csv file, which only consists of a list of surnames on separate lines each. e.g.
Sybott
O Neill
Potter
that I am to read from. I then use a hash function, called hash1, to convert these strings into an integer which would give me my index for my hash table. I am then to store the frequency of the occurrence of each name.
However, I am getting a segmentation fault which I have deduced is coming from my
void insert(struct individual *p)
function. I'm clueless as to how to solve this and have only started practising C.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define maxSize 500
/* Hash function that returns my key as an integer, giving me my index */
int hash1(char *s){
int hash = 0;
while(*s){
hash = hash + *s;
s++;
}
return hash;
}
/* Item to be stored */
struct individual{
int frequency; /* Value to be stored */
char name[50]; /* This is will be my key */
};
/* The hash table */
struct individual *hashArray[maxSize];
/* Initialising hash table */
void initArray(){
for (int i = 0; i < maxSize; i++){
hashArray[i]->frequency = 0;
hashArray[i]->name[i] = 0;
}
}
/* Function to load the names */
int next_field(FILE *f, char *buffer, int max){
int i = 0, end = 0;
for(;;){
buffer[i] = fgetc(f);
if(buffer[i] == '\n' || feof(f)){ end = 1; break; }
}
buffer[i] = 0;
return end;
};
/* Loading the names into structs - Done */
void reader(FILE *f, struct individual *n){
char buf[50];
next_field(f, n->name, maxSize);
};
/* Adding to the hash table */
void insert(struct individual *p){
struct individual *person = malloc(sizeof(struct individual));
int index = hash1(p->name) % maxSize;
// The issue is coming from this line here:
int primaryIndex = hash1(hashArray[index]->name) % maxSize;
/* Linear Probing */
printf("Do I get to here\n");
while(hashArray[index] != NULL){
if(primaryIndex == index){
hashArray[primaryIndex]->frequency++;
} else{
++index; /* Going to next block */
}
index %= maxSize; /* Looping through the hash table */
}
hashArray[index] = person;
};
void display(struct individual *duine){
printf("%s\n", duine->name);
};
int main(int argc, char *argv[]){
FILE *list;
struct individual in;
//initArray();
/* Opening file */
if( argc < 2 ) {
printf("Also include csv file name.\n");
return EXIT_FAILURE;
}
/* Checking if file is found */
list = fopen(argv[1], "r");
if(!list) {
printf("File not found. %s\n", argv[1]);
return EXIT_FAILURE;
}
while(!feof(list)){
reader(list, &in);
insert(&in);
display(&in);
}
fclose(list);
return EXIT_SUCCESS;
}
What I'm trying to do here is to compare two indices, one from the struct p being passed into this function and one from the hash table at this index. If they are the same, I wish to increase the frequency count stored there by 1. If I do remove this line, the rest of my code runs fine.
Thank you very much

How do I unpack and extract data properly using msgpack-c?

I'm currently trying to use msgpack in a project written in C. I'm using msgpack for the purpose of serializing the contents of a struct, which is then to be sent over the network, and deserialized back into a corresponding struct on the other side.
Condensed version of what I'm trying to do:
#include <stdio.h>
#include <msgpack.h>
#include <stdbool.h>
typedef someStruct{
uint32_t a;
uint32_t b;
float c;
} someStruct;
int main (void){
someStruct data;
/* ... Fill 'data' with some data for test purposes ...*/
msgpack_sbuffer* buff = msgpack_sbuffer_new();
msgpack_packer* pck = msgpack_packer_new(buff, msgpack_sbuffer_write);
someStruct* structs = malloc(sizeof(someStruct) * 10);
/* ... Fill 'structs' with members containing test data ... */
// Serialize
msgpack_pack_array (pck, 10);
int i;
for(i = 0 ; i < 10 ; i++){
msgpack_pack_array (pck, 3);
msgpack_pack_uint32 (pck, structs[i].a);
msgpack_pack_uint32 (pck, structs[i].b);
msgpack_pack_float (pck, structs[i].c);
}
free(structs);
msgpack_packer_free(pck);
// Deserialize
msgpack_unpacked msg;
msgpack_unpacked_init(&msg);
bool deserialize_success = msgpack_unpack_next
(&msg, buff->data, buff->size, NULL);
if(!deserialize_success) /* Error */
msgpack_object obj = msg.data;
msgpack_object_print(stdout,obj); // This seems to work perfectly, indicating serialize / deserialize works as intended...
someStruct deserialized_data;
/* Insert code to extract and cast deserialized data to 'deserialized_data */
// Clean
msgpack_sbuffer_free(buff);
msgpack_packer_free(pck);
return 0;
}
The code listed is more or less ripped straight from here, which seems to be one of very few resources on msgpack-c.
Can anyone point me in the right direction as to a way to 'recreate' the original struct on the other side of the wire? The only way I've found to actually utilize the deserialized data, is to use the msgpack_object_print() call to print from the messagepack_object. This does, however seem to work, so I'm certain the data is there.
Do I need to somehow loop through the serialized data and use msgpack_unpack_next() with an offset to retrieve each someStruct member? Using memcpy to a local byte buffer?
Any help is greatly appreciated!
Please find below a rewritten version that illustrates how to pack / unpack your data.
The whole idea is to pack each successive field of your struct, in a contiguous fashion, and apply (of course), the same logic at unpack time.
Right after pack, you are free to use the buffer the way you want (e.g send over the network, save on-disk, etc).
#include <stdio.h>
#include <assert.h>
#include <msgpack.h>
typedef struct some_struct {
uint32_t a;
uint32_t b;
float c;
} some_struct;
static char *pack(const some_struct *s, int num, int *size);
static some_struct *unpack(const void *ptr, int size, int *num);
/* Fixtures */
some_struct ary[] = {
{ 1234, 5678, 3.14f },
{ 4321, 8765, 4.13f },
{ 2143, 6587, 1.34f }
};
int main(void) {
/** PACK */
int size;
char *buf = pack(ary, sizeof(ary)/sizeof(ary[0]), &size);
printf("pack %zd struct(s): %d byte(s)\n", sizeof(ary)/sizeof(ary[0]), size);
/** UNPACK */
int num;
some_struct *s = unpack(buf, size, &num);
printf("unpack: %d struct(s)\n", num);
/** CHECK */
assert(num == (int) sizeof(ary)/sizeof(ary[0]));
for (int i = 0; i < num; i++) {
assert(s[i].a == ary[i].a);
assert(s[i].b == ary[i].b);
assert(s[i].c == ary[i].c);
}
printf("check ok. Exiting...\n");
free(buf);
free(s);
return 0;
}
static char *pack(const some_struct *s, int num, int *size) {
assert(num > 0);
char *buf = NULL;
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pck;
msgpack_packer_init(&pck, &sbuf, msgpack_sbuffer_write);
/* The array will store `num` contiguous blocks made of a, b, c attributes */
msgpack_pack_array(&pck, 3 * num);
for (int i = 0; i < num; ++i) {
msgpack_pack_uint32(&pck, s[i].a);
msgpack_pack_uint32(&pck, s[i].b);
msgpack_pack_float(&pck, s[i].c);
}
*size = sbuf.size;
buf = malloc(sbuf.size);
memcpy(buf, sbuf.data, sbuf.size);
msgpack_sbuffer_destroy(&sbuf);
return buf;
}
static some_struct *unpack(const void *ptr, int size, int *num) {
some_struct *s = NULL;
msgpack_unpacked msg;
msgpack_unpacked_init(&msg);
if (msgpack_unpack_next(&msg, ptr, size, NULL)) {
msgpack_object root = msg.data;
if (root.type == MSGPACK_OBJECT_ARRAY) {
assert(root.via.array.size % 3 == 0);
*num = root.via.array.size / 3;
s = malloc(root.via.array.size*sizeof(*s));
for (int i = 0, j = 0; i < root.via.array.size; i += 3, j++) {
s[j].a = root.via.array.ptr[i].via.u64;
s[j].b = root.via.array.ptr[i + 1].via.u64;
s[j].c = root.via.array.ptr[i + 2].via.dec;
}
}
}
msgpack_unpacked_destroy(&msg);
return s;
}

qsort for structures c

Below is my code:
I cant seem to use qsort effectively... It turns my array into 0's after they are populated with names and start times... Is it a problem with my qsort call? or the qsort itself.
The header with the structures is as follows:
/**
* Simulation of a process scheduler
*/
//#ifndef SCHEDULER_H_
#define SCHEDULER_H_
#include <stddef.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
/* types */
/** units of time */
typedef long time;
/** process identifier */
typedef int pid;
/** Information about a job of interest to the task scheduler */
struct job_data {
/* pid of this process */
pid pid;
/* time process starts */
time start;
/* time needed to finish */
time finish;
/* time spent processing so far */
time scheduled;
/* Number of lines */
int lines;
};
struct job {
/* Various parameters used by the scheduler */
char job_id[20];
struct job_data parameters;
char *lines[20];
};
/* I/O Files */
//static char *inputFile;
char * in;
static FILE *input;
static FILE *cur;
/*Scheduled jobs indexed by PID*/
struct job list[20];
/* the next job to schedule */
//static struct job *job_next = NULL;
/* Time */
time clock;
/*Comparison for qsort*/
int compare_start(const void *x, const void *y)
{
const struct job *a = x;
const struct job *b = y;
printf("%ld, %ld\n", a->parameters.start, b->parameters.start);
if (a->parameters.start < b->parameters.start)
{
return -1;
}
if (a->parameters.start > b->parameters.start)
{
return 1;
}
return 0;
}
/*Order Jobs*/
static void order_jobs(void)
{
qsort(list, (sizeof list) / (sizeof list[0]), sizeof list[0], compare_start);
}
/** Read and parse input from input file */
static void parse_input(void)
{
char buffer[BUFSIZ];
char lines[BUFSIZ];
int jobs = 0;
struct job *current;
while( fgets(buffer, sizeof(buffer), input) )
{
time start;
char buf[BUFSIZ];
sscanf(buffer,"./%s/", buf);
cur = fopen(buf, "r" );
int n_lines = 0;
while( fgets(lines, sizeof(lines), cur) )
{
if( n_lines == 0 )
{
current = &list[jobs];
strcpy(current->job_id, buf);
sscanf(lines,"%ld", &start);
current->parameters.start = start;
}
n_lines++;
}
current->parameters.lines = n_lines;
jobs++;
fclose(cur);
}
order_jobs();
for (int i = 0; i < jobs; i++)
{
printf("%s %ld %d\n", list[i].job_id, list[i].parameters.start, list[i].parameters.lines);
}
}
int main(int argc, char **argv)
{
in = argv[1];
if ( (input = fopen(in, "r")) == NULL ) {
fprintf(stderr, "cannot open %s\n", argv[1]);
}
parse_input();
fclose(input);
return EXIT_SUCCESS;
}
You only load jobs entries into the array, but you tell qsort() to sort the entire array (20 elements). This probably puts non-initialized elements at the front, which you then print.

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. 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. 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. And that line needs to be an array of 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. 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. 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.

Resources