I am thoroughly stuck and too tired to RTFM, so here is some code hoping that somebody can teach me the basics... ;-)
The idea is simple:
- load a tab-delimited text file into a buffer
- create an array of (rows, columns) pointers
- scan the buffer with char c=buffer[currentposition]
- if c = \tab, isolate the string (i.e. replace tab with \0) and put its address into matrix[row][col], then col++
- if c = \newline, isolate the string and put its address into matrix[row][0], then row++, col=0;
So far, so simple. The good news: It works, and it's by far the fastest method to read a tab-delimited text into a matrix of pointers.
The bad news: It works only in assembler - in Pelles C, I seem to stumble over very basic problems... can somebody help?
EDIT: Version 3 works. The [r,c] assignment is OK now, but I know there should be a sizeof int in malloc().
One problem was this:
char *tmpc;
tmpc=(char*)buffer;
// mov eax, [ebp-0C]
// mov [ebp-3C], eax
printf("tmp=%X\n", tmpc); // tmp=4101AC, address
tmpc=(char*)buffer[0];
// mov eax, [ebp-0C]
// mov eax, [eax]
// mov [ebp-3C], eax
printf("tmp=%X\n", tmpc); // tmp=73726946, content
#include <stdio.h>
#include <windows.h>
#include <conio.h> // for _getch()
#pragma comment(linker, "-subsystem:console")
#pragma warn(disable:2216) // retval never used
#pragma warn(disable:2007) // assembly not portable
#pragma warn(disable:2118) // para not referenced
// #pragma warn(disable:2215) // conversion ... loss of data
int main(int argc, char* argv[]) {
#define cols 6
FILE *fp = fopen("Database.tab", "r");
// Name FamilyName Age Profession Street City
// Bill Watson 55 lawyer Main Street, 12 London
// John Doe 33 coder Small lane, 22 Edinburgh
// Will Smith 44 actor Catwalk Hollyword
fseek(fp, 0, SEEK_END); // go to end
long len=ftell(fp); // get position at end (length)
fseek(fp, 0, SEEK_SET); // back to start
char *psRight=malloc(len); // malloc buffer
char *psLeft=psRight; // get a copy pointer to the content
fread(psRight, len, 1, fp); // read file into buffer
fclose(fp);
int **rows=malloc(len/cols/4+100); // rough estimate of required #rows
int row=0, col, i, j;
byte c=99; // some value different from zero
while (c) {
rows[row]=malloc(cols*4); // reserve memory for one row of pointers
// would like to preset matrix[r,c] to a nullstring but this sets bytes only...
// memset(rows[row], 0, 1);
col=0;
while (c && c!=10) {
c=psRight[0];
if (c<=10) { // tab or linefeed
// put the address of a string into the matrix of pointers
rows[row][col]=(int)psLeft;
col++;
// replace \t or \n with \0
psRight[0]=0;
psLeft=psRight+1;
}
psRight++; // tab is one byte
}
psRight++; // CrLf is 2 bytes
row++;
c=psRight[0];
}
for (i=0; i<row; i++) {
printf("\n");
for (j=0; j<cols; j++) {
printf("%s\t", (char*) rows[i][j]);
}
}
}
Attached code compiles fine and is almost working.