How to Declare an Array of Unknown Size Then Take Input Till I Desire and Then Get the Size of the Array

How do I declare an array of unknown size then take input till I desire and then get the size of the array?

cin >> arr; puts a C-style string into arr, which is terminated with '\0', not with '\n' (even though you press enter to send the input to your program). To get that expected output of 4, you need to change this

if (arr[i] == '\n')

To this:

if (arr[i] == '\0')

Programming in C, How to declare array of unknown size to be used later?

You could use dynamic memory allocation, which will allow you to declare an array of unknown size to be used later at runtime.

Here is an example of what you could do :

#include <stdio.h>

int main (void) {
int n_legal_cards;
int* legal_cards;

printf("How many legal cards are there?\n");
scanf("%d", &n_legal_cards);

if (n_legal_cards > 0) {

legal_cards = malloc(n_legal_cards * sizeof(int));

}


/*
...
[scanning other variables in here]
[a little bit of other code here]
...
*/


if (n_legal_cards > 0) {
int rounds_suit = legal_cards[0];
}


return 0;
}

Add user input to array of unknown size

regarding:

int main(void)
{
int score;
// start count for size of array
int count = - 1;

do
{
score = get_int("Score: ");
// add one to the count for each score
count++;
}
while (score != 0);

// now the size of the array is defined by how many times the user has typed.
int scores[count];

for (int i = 0; i < count; i++)
{
// how do I add each score to the array???
}
}

this does not compile and contains several logic errors

it is missing the statements: #include <cs50.h> and
#include <stdio.h>

regarding:

    int score;
// start count for size of array
int count = - 1;

do
{
score = get_int("Score: ");
// add one to the count for each score
count++;
}
while (score != 0);

This only defines a single variable: score and each time through the loop that single variable is overlayed. Also, the first time through the loop, the counter: count will be incremented to 0, not 1

on each following time through the loop, the variable score will be overlayed (I.E. all prior values entered by the user will be lost)

suggest using dynamic memory. Note: to use dynamic memory, will need the header file: stdlib.h for the prototypes: malloc() and free(). Suggest:

#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>

int main( void )
{
// pointer to array of scores
int * score = NULL;

// start count for size of array
int count = 0;

while( 1 )
{
int score = get_int("Score: ");

if( score != 0 )
{ // then user has entered another score to put into array
count++;
int * temp = realloc( scores, count * sizeof( int ) )
if( ! temp )
{ // realloc failed
// output error info to `stderr`
// note: `perror()` from `stdio.h`
perror( "realloc failed" );

// cleanup
free( scores );

// `exit()` and `EXIT_FAILURE` from `stdlib.h`
exit( EXIT_FAILURE );
}

// implied else, 'realloc()' successful, so update the target pointer
scores = temp;

// insert the new score into the array
scores[ count ] = score;
}

else
{ // user entered 0 so exit the loop
break;
}
}

note: before exiting the program, pass scores to free() so no memory leak.

How to create an array without declaring the size in C?

C does not support arrays with a dynamic number of elements. The number of elements of an array must be determined either at compile time or since C99 can be evaluated at runtime at the point of creation. Once the array is created, its size is fixed and cannot be changed. There are a few cases where the size is not explicitly specified between the [], either in array definitions or in array declarations.

You can define an array without an explicit size for the leftmost dimension if you provide an initializer. The compiler will infer the size from the initializer:

int a[] = { 1, 2, 3 };              // equivalent to int a[3] = { 1, 2, 3 };
int m[][2] = {{ 1, 2 }, { 3, 4 }}; // equivalent to int m[2][2] = {{ 1, 2 }, { 3, 4 }};
char s[] = "Hello world\n"; // equivalent to char s[13] = "Hello world\n";

Note how the compiler adds the implicit null terminator in the string case.

You can declare an array without a size specifier for the leftmost dimension in multiples cases:

  • as a global variable with extern class storage (the array is defined elsewhere),
  • as a function parameter: int main(int argc, char *argv[]). In this case the size specified for the leftmost dimension is ignored anyway.
  • as the last member of a struct with more than one named member. This is a C99 extension called a flexible array.

The compiler has no information on the actual size of these arrays. The programmer will use some other information to determine the length, either from a separate variable or from the array contents.

In the case of a function argument, the array is passed as a pointer and even if the number of elements is specified, sizeof(argv) evaluates to the size of a pointer.

C scanf - unknown array size

You can dynamically allocate the array and then reallocate the memory for it when the previously allocated buffer is full. Note that the conversion specifier %f in the format string of scanf reads and discards the leading whitespace characters. From the man page of scanf -

scanf returns the number of items successfully matched and assigned
which can be fewer than provided for, or even zero in the event of an
early matching failure. The value EOF is returned if the end of input
is reached before either the first successful conversion or a matching
failure occurs.

This means that scanf will return EOF only when it encounters EOF as the first input when it is called because EOF must be preceded with a newline '\n' else it won't work (depending on the OS). Here's a small program to demonstrate how you can do it.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
size_t len = 4;
float *buf = malloc(len * sizeof *buf);

if(buf == NULL) { // check for NULL
printf("Not enough memory to allocate.\n");
return 1;
}

size_t i = 0;
float *temp; // to save buf in case realloc fails

// read until EOF or matching failure occurs
// signal the end of input(EOF) by pressing Ctrl+D on *nix
// and Ctrl+Z on Windows systems

while(scanf("%f", buf+i) == 1) {
i++;
if(i == len) { // buf is full
temp = buf;
len *= 2;
buf = realloc(buf, len * sizeof *buf); // reallocate buf
if(buf == NULL) {
printf("Not enough memory to reallocate.\n");
buf = temp;
break;
}
}
}

if(i == 0) {
printf("No input read\n");
return 1;
}

// process buf

for(size_t j = 0; j < i; j++) {
printf("%.2f ", buf[j]);
// do stuff with buff[j]
}

free(buf);
buf = NULL;

return 0;
}

How do I declare an array of undefined or no initial size?

This can be done by using a pointer, and allocating memory on the heap using malloc.
Note that there is no way to later ask how big that memory block is. You have to keep track of the array size yourself.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv)
{
/* declare a pointer do an integer */
int *data;
/* we also have to keep track of how big our array is - I use 50 as an example*/
const int datacount = 50;
data = malloc(sizeof(int) * datacount); /* allocate memory for 50 int's */
if (!data) { /* If data == 0 after the call to malloc, allocation failed for some reason */
perror("Error allocating memory");
abort();
}
/* at this point, we know that data points to a valid block of memory.
Remember, however, that this memory is not initialized in any way -- it contains garbage.
Let's start by clearing it. */
memset(data, 0, sizeof(int)*datacount);
/* now our array contains all zeroes. */
data[0] = 1;
data[2] = 15;
data[49] = 66; /* the last element in our array, since we start counting from 0 */
/* Loop through the array, printing out the values (mostly zeroes, but even so) */
for(int i = 0; i < datacount; ++i) {
printf("Element %d: %d\n", i, data[i]);
}
}

That's it. What follows is a more involved explanation of why this works :)

I don't know how well you know C pointers, but array access in C (like array[2]) is actually a shorthand for accessing memory via a pointer. To access the memory pointed to by data, you write *data. This is known as dereferencing the pointer. Since data is of type int *, then *data is of type int. Now to an important piece of information: (data + 2) means "add the byte size of 2 ints to the adress pointed to by data".

An array in C is just a sequence of values in adjacent memory. array[1] is just next to array[0]. So when we allocate a big block of memory and want to use it as an array, we need an easy way of getting the direct adress to every element inside. Luckily, C lets us use the array notation on pointers as well. data[0] means the same thing as *(data+0), namely "access the memory pointed to by data". data[2] means *(data+2), and accesses the third int in the memory block.

Is there any way to create an array until user enters a specific number?

This worked for me.

#include<stdio.h>
#include<stdlib.h>
int main()
{
int *ptr,n;
ptr = (int *)malloc(sizeof(int)); //
int i = 0;
while(1)
{
puts("Enter a number");
scanf(" %d",&n);// Take the value
if(n == -5) //
{
*(ptr + i) = n; //if you don't wish to add -5 to your array remove this
// statement and following i++
i++;
break;
}
else
{
*(ptr + i) = n;
ptr = realloc(ptr,(i+2)*sizeof(int));// reallocating memory and
// passing the new pointer as location in memory can
// change during reallocation.
i++;
}
}
int end = i;// Saving the number of elements.
for(i=0;i<end;i++)
printf(" %d\n",ptr[i]);
return 0;
}


Related Topics



Leave a reply



Submit