0

Here is how I defined and assigned a string array at the same time

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

int main()
{
    string word = get_string("Enter a Word;");

    for(int i = 0; i<strlen(word); i++)
    {
        printf("%c\n",word[i]);
    }
}

Now I want to apply the same technique for taking integer values from user

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

int main()
{
    int scores[] = get_int("Enter score:");
    int len = sizeof(scores)/sizeof(int);

    for(int i = 0; i<len; i++)
    {
        printf("%i\n", scores[i]);
    }
}

But the code doesn't get compiled and compiler says like this:

IntArray.c:5:9: error: array initializer must be an initializer list or wide string literal
    int scores[] = get_int("Enter integer:");
        ^
1 error generated.
make: *** [<builtin>: IntArray] Error 1

I know we have a for loop for that solution, which goes like this: That's why I have to keep using for loop, which looks like this:

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

int main()
{
    int scores[3];

    for(int I = 0; I<3; I++)
    {
        score[I] = get_int("Enter score: ");
    }

    for(int j =0; j<3; j++)
    {
        printf("%I\n", scores[j]);
    }
}

My question is can I define and assign the integer array at the same time?

I tried to define and assign an integer array at the same time as we do with the single string, but I couldn't.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
Coderey123
  • 11
  • 3
  • 1
    No it's not possible or allowed. Arrays need a fixed size, and it needs an actual array initializer. – Some programmer dude Jan 13 '23 at 03:25
  • By the way, your array-size calculation is wrong. It's generally "size of array divided by the size of a single array element". – Some programmer dude Jan 13 '23 at 03:26
  • 3
    You can do this with *dynamically allocated* arrays, but not with fixed types. `get_string()` returns `char*` which is (hopefully) dynamically allocated. Keep that in mind. `string` is not a thing in C like it is in Java despite what CS50 stubbornly insists. – tadman Jan 13 '23 at 03:30
  • 2
    Oh and [*variable-length arrays*](https://en.wikipedia.org/wiki/Variable-length_array) can't be initialized at all. For them you must use a loop to assign to each and every element. – Some programmer dude Jan 13 '23 at 03:32
  • 2
    Technically you can write `int scores[3] = { get_int("Enter score:"), get_int("Enter score:"), get_int("Enter score:") };` but that is not very amenable to adding functionality – M.M Jan 13 '23 at 03:33
  • As another part of the problem with the integer array, how would the compiler even know how many times to call `get_int`? – Some programmer dude Jan 13 '23 at 03:33
  • @some programmer dude thank's for pointing out my mistake. I corrected it. – Coderey123 Jan 13 '23 at 03:35
  • yeah , so I am trying to create a array box only after user put a eligible variable which I can store in an array( I like to refer indexes as array box) – Coderey123 Jan 13 '23 at 03:37
  • @tadman what really is dynamically allocated arrays? – Coderey123 Jan 13 '23 at 03:39
  • The purpose of **bold** formatting is to add emphasis. When you use it for every single sentence in your post, it defeats the entire purpose of using it at all. I've removed it, because it's unnecessary. – Ken White Jan 13 '23 at 03:39
  • Have you explored the difference between automatic (stack) allocation, and dynamic (heap) allocation? This is a very important thing to understand when working with a fairly low-level language like C. It's not called "fancy assembly" for nothing. – tadman Jan 13 '23 at 03:50
  • The problem here is the CS50 helper-function `get_int`, because it doesn't handle end of input gracefully. That means you can't call it in a loop until the user wants to end the input. You either have to ask the user "Do you want to enter another number?" and handle that, or decide that some specific value (like zero or a negative number) means end of input, and use that as the loop terminating condition. The first way adds extra code and complexity, the second means you loose one or more value that could otherwise be valid. – Some programmer dude Jan 13 '23 at 03:51
  • Or, of course, make the program only read a fixed number of inputs. – Some programmer dude Jan 13 '23 at 03:58
  • After watching [week 4 of CS50](https://cs50.harvard.edu/x/2023/weeks/4/), it may be easier for you to understand why you can't solve the problem by doing something similar as in your first code snippet. In that lesson, you will learn that a variable of type `string` is not an array, but rather a pointer (i.e. a reference) to an array. – Andreas Wenzel Jan 13 '23 at 04:24
  • you could definitely write a function, say, `get_ints` that loads a dynamic array and returns a pointer to it. – pm100 Jan 13 '23 at 04:35
  • CS50 is the source of all your problems, not teaching you proper practices but hiding fundamental language knowledge underneath the carpet. Get rid of CS50 and avoid programming classes from Harvard. There are countless of better programming classes out there. – Lundin Jan 13 '23 at 09:11
  • @Lundin: I disagree with your recommendation to throw away CS50. I strongly recommend it. The only problem is that OP is trying to do too much before [week 4 of CS50](https://cs50.harvard.edu/x/2023/weeks/4/), in which they learn what pointers are. In that lesson, they learn the true nature of what the data type `string` is. – Andreas Wenzel Jan 13 '23 at 14:23
  • In fact any programming class which tries to mystify or obscure pointers is harmful. They should be taught as just being plain numbers/addresses, even if that's a simplification. If pointers are treated as mysterious entities, then beginners will get confused. – Lundin Jan 13 '23 at 14:44
  • 1
    @Someprogrammerdude *Oh and variable-length arrays can't be initialized at all.* [C23 to the rescue](https://www.iso-9899.info/n3047.html#6.7.10): "An entity of variable length array type shall not be initialized except by an empty initializer." (Yeah, I'm slow...) – Andrew Henle Jan 14 '23 at 01:53

3 Answers3

1

Can I define and assign an integer array at the same time like we do with the string array?

string word is not an array. That object is of a CS50 type string, which is a pointer, that points to an array of char.
Arrays are not pointers.
Pointers are not arrays.

Code can create similar code to define an int pointer ...

// string word = get_string("Enter a Word;");
int *ints = get_ints("Enter ints;");

... and use a special value, like INT_MIN, to denote the end of the array of ints. Of course then INT_MIN is not available as a value to read. This is analogous to C strings, which uses a special value, the null character to signify the end of the array.


My question is can I define and assign the integer array at the same time?

Yes.

See @M.M comment.

int scores[] = { get_int("Enter score:"), get_int("Enter score:"), get_int("Enter score:") };

This obliges that the array size is determined before getting the data.


Code could read the ints into some collection of data, then use the int count to define a variable length array (VLA). But VLAs may not be initialized. They could be assigned later.

some_tbd_data_collection_type data = 0;
unsigned n = get_ints(&data);
int a[n];
for (unsigned i = 0; i < n; i++) {
  a[i] = get_int(&data, i);
}
data_free(&data); 
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

Building on this earlier answer. The function read_ints reads integers until it reads end_of_list, after which it returns.

void read_ints(Array *a, int end_of_list)
{
    int current;
    while(1){
        scanf("%d",&current);
        if(current == end_of_list) return;
        insertArray(a,current);
    }
}
int main()
{
    Array a;
    initArray(&a, 5);
    printf("Enter numbers:");
    read_ints(&a,-1);

    for(int i=0; i<a.used; i++) printf("%d ", a.array[i]);
    return 0;
}
afarrag
  • 344
  • 1
  • 2
  • 11
0

Here is how I defined and assigned a string array at the same time

This statement is incorrect. In the line

string word = get_string("Enter a Word;");

the variable word is not an array. In particular, the data type string is not an array, but rather a reference ("a pointer") to an array. You will learn this in week 4 of CS50.

What really happens is that the function get_string creates an array based on user input and returns a reference to this newly created array. You then store this reference in the variable word. So you are creating a copy of the reference, not a copy of the array itself.

Here is an example program for demonstration purposes:

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

int main( void )
{
    string word1 = get_string( "Enter a word: " );
    string word2 = word1;
    word2[0] = 'J';

    printf( "\nContent of strings:\n" );
    printf( "word1: %s\n", word1 );
    printf( "word2: %s\n", word2 );
}

In the program above, if the user enters Test, then the line

string word2 = word1;

will not make a copy of the array containing the characters Test, but merely make a copy of the reference to the array. Afterwards, you will have two variables referencing the same array.

If you then modify the first character of the array using

word2[0] = 'J';

you will be modifying the array referenced by word1 and word2. Therefore, the lines

printf( "word1: %s\n", word1 );
printf( "word2: %s\n", word2 );

will not output the original input Test, but will both output Jest.

For this reason, half of your question does not make sense, because initializing an array cannot be compared with initializing a reference ("a pointer") to an array.

My question is can I define and assign the integer array at the same time?

The line

int scores[] = get_int("Enter score:");

will not work.

On the other hand,

int scores[] = { get_int("Enter score:") };

will work, but this is probably not what you want, because it will only create an array of size 1 and calling the function get_int will only ask the user for a single int.

If you want to ask the user for several int values, then you will have to call the function get_int multiple times, for example like this:

int scores[] = {
    get_int( "Enter first score: "),
    get_int( "Enter second score: "),
    get_int( "Enter third score: ")
};

However, this solution is not ideal, especially if you later want to change your program to have more than 3 inputs. Therefore, not initializing the array in the declaration and using a loop instead (as you do in your last code snippet) would probably be the better solution.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39