Rookie pointer problem: 2 dimensions, malloc
I will always be a pointer rookie, but any "real" C person will find this question to be kid stuff. As you can see underneath this very simple code, the input file is dropping a line (or character), though the code as written should exactly reproduce the input. Can anyone see the flaw in my code?
This is simple ANSI C. small model. I'm even using TC2.01 (may it never die). FWIW this is a massively stripped shell of a customizable sort. The game plan will be to take numerous argv column numbers and do a compound sort (vs. SORT.EXE only handling a single start column).
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void main(void)
{
FILE *fp;
char **TwoDimenSortable, **prow, buff[10];
unsigned u, ulines, umaxlen;
if((fp=fopen("test.dat","r"))==NULL) {puts("fopen poop");exit(55);}
/* count input file lines and max width too */
for (ulines=0, umaxlen = 0; fgets(buff, sizeof buff,fp); ++ulines) {
umaxlen=max(umaxlen, strlen(buff)); /* get max width while we're at it */
}
rewind(fp);
/* malloc the mass 2 dimensional array */
if (NULL==(TwoDimenSortable=(char **)malloc (ulines * umaxlen * sizeof (char)))) {
printf("Jeez, couldn't malloc %u lines for %u cols.\n",ulines,umaxlen);
exit(70);
}
/* malloc pointers to each line */
if (NULL==(prow=malloc(ulines * sizeof(char *)))) {
puts("malloc failure - cheez! (tiny one)\n");
exit(44);
}
for (u=0; u<ulines; ++u) {
prow[u] = (char *) TwoDimenSortable + (u * umaxlen); /* qsortable pointer array */
fgets(buff, sizeof buff, fp);
if(buff[strlen(buff)-1]=='\n')buff[strlen(buff)-1]='\0'; /* stripEOL */
strcpy((char *)TwoDimenSortable+u*umaxlen, buff);
}
fclose(fp);
/* qsort(prow, ulines, umaxlen, strncmp); */
for (u=0; u<ulines; ++u) {
prow[umaxlen-1]='\0';
puts(prow[u]);
}
}
/*
The input file test.dat is 5 simple lines, each one byte and CRLF:
1
2
3
4
*/
/*
The output is bizarrely
1
3
4
*/