Keith said:
frank said:
Keith said:
I was hoping to follow the development of 2-d resizable arrays in _C
Unleashed_. The material is difficult for me, and doing it on a
relatively new to me platform has been a series of pratfalls. It's
chapter 11, and I'm looking at 11-18. The readme.txt has the
following suggestions for command lines:
Unix/Linux/DJGPP:
gcc -Wall -ansi -pedantic -c -o foo.o foo.c [-lm]
Microsoft C (any 16-bit version including VC1.0 and 1.5):
cl -AL -W4 -Za -Zi -Od -c foo.c
...
I think the [-lm] indicates something optional.
Yes, the square brackets in this context mean that it's optional.
The "-lm" option, on some compilers (including most Unix compilers)
tells the linker to use the math library. It's not necessary if
you're not using any functions defined in the math library (which
functions those are is implementation-specific, but it's typically
close to what's declare in <math.h>), or if the implementation is
smart enough not to need the option. The reasons for this are
historical; at one time, implementations weren't clever enough
to figure out on their on whether the math library is needed,
and omitting it by default could save significant time and space.
These are mostly irrelevant for modern systems, but the behavior
lives on.
Is it an accurate statement that gcc is C99-compliant?
First of all, the "-lm" option has nothing to do with C99 compliance.
Second, no, gcc is not entirely C99-compliant, though it's close. See
<
http://gcc.gnu.org/c99status.html> for the current status. Follow
the links to see the status for the version you're using. Remember
that library issues are independent of gcc.
That's a good page; I bookmarked it. I'm not all that well informed
about the hiccups in differing vendors' C99 implementations. I'm
surprised one doesn't hear more about this effort in clc.
It's nearly impossible to tell what the problem is without seeing code.
My wild guess is that you're using
#include <myheader.h>
when you should be using
#include "myheader.h"
That's not it. BTW, in #include "myheader.h", MUST a compiler include a
myheader.h in the same directory?
The first command line folds over in an unfortunate way (there is only a
space between -Wextra and t1.c):
dan@dan-desktop:~/source/unleashed/ch11$ gcc -std=c99 -Wall -Wextra
t1.c -o out/tmp/ccQ5ko8j.o: In function `ReadFile':
t1.c

.text+0x7e): undefined reference to `AllocStrArray'
t1.c

.text+0x147): undefined reference to `AddRowsToStrArray'
t1.c

.text+0x187): undefined reference to `ResizeOneString'
t1.c

.text+0x203): undefined reference to `AddRowsToStrArray'
t1.c

.text+0x246): undefined reference to `FreeStrArray'
t1.c

.text+0x269): undefined reference to `ConsolidateStrArray'
/tmp/ccQ5ko8j.o: In function `main':
t1.c

.text+0x322): undefined reference to `FreeStrArray'
collect2: ld returned 1 exit status
dan@dan-desktop:~/source/unleashed/ch11$ cat t1.c
/* c11_018.c - read a text file into memory
*
* C11_018 - dynamic allocation of arrays
*
* Copyright (C) 2000 Richard Heathfield
* Eton Computer Systems Ltd
* Macmillan Computer Publishing
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
* Public License as published by the Free Software
* Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General
* Public License along with this program; if not, write
* to the Free Software Foundation, Inc., 675 Mass Ave,
* Cambridge, MA 02139, USA.
*
* Richard Heathfield may be contacted by email at:
* (e-mail address removed)
*
*/
#include <stdio.h>
#include <string.h>
#include "strarr.h"
#define DEFAULT_LINE_LEN 64
#define LINES_PER_ALLOC 16
#define ERR_ROWS_NOT_ADDED 1
#define ERR_STRING_NOT_RESIZED 2
#define ERR_FILE_OPEN_FAILED 3
#define ERR_ALLOC_FAILED 4
int ReadFile(char *Filename,
char ***Array,
int *NumRows)
{
char Buffer[DEFAULT_LINE_LEN] = {0};
char *NewLine = NULL;
FILE *fp;
int Error = 0;
int Row = 0;
size_t NumBlocks;
*NumRows = 0;
*Array = AllocStrArray(LINES_PER_ALLOC,
DEFAULT_LINE_LEN);
if(NULL != *Array)
{
fp = fopen(Filename, "r");
if(fp != NULL)
{
*NumRows = LINES_PER_ALLOC;
NumBlocks = 1;
/* fgets will give us no more than sizeof Buffer
* bytes, including zero terminator and newline
* if one is present within that number of bytes.
* Therefore we need to cater for longer lines.
* To do this, we call fgets again (and again
* and again) until we encounter a newline.
*/
while(0 == Error &&
NULL != fgets(Buffer, sizeof Buffer, fp))
{
NewLine = strchr(Buffer, '\n');
if(NewLine != NULL)
{
*NewLine = '\0';
}
/* This strcat relies on the AllocStrArray()
* function initialising rows to empty strings.
*/
strcat((*Array)[Row], Buffer);
if(NewLine != NULL)
{
/* There was a newline, so the
* next line is a new one.
*/
NumBlocks = 1;
++Row;
if(Row >= *NumRows)
{
/* Add another LINES_PER_ALLOC lines.
* If it didn't work, give up.
*/
if(0 == AddRowsToStrArray(Array,
*NumRows,
LINES_PER_ALLOC,
DEFAULT_LINE_LEN))
{
Error = ERR_ROWS_NOT_ADDED;
}
else
{
*NumRows += LINES_PER_ALLOC;
}
}
}
else
{
++NumBlocks;
/* Make room for some more data on this line */
if(0 ==
ResizeOneString(*Array,
Row,
NumBlocks * DEFAULT_LINE_LEN))
{
Error = ERR_STRING_NOT_RESIZED;
}
}
}
fclose(fp);
if(0 == Error && *NumRows > Row)
{
if(0 == AddRowsToStrArray(Array,
*NumRows,
Row - *NumRows,
0))
{
Error = ERR_ALLOC_FAILED;
}
*NumRows = Row;
}
}
else
{
Error = ERR_FILE_OPEN_FAILED; /* Can't open file */
}
}
else
{
Error = ERR_ALLOC_FAILED; /* Can't allocate memory */
}
if(Error != 0)
{
/* If the original allocation failed,
* *Array will be NULL. FreeStrArray()
* correctly handles this possibility.
*/
FreeStrArray(*Array, *NumRows);
*NumRows = 0;
}
else
{
ConsolidateStrArray(*Array, *NumRows);
}
return Error;
}
int main(int argc, char **argv)
{
char **array = NULL;
int rows;
int thisrow;
int error;
if(argc > 1)
{
error = ReadFile(argv[1], &array, &rows);
switch(error)
{
case 0:
for(thisrow = rows - 1; thisrow >= 0; thisrow--)
{
printf("%s\n", array[thisrow]);
}
FreeStrArray(array, rows);
break;
case ERR_STRING_NOT_RESIZED:
case ERR_ALLOC_FAILED:
case ERR_ROWS_NOT_ADDED:
puts("Insufficient memory.");
break;
case ERR_FILE_OPEN_FAILED:
printf("Couldn't open %s for reading\n", argv[1]);
break;
default:
printf("Unknown error! Code %d.\n", error);
break;
}
}
else
{
puts("Please specify the text file name.");
}
return 0;
}
/* end of c11_018.c */
/* gcc -Wall -ansi -pedantic -o out t1.c
gcc -std=c99 -Wall -Wextra t1.c -o out */
dan@dan-desktop:~/source/unleashed/ch11$ cat strarr.h
/* strarr.h - header for string array demo
*
* STRARR - dynamic allocation of arrays of strings
*
* Copyright (C) 2000 Richard Heathfield
* Eton Computer Systems Ltd
* Macmillan Computer Publishing
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
* Public License as published by the Free Software
* Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General
* Public License along with this program; if not, write
* to the Free Software Foundation, Inc., 675 Mass Ave,
* Cambridge, MA 02139, USA.
*
* Richard Heathfield may be contacted by email at:
* (e-mail address removed)
*
*/
#ifndef STRARR_H__
#define STRARR_H__
void FreeStrArray(char **Array, size_t NumRows);
char **AllocStrArray(size_t NumRows, size_t Width);
int ResizeOneString(char **Array,
size_t Row,
size_t NewSize);
int AddRowsToStrArray(char ***ArrayPtr,
size_t OldNumRows,
int NumRowsToAdd,
size_t InitWidth);
int ConsolidateStrArray(char **ArrayPtr,
size_t NumRows);
#endif
dan@dan-desktop:~/source/unleashed/ch11$
I apologize for the product of the length of this post times whatever
idiocy my misunderstanding must represent.