Reputation: 531
I would like to read input char by char and save it as a word into char* array. I don't know how long the input will be, so i want to alloc the memmory dynamicaly. The program ends,when the char is whitespace. How can i do this using realloc? There is my code:
#include <stdio.h>
int main(void) {
char *word=malloc(1*sizeof(char));
char c;
int numOfChars=0;
c=getchar();
word[0]=c;
numOfChars++;
while((c=getchar())!=' '){
numOfChars++;
realloc(word,numOfChars);
word[numofChars-1]=c;
}
printf("%s", word);
return 0;
}
Example input:Word
Example output:Word
Upvotes: 1
Views: 2715
Reputation: 21965
This will do
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *ptr;
char *word=malloc(1*sizeof *word);
char c;
int numofChars=0;
printf("Enter string terminated by a space :");
c=getchar();
word[0]=c;
numofChars++;
while((c=getchar())!=' '){
numofChars++;
ptr=realloc(word,numofChars*sizeof *ptr);
if(ptr!=NULL)
{
word=ptr;
word[numofChars-1]=c;
}
}
/* You need to append a null character to make it a valid string */
numofChars++;
ptr=realloc(word,numofChars*sizeof *ptr);
if(ptr!=NULL)
{
word=ptr;
word[numofChars-1]='\0';
}
printf("Word : %s\n", word);
free(word); // Freeing word/
return 0;
}
Well, you may write a function to replace
numofChars++;
ptr=realloc(word,numofChars*sizeof *ptr);
if(ptr!=NULL)
{
word=ptr;
word[numofChars-1]='\0';
}
Note: It is not suggested that you do
word=realloc(word,numOfChars*sizeof(char));
because in case realloc
fails, you have memory leak. So I used ptr
here.
Upvotes: 1
Reputation: 311038
The program can look the following way. Take into account that the input is buffered and filled until a new line character is entered that is also a white space character. And the result word must be zero terminated if you are going to use format specifier %s
to output it.
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
int main( void )
{
int c;
size_t n;
char *word;
char *tmp;
n = 0;
word = malloc( n + 1 );
word[n++] = '\0';
printf( "Enter a word: " );
while ( ( c = getchar() ) != EOF && !isspace( c ) && ( tmp = realloc( word, n + 1 ) ) != NULL )
{
word = tmp;
word[n-1] = c;
word[n++] = '\0';
}
printf( "You've entered \"%s\"\n", word );
free( word );
}
The program output might look like
Enter a word: Hello
You've entered "Hello"
Upvotes: 2
Reputation: 556
In order to explain what I had in mind, i quickly set up this little programm to explain how to use an exponential growth :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INITIAL_CAPACITY 100
#define GROW_FACTOR 1.5
struct string_buffer {
size_t capacity;
size_t length;
char *buffer;
};
typedef struct string_buffer string_buffer_t;
string_buffer_t *sb_init(void);
static void sb_grow(string_buffer_t *sb);
void sb_shrink(string_buffer_t *sb);
char *sb_release(string_buffer_t *sb);
void sb_append_char(string_buffer_t *sb, char c);
char *sb_peek_string(string_buffer_t *sb);
int main(void)
{
string_buffer_t *sb=sb_init();
int c;
while ( (c=getchar())!=' ' && c!='\n' && c!=EOF )
sb_append_char(sb, c);
char *string=sb_release(sb);
printf("string : \"%s\"\nlength : %zu\n", string, strlen(string));
free(string);
return 0;
}
string_buffer_t *sb_init(void)
{
string_buffer_t *new=malloc(sizeof *new);
if (new==NULL) exit(EXIT_FAILURE);
new->capacity=INITIAL_CAPACITY;
new->length=1;
new->buffer=malloc(INITIAL_CAPACITY);
if (new->buffer==NULL) exit(EXIT_FAILURE);
new->buffer[0]=0;
return new;
}
static void sb_grow(string_buffer_t *sb)
{
char *new=realloc(sb->buffer, (size_t) (GROW_FACTOR*sb->capacity));
if (new==NULL) exit(EXIT_FAILURE);
sb->capacity=(size_t) (GROW_FACTOR*sb->capacity);
sb->buffer=new;
}
void sb_shrink(string_buffer_t *sb)
{
char *new=realloc(sb->buffer, sb->length);
if (new==NULL) exit(EXIT_FAILURE);
sb->buffer=new;
}
char *sb_release(string_buffer_t *sb)
{
sb_shrink(sb);
char *string=sb->buffer;
free(sb);
return string;
}
void sb_append_char(string_buffer_t *sb, char c)
{
if (sb->capacity==sb->length) sb_grow(sb);
sb->buffer[sb->length-1]=c;
sb->buffer[sb->length]=0;
sb->length=sb->length+1;
}
Upvotes: 2