Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to read in a string of unknown size in C, without having to put it in a pre-allocated fixed length buffer?

Tags:

c

Is it possible to read in a string in C, without allocating an array of fixed size ahead of time?

Everytime I declare a char array of some fixed size, I feel like I'm doing it wrong. I'm always taking a guess at what I think would be the maximum for my usecase, but this isn't always easy.

Also, I don't like the idea of having a smaller string sitting in a larger container. It doesn't feel right.

Am I missing something? Is there some other way I should be doing this?

like image 282
Daonkoyd Avatar asked Mar 03 '10 17:03

Daonkoyd


4 Answers

At the point that you read the data, your buffer is going to have a fixed size -- that's unavoidable.

What you can do, however, is read the data using fgets, and check whether the last character is a '\n', (or you've reached the end of file) and if not, realloc your buffer, and read more.

I rarely find that necessary, but do usually allocate a single fixed buffer for the reading, read data into it, and then dynamically allocate space for a copy of it, allocating only as much space as it actually occupies, not the whole size of the buffer I originally used.

like image 109
Jerry Coffin Avatar answered Oct 03 '22 10:10

Jerry Coffin


When you say "ahead of time", do you mean at runtime, or at compile time? At compile time you do this:

char str[1000];

at runtime you do this:

char *str = new char[size];

They only way to get exactly the right size is to know how many characters you are going to read in. If you're reading from a file, you can seek to the nearest newline (or some other condition) and then you know exactly how big the array needs to be. ie:

int numChars = computeNeededSpace(someFileHandle);
char *readBuffer = new char[numChars];
fread(someFileHandle, readBuffer, numChars);  //probly wrong parameter order

There is no other way to do this. Put yourself in the programs perspective, how is it supposed to know how many keys the user is going to press? The best thing you can do is limit the user, or whatever input.

there are some more complex things, like creating a linked list of buffers, and allocating chunks of buffers then linking them after. But I think that's not the answer you wanted here.

EDIT: Most languages have string/inputbuffer classes that hide this from you.

like image 23
Chris H Avatar answered Oct 03 '22 11:10

Chris H


You must allocate fixed buffer. If it becomes small, than realloc() it to bigger size and continue.

like image 39
Marko Kevac Avatar answered Oct 03 '22 12:10

Marko Kevac


There's no way of determining the string length until you've read it in, so reading it into a fixed-size buffer is pretty much your only choice.

I suppose you have the alternative to read the string in small chunks, but depending on your application that might not give you enough information at a time to work with.

Perhaps the easiest way to handle this dilemma is by defining maximum lengths for certain string input (#define-ing a constant for this value helps). Use a buffer of this pre-determined size whenever you are reading in a string, but make sure to use the strncpy() form of the string commands so you can specify a maximum number of characters to read. Some commonly-used types of strings (for example, filenames or paths) may have system-defined maximum lengths.

There's nothing inherently 'wrong' about declaring a fixed-size array as long as you use it properly (do proper bounds checking and handle the case where input will overflow the array). It may result in unused memory being allocated, but unfortunately the C language doesn't give us much to work with when it comes to strings.

like image 24
bta Avatar answered Oct 03 '22 12:10

bta