Enter Array Without Knowing Its Size

Enter array without knowing its size

Is there a way to make an array in java, without defining or asking for it's length first ? A.k.a the user enters some numbers as arguments, and the program creates an array with that many arguments.

It's unclear exactly what situation you're in. If you know the array length at execution time but not at compile time, that's fine:

public class Test {
public static void main(String[] args) {
int length = Integer.parseInt(args[0]);
String[] array = new String[length];
System.out.println("Created an array of length: " + array.length);
}
}

You can run that as:

java Test 5

and it will create an array of length 5.

If you really don't know the length of the array before you need to create it - for example, if you're going to ask the user for elements, and then get them to enter some special value when they're done, then you would probably want to use a List of some kind, such as ArrayList.

For example:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Test {
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);

System.out.println("Enter numbers, with 0 to end");
List<Integer> list = new ArrayList<>();
while (true) {
int input = scanner.nextInt();
if (input == 0) {
break;
}
list.add(input);
}
System.out.println("You entered: " + list);
}
}

You can then convert that List into an array if you really need to, but ideally you can just keep using it as a List.

How to create an array without knowing the size in c language

You can create a dynamic array by following the answer to this question. It uses a structure that contains the array, its max size and its used size. If the max size is reached, the array will be reallocated and the max size increased.

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.

How to input elements in an array WITHOUT inputting n? (c++)

The standard input filter loop in C++ is while(cin >> a) - this will read until there is no more input, or other bad things happen:

#include <vector>
#include <iterator>
#include <iostream>
int main() {
std::vector<int> nums;
while (std::cin >> a) {
nums.push_back(a);
}
std::copy(nums.begin(), nums.end(), ostream_iterator<int>{cout, " "});
}

You could also use a one liner with input iterators - the shortest way to read elements in a vector:

#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>

int main() {
std::vector<int> nums(std::istream_iterator<int>(std::cin), {});
std::copy(nums.begin(), nums.end(), std::ostream_iterator<int>{std::cout, " "});
}

See Ideone example here

Assuming however that you wish to ignore all this C++ awesomeness, strongly discouraged IMHO, you can just:

#include <iostream>
int main() {
const int MAX_SIZE = 100;
int nums[MAX_SIZE];
int a;
int i=0;
while (std::cin >> a) {
nums[i++] = a;
}

// do your output
}

Note that you will:

  1. need to guess the MAX_SIZE,
  2. or manually handle reallocation once you read more elements than MAX_SIZE;

Hence: use an std::vector!!

How to allow user input for an array without initial size?

Yes, you can use realloc() for this. A common approach to this is to create a struct, that will represent you array, that can be expandable. The struct can look like this:

typedef struct
{
int allocated; // Here you can save how many elements you have allocated space for
int used; // Here is how many elements are in the array
int * array; // here is pointer to the array

} Array;

Then you should create a function, that will initialize this Array structure:

void initArray(Array * a)
{
a->allocated = INIT_SIZE;
a->used = 0;
a->array = malloc(INIT_SIZE * sizeof(int));
}

Now the array is initialized, you have allocated memory for INIT_SIZE elements. Now the most important part - actually adding elements. You can also create a function for this:

bool insertEl(Array * a, int el)
{
if(a->used == a->allocated) //If there is no more space, then we need to realloc
{
int * temp = realloc(a->array, 2 * a->allocated * sizeof(int));
if(!temp) // Just check if realloc succeeded
{
printf("Reallocation failed!\n");
return false;
}
a->array = temp;
a->allocated *= 2;
}

a->array[a->used] = el;
a->used++;

return true;
}

As reallocation is pretty expensive operation, it's good idea increase the number of allocated elements more than just some constant. I usually double the space. Since you used malloc() and realloc() to allocate the memory, you should free() it once you're done with it:

void freeArray(Array * a)
{
free(a->array);
a->array = NULL;
a->allocated = 0;
a-> used = 0;
}

Once you have an Array structure like this, you can the run scanf() in cycle until there's an EOF, and in each cycle, you scanf() the input and use insertEl() function to add it to the array.

How do I declare an array without knowing its size? C++

You can use a std::vector, which is a variable-length collection to which you can add elements. It manages reallocation automatically when needed. For example:

std::vector<int> values;
values.push_back(0);
values.push_back(1);
...

how to iterate through an array without knowing the size in c

In C, there is no way to tell the number of elements in an array from a pointer to an element. sizeof(array) / sizeof(*array) only works for an actual array, not for a pointer, which is what a function receives as an argument, even if the array syntax is used in the function prototype. In this case sizeof(array) evaluates to the size of the pointer, so dividing that by the size of an element is meaningless.

The best approach for your function to get the number of elements is to provide it as a separate argument.

If this is not practical, there are different ways to infer the number of elements, relying on a convention that must be adhered to by the callers:

  • the array could have a known fixed number of elements

  • the array could have a sentinel value as the last element of the array.

    It is common to use a null pointer (NULL) as such a sentinel for arrays of pointers, such as the char *argv[] argument of the main() function, but note that int argc is also provided to this function.

    The null byte (\0) is used to tell the end of C strings, which are arrays of char.

    In your case, you could consider 0 or -1 to signify the end of the array, but this convention must be used consistently by all callers of your function.

How can I initialize an array without knowing its size?

You can't... an array's size is always fixed in Java. Typically instead of using an array, you'd use an implementation of List<T> here - usually ArrayList<T>, but with plenty of other alternatives available.

You can create an array from the list as a final step, of course - or just change the signature of the method to return a List<T> to start with.

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;
}


Related Topics



Leave a reply



Submit