Skip to content

Instantly share code, notes, and snippets.

@edomora97
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save edomora97/04710b044a1205b03763 to your computer and use it in GitHub Desktop.
Save edomora97/04710b044a1205b03763 to your computer and use it in GitHub Desktop.
File reader
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
class FileReader {
private:
FileReader(const FileReader&fr){}
int maxBufferSize,bufferSize,bufferPointer;int fileNo;char*buffer;
void loadBuffer(){bufferSize=read(fileNo,buffer,maxBufferSize);bufferPointer=0;}
inline char nextChar(){if(bufferPointer>=bufferSize)loadBuffer();return buffer[bufferPointer++];}
bool skipSpaces(){char c;while(((c=nextChar())==' '||c=='\n'||c=='\t')&&c!='\0');if(c=='\0')return 0;bufferPointer--;return 1;}
public:
FileReader(const char*_name,int _bufferSize=150000){buffer=(char*)malloc(_bufferSize);fileNo=open(_name,O_RDONLY);maxBufferSize=_bufferSize;loadBuffer();}
FileReader(int _fileNo,int _bufferSize=150000){buffer=(char*)malloc(_bufferSize);fileNo=_fileNo;maxBufferSize=_bufferSize;loadBuffer();}
~FileReader(){free(buffer);close(fileNo);}
int readInt(){return(int)readLongLong();}
long long readLongLong(){long long n=0;int mul=1;char c;if(!skipSpaces())abort();c=nextChar();if(c=='+'||c=='-')mul=(c=='+')?1:-1;else bufferPointer--;do{c=nextChar();if(c>='0'&&c<='9')n=n*10+(c-'0');}while(c>='0'&&c<='9');return n*mul;}
double readDouble(){double n=0;int mul=1,i=0,dotpos=0;char c;if(!skipSpaces())abort();c=nextChar();if(c=='+'||c=='-')mul=(c=='+')?1:-1;else bufferPointer--;do{i++;c=nextChar();if(c>='0'&&c<='9')n=n*10.0+(c-'0');if(c=='.')dotpos=i;}while((c>='0'&&c<= '9')||c=='.');if(dotpos>0)for(;dotpos<i-1;dotpos++)n/=10.0;return n*mul;}
int readString(char*str){if(!skipSpaces())return str[0]=0;char c;int l=0;do{c=nextChar();str[l++]=c;}while(c!=' '&&c!='\n'&&c!='\t'&&c!='\0');str[--l]='\0';return l;}
char readChar(){if(!skipSpaces())return'\0';return nextChar();}
};
class FileWriter {
private:
FileWriter(const FileWriter&fr){}
char*buffer;int bufferPointer,bufferSize;int fileNo;
inline void flushBuffer(){if(write(fileNo,buffer,bufferPointer)==-1)abort();bufferPointer=0;}
inline void writeCharBuffer(char c){if(c!=0)buffer[bufferPointer++]=c;if(bufferPointer+5>=bufferSize)flushBuffer();}
public:
FileWriter(const char*path,int bufSize=100000){fileNo=open(path,O_CREAT|O_TRUNC|O_WRONLY,S_IRWXU|S_IRWXG|S_IRWXO);buffer=(char*)malloc(bufSize);bufferSize=bufSize;bufferPointer=0;}
FileWriter(int fd,int bufSize=100000){fileNo=fd;buffer=(char*)malloc(bufSize);bufferSize=bufSize;bufferPointer=0;}
~FileWriter(){flushBuffer();free(buffer);close(fileNo);}
void writeInt(int val,char sep='\n'){writeLongLong(val,sep);}
void writeLongLong(long long val,char sep='\n'){char buf[21];int point=0;bool neg=val<0;if(neg)val=-val;while(val>0){buf[point++]=(val%10)+'0';val/=10;}if(neg)writeCharBuffer('-');for(int i=point-1;i>=0;i--)writeCharBuffer(buf[i]);if(point==0)writeCharBuffer('0');writeCharBuffer(sep);}
void writeChar(char c,char sep='\n'){writeCharBuffer(c);writeCharBuffer(sep);}
void writeString(char* str,int l,char sep='\n'){while(l--){writeCharBuffer(str[0]);str++;}writeCharBuffer(sep);}
void flush(){flushBuffer();}
};
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
/**
* Read a file (a lot) faster than scanf/cin
*/
class FileReader {
private:
FileReader(const FileReader& fr) {}
int maxBufferSize, bufferSize, bufferPointer;
int fileNo;
char* buffer;
/**
* Load the buffer and replace the old one
*/
void loadBuffer() {
bufferSize = read(fileNo, buffer, maxBufferSize);
// reset the pointer to the begin
bufferPointer = 0;
}
/**
* Get the next char from the buffer, if the buffer finish reload it
*/
inline char nextChar() {
// reload the buffer if needed
if (bufferPointer >= bufferSize)
loadBuffer();
return buffer[bufferPointer++];
}
/**
* Skip all spaces (spaces, end line, tabulation). If the file finish
* return false
*/
bool skipSpaces() {
char c;
while (((c = nextChar()) == ' ' || c == '\n' || c == '\t') && c != '\0')
;
if (c == '\0')
return 0;
// un-get the last chat
bufferPointer--;
return 1;
}
public:
/**
* Load the file and the buffer
* _name is the file name
* _bufferSize is the maximum amuount of memory used for the buffer
*/
FileReader(const char* _name, int _bufferSize = 150000) {
buffer = (char*)malloc(_bufferSize);
fileNo = open(_name, O_RDONLY);
maxBufferSize = _bufferSize;
loadBuffer();
}
/**
* Load from a file descriptor
* _fileNo is the file descriptor (must be opened in read mode! try STDIN_FILENO ;)
* _bufferSize is the maximum amount of memory used for the buffer
*/
FileReader(int _fileNo, int _bufferSize = 150000) {
buffer = (char*)malloc(_bufferSize);
fileNo = _fileNo;
maxBufferSize = _bufferSize;
loadBuffer();
}
/**
* Release the buffer
*/
~FileReader() {
free(buffer);
close(fileNo);
}
/**
* Read the next integer from the buffer. Negative numbers are allowed
*/
int readInt() {
int n = 0, mul = 1;
char c;
// if the file ends there isn't a number. So yeah
if (!skipSpaces()) abort();
// try to parse the sign
c = nextChar();
if (c == '+' || c == '-')
mul = (c == '+') ? 1 : -1;
else // if the sign is not present, un-get the read char
bufferPointer--;
do {
c = nextChar();
if (c >= '0' && c <= '9')
n = n*10 + (c-'0');
} while (c >= '0' && c <= '9');
return n * mul;
}
/**
* Read a long long from the buffer. Negative #s are ok!
*/
long long readLongLong() {
long long n = 0;
int mul = 1;
char c;
if (!skipSpaces()) abort();
c = nextChar();
if (c == '+' || c == '-')
mul = (c == '+') ? 1 : -1;
else
bufferPointer--;
do {
c = nextChar();
if (c >= '0' && c <= '9')
n = n*10 + (c-'0');
} while (c >= '0' && c <= '9');
return n * mul;
}
/**
* Read a double from the buffer. Formats allowed are:
* 0.1
* 1
* -1
* -1.0
* .0
* -.0
*/
double readDouble() {
double n = 0;
int mul = 1, i = 0;
int dotpos = 0;
char c;
if (!skipSpaces()) abort();
c = nextChar();
if (c == '+' || c == '-')
mul = (c == '+') ? 1 : -1;
else
bufferPointer--;
do {
i++;
c = nextChar();
if (c >= '0' && c <= '9')
n = n*10.0 + (c-'0');
if (c == '.')
dotpos = i;
} while ((c >= '0' && c <= '9') || c == '.');
// if there is the dot
if (dotpos > 0)
for (; dotpos < i-1; dotpos++)
n /= 10.0;
return n * mul;
}
/**
* Read a string from the buffer. Spaces, tabs, endlines, EOF
* terminate the string
*/
int readString(char* str) {
// no string, no party
if (!skipSpaces())
return str[0] = 0;
char c;
int l = 0;
do {
c = nextChar();
str[l++] = c;
} while (c != ' ' && c != '\n' && c != '\t' && c != '\0');
str[--l] = '\0';
return l;
}
/**
* Read a single char (skipping spaces before)
*/
char readChar() {
if (!skipSpaces())
return '\0';
return nextChar();
}
};
#include <assert.h>
#include <time.h>
int main() {
printf("BENCHMARK FileReader\n");
const int N_SAMPLES = 10000000;
int* v;
bool custom = false;
// try to open the file
FILE* in = fopen("sample.txt", "r");
// if not present, generate it!
if (in == NULL) {
printf("Generazione file...\n");
// generate a random vector
v = (int*)malloc(N_SAMPLES * sizeof(int));
for (int i = 0; i < N_SAMPLES; i++)
v[i] = rand();
printf("Scrittura file...\n");
// write the vector to file
FILE* out = fopen("sample.txt", "w");
fprintf(out, "%d\n", N_SAMPLES);
for (int i = 0; i < N_SAMPLES; i++)
fprintf(out, "%d\n", v[i]);
fclose(out);
// open the new file
in = fopen("sample.txt", "r");
} else {
printf("File già presente...\n");
// confronto con il vettore generato = mi sa proprio di no :(
custom = true;
}
/*
* Formato file sample.txt
* Prima riga N, numero elementi
* Successive N righe, elementi
*/
printf("fscanf : ");
time_t start1 = clock() / (CLOCKS_PER_SEC / 1000);
int N1; assert(1 == fscanf(in, "%d", &N1));
// se è custom alloca un nuovo vettore
// altrimenti controlla la dimensione letta
if (custom) v = (int*)malloc(N1 * sizeof(int));
if (!custom) assert(N1 == N_SAMPLES);
int x;
for (int i = 0; i < N1; i++) {
assert( 1 == fscanf(in, "%d", &x) );
// se non è custom allora controlla con il vettore generato,
// altrimenti salva x
if (!custom) assert(x == v[i]);
else v[i] = x;
}
time_t end1 = clock() / (CLOCKS_PER_SEC / 1000);
printf("%ld ms\n", end1-start1);
printf("FileReader: ");
time_t start2 = clock() / (CLOCKS_PER_SEC / 1000);
FileReader fr("sample.txt");
int N2 = fr.readInt();
// controlla la dimensione letta
if (!custom) assert(N2 == N_SAMPLES);
assert(N1 == N2);
for (int i = 0; i < N2; i++) {
x = fr.readInt();
// il numero letto deve corrispondere a quello nel vettore
assert(x == v[i]);
}
time_t end2 = clock() / (CLOCKS_PER_SEC / 1000);
printf("%ld ms\n", end2-start2);
return 0;
}
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
/**
* Write a file (a lot) faster than printf/cout
*/
class FileWriter {
private:
FileWriter(const FileWriter& fr) {}
char* buffer;
int bufferPointer, bufferSize;
int fileNo;
/**
* Write the buffer to file
*/
inline void flushBuffer() {
if (write(fileNo, buffer, bufferPointer) == -1)
abort();
bufferPointer = 0;
}
/**
* Write a char into the buffer. Flush it if needed
*/
inline void writeCharBuffer(char c) {
if (c != 0)
buffer[bufferPointer++] = c;
if (bufferPointer+5 >= bufferSize)
flushBuffer();
}
public:
/**
* Open the file for writing. If the file doesn't exists, it will be
* created
* path: the file path
* bufSize: the size of the buffer
*/
FileWriter(const char* path, int bufSize = 100000) {
fileNo = open(path, O_CREAT|O_TRUNC|O_WRONLY, S_IRWXU|S_IRWXG|S_IRWXO);
buffer = (char*)malloc(bufSize);
bufferSize = bufSize;
bufferPointer = 0;
}
/**
* Use an already open file descriptor. Warning! if the same file
* is used with an other library it could become incoerent
* fd: the file descriptor open in writing
* bufSize: the size of the buffer
*/
FileWriter(int fd, int bufSize = 100000) {
fileNo = fd;
buffer = (char*)malloc(bufSize);
bufferSize = bufSize;
bufferPointer = 0;
}
/**
* Release the buffer and close the file
*/
~FileWriter() {
flushBuffer();
free(buffer);
close(fileNo);
}
/**
* Write an integer into the buffer. sep will be appended after
*/
void writeInt(int val, char sep = '\n') {
writeLongLong(val, sep);
}
/**
* Write a long integer into the buffer. sep will be appended after
*/
void writeLongLong(long long val, char sep = '\n') {
char buf[21]; int point = 0;
bool neg = val < 0;
if (neg) val = -val;
while (val > 0) {
buf[point++] = (val % 10) + '0';
val /= 10;
}
if (neg) writeCharBuffer('-');
for (int i = point-1; i >= 0; i--)
writeCharBuffer(buf[i]);
if (point == 0) writeCharBuffer('0');
writeCharBuffer(sep);
}
/**
* Write a char into the buffer. sep will be appended after
*/
void writeChar(char c, char sep = '\n') {
writeCharBuffer(c);
writeCharBuffer(sep);
}
/**
* Write a string of l charaters into the buffer. sep will be
* appended after
*/
void writeString(char* str, int l, char sep = '\n') {
while (l--) {
writeCharBuffer(str[0]);
str++;
}
writeCharBuffer(sep);
}
/**
* Flush the buffer
*/
void flush() {
flushBuffer();
}
};
char str[1000];
int main() {
FileWriter fw("out.txt", 100000);
fw.writeInt(123);
fw.writeInt(1234567890);
fw.writeInt(-1234567890);
fw.writeLongLong(0);
fw.writeLongLong(1234567890123456789);
fw.writeLongLong(-1234567890123456789);
fw.writeChar('a', ' ');
fw.writeChar('b', '\0');
fw.writeChar('c');
for (int i = 0; i < 1000-1; i++) str[i] = 'a';
str[1000-1] = 0;
fw.writeString(str, 1000);
fw.flush();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment