Storing one value for each item in 2-Dimensional array - c

Luckily I came up with a decent title, describing what I was curious about.
While this is really hard for me to explain, I am doing my best.
I tried, storing values in 3D array as such:
char arr[10][10][1];
To copy a string I have to do it in arr[y][x], (And I sadly I can't in just arr[y])but then, because of a reason still unknown for me, I could overflow the buffer with arr[8][8][8]. Maybe because of the size of char** but anyway.
I couldn't find a slot to store a character for each item (x and y)
I tried, it the other way:
char arr[1][10][10];
Assuming that I have 1 item * x and y.
To store a string, I have to do it in arr[0][y], which means the 3rd cell will be a character from the string.
So as a resume, I am trying to store one value for each character in x and y.
Do I really need 4D array for this?
Additional clarification:
I am aware what 1D and 2D arrays are for. Seems I can't understand the 3D array.
I thought that I can store an additional item for each character at y or x.
Example:
char arr[y][x][z];
Where y is the line, x is the column and z is the additional item that applies to all the characters.

A string is an array of characters. An array of strings is therefore an array of arrays of characters. Why you think you need the 3rd dimension, I have no idea.
When you allocate a multi-dimensional array statically, you must specify the maximum number of items that it can contain. In this case, you must specify how many bytes long the string is allowed to be, including one byte for null termination. This is the right-most [] in the expression, in your case 1 byte.
So you haven't actually allocated any memory at all to store a string: 1 byte is enough to store the null termination and nothing else. This is why you get a crash/seg fault when you attempt [x][y][z] when z is any other value than 0. And you cannot store anything meaningful there either.
Size of char** has absolutely nothing to do with this whatsoever. Pointers are not arrays.
I'd strongly suggest that your study this C FAQ about pointers and arrays.
Now what you probably want to do is something like this:
char string_array [10][20+1]; // 10 strings each containing 20 letters + null
strcpy(string_array[0], "hello");
strcpy(string_array[1], "world");
...
printf("%s\n", string_array[0]);
printf("%s\n", string_array[1]);
...

No need for the 3rd dimension as such .
you can use for example a[x][y];
and you can access this using *a[];
As you can also see that while using command line arguments where 2D array *argv[] is used to store a number of strings from command line. It explains you the best how 2D arrays are used.
For further reference you can have a look at this http://www.tutorialspoint.com/cprogramming/c_multi_dimensional_arrays.htm

Related

Is it good practise to include an index for an array in C?

I have an array in C that stores strings, and I need to be able to dynamically append to this array. Is it good practise to store the index of this array in a separate variable, or is there some better way to do this? Here's my code.
First defining these variables
char x[10][10];
int x_index = 0;
Adding strings to this array
strcpy(x[x_index], "hello");
x_index += 1;
strcpy(x[x_index], "world");
x_index += 1;
You should call the index the length of the array, because what it is: It is the number of valid entries in the array. There are other entries, but they shouldn't be accessed.
It is not only good practice, but in the most cases necessary to keep track of the current size. Otherwise, how would you know ehere to append the next item? In C, this must be done with an extra variable. (Make sure that you can see that array and length belong together with a consistent nomenclature.)
Make sure that the length doesn't exceed the size of the array, 10 in your example. Often, you have to track both, the length and the size, where the size can be a compile-time constant
if (xlen < XSIZE) strcpy(x[xlen++], str);
(You must also take care not to overflow the 10-character buffer, of course.)
For arrays in which you need to parse every element anyways (and only parse, with no insertion), it is better to put a special value at the end of the array, such as '\0' in char arrays in order to tell the parsing loop when to stop.

How can we iterate through an array of integers when we do not know the size of the array? [duplicate]

This question already has answers here:
How do I determine the size of my array in C?
(24 answers)
Closed 5 years ago.
This is a code from geeksforgeeks counting sort implementation:
The have used the below for loop to iterate through a string -
char arr[] = "geeksforgeeks";
for(i = 0; arr[i]; ++i)
++count[arr[i]];
From google search I could understand that this condition implicitly evaluates to arr[i]!='\0'. Have I understood it correctly ?
If I were to use a similar for loop to iterate through an array of integers, would it evaluate to arr[i]!=0 ?
Or is there any better way to iterate through an array of integers when we do not know its size. I am a beginner and please try to provide suggestions which do not involve advanced data structures in C.
Unless you know for sure that there is some sort of sentinel value at the end of the array, you cannot iterate over an array unless you know its size.
An example of a sentinel value is '\0' in the case of strings.
When you want to work with integer arrays you should keep around both the array and the size. This is why functions that take arrays as input parameters take a pointer and an int:
void example(int* array, int size) { /* ... */ }
Yes, an integer expression that evaluates to zero will be considered false by the for construct and end the loop.
Since strings are terminated by a '\0' character with the value 0, this works to detect the end of the string.
Yes, you can use this to iterate over an array of any integer (or pointer, where NULL is considered false) array, but of course terminating such arrays with zero is less common (since zero is a rather useful integer).
If you can use some other value to mark the end (this is called a "sentinel") you can course use that, rather than the length or zero. There's nothing magical about zero, except that for strings it's the convention and thus well supported.

Number sequences length, element first and last indexes in array

Im beginner in programming. My question is how to count number sequences in input array? For example:
input array = [0,0,1,1,1,1,1,1,0,1,0,1,1,1]
output integer = 3 (count one-sequences)
And how to calculate number sequences first and last indexes in input array? For example:
input array = [0,0,1,1,1,1,1,1,0,1,0,1,1,1]
output array = [3-8,10-10,12-14] (one first and last place in a sequence)
I tried to solve this problem in C with arrays. Thank you!
Your task is a good exercise to familiarize you with the 0-based array indexes used in C, iterating arrays, and adjusting the array indexes to 1-based when the output requires.
Taking the first two together, 0-based arrays in C, and iterating over the elements, you must first determine how many elements are in your array. This is something that gives new C programmers trouble. The reason being is for general arrays (as opposed to null-terminated strings), you must either know the number of elements in the array, or determine the number of elements within the scope where the array was declared.
What does that mean? It means, the only time you can use the sizeof operator to determine the size of an array is inside the same scope (i.e. inside the same block of code {...} where the array is declared. If the array is passed to a function, the parameter passing the array is converted (you may see it referred to as decays) to a pointer. When that occurs, the sizeof operator simply returns the size of a pointer (generally 8-bytes on x86_64 and 4-bytes on x86), not the size of the array.
So now you know the first part of your task. (1) declare the array; and (2) save the size of the array to use in iterating over the elements. The first you can do with int array[] = {0,0,1,1,1,1,1,1,0,1,0,1,1,1}; and the second with sizeof array;
Your next job is to iterate over each element in the array and test whether it is '0' or '1' and respond appropriately. To iterate over each element in the array (as opposed to a string), you will typically use a for loop coupled with an index variable ( 'i' below) that will allow you to access each element of the array. You may have something similar to:
size_t i = 0;
...
for (i = 0; i< sizeof array; i++) {
... /* elements accessed as array[i] */
}
(note: you are free to use int as the type for 'i' as well, but for your choice of type, you generally want to ask can 'i' ever be negative here? If not, a choice of a type that handles only positive number will help the compiler warn if you are misusing the variable later in your code)
To build the complete logic you will need to test for all changes from '0' to '1' you may have to use nested if ... else ... statements. (You may have to check if you are dealing with array[0] specifically as part of your test logic) You have 2 tasks here. (1) determine if the last element was '0' and the current element '1', then update your sequence_count++; and (2) test if the current element is '1', then store the adjusted index in a second array and update the count or index for the second array so you can keep track of where to store the next adjusted index value. I will let you work on the test logic and will help if you get stuck.
Finally, you need only print out your final sequence_count and then iterate over your second array (where you stored the adjusted index values for each time array was '1'.
This will get you started. Edit your question and add your current code when you get stuck and people can help further.

Context-free grammar in C

I have an assignment to make a program in C that displays a number (n < 50) of valid, context-free grammar strings using the following context-free grammar:
S -> AA|0
A -> SS|1
I had few concepts of how to do it, but after analyzing them more and more, none of them were right.
For now, I'm planning to make an array and randomly change [..., A, ...] for [..., S, S, ...] or [..., 1, ...] until there are only 0s and 1s and then check whether the same thing was already randomly generated.
I'm still not convinced if that is the right approach, and I still don't know exactly how to do that or where to keep the final words because the basic form will be an array of chars of different length. Also, in C, is a two dimensional array of chars equal to an array of strings?
Does this make any sense, and is it a proper way to do it? Or am I missing something?
You can simply make a random decision every time you need to decide on something. For example:
function A():
if (50% random chance)
return "1"
else
return concat(S(), S())
function S():
if (50% random chance)
return "0"
else
return concat(A(), A())
Calling S() multiple times give me these outputs:
"0"
"00110110100100101111010111111111001111101011100100011000000110101110000110101110
10001000110001111100011000101011000001101111000110110011101010111111111011010011
10000000101111100100011011010000000101000111110010001000101001100110100111111111
1001010011"
"11"
"10010010101111010111101"
All valid strings for your grammar. Note that you may need to tweak a little the random chances. This sample has a high probability to generate very small strings like "11".
Try to think of the context-free grammar as a set of rules that allow you to generate new strings in a language. For example, the first rule:
S -> AA | 0
How could you generate a word S in this language? One way is with a function that generates, at random, either the string "0" or two A words, concatenated.
Similarly, to implement the second rule:
A -> SS | 1
write a function that generates, at random, either "1" or two S words concatenated.
You asked several questions...
Regarding The question: BTW in C, is two dimensional array of chars equal to array of strings?
Yes.
Here are ways to declare arrays of strings, each example shows varying flexibility in terms of usage:
char **ArrayOfStrings; //most flexible declaration -
//pointer to pointer, can use `calloc()` or `malloc()` to create memory for
//any number of strings of any length (all strings will have same length)
or
char *ArrayOfStrings[10]; //somewhat flexible -
//pointer to array of 10 strings, again can use `c(m)alloc()` to allocate memory for
//each string to have any lenth (all strings will have same length)
or
ArrayOfStrings[5][10]; //Not flexible - (but still very useful)
//2 dimensional array of 5 strings, each with space for up to 9 chars + '\0'
//Note: In C, by definition, strings must always be NULL terminated.
Note: Although each of these forms are valid, and very useful when used correctly, It is good to be aware there are differences in the way each will behave in practice. (read the link for a good discussion on that)

An array of length 4-20?

I'd like for my array to be of a set length using a simple format. Please, let me know how this is done.
What I already have:
arr[100]
Pseudocode: what I would like to have:
arr[4-20] or arr[$min_int THROUGH $max_int]
Additional detail edit: The int should be within the range array = (4, 20). The input may contain leading zeros. I'd like to keep the length of the array restricted (i.e., to 9 or 10 characters).
Arrays simply do not work this way in C. You will need to implement it yourself by only looping through valid indices (and wasting memory in the process) or by using a data structure better suited to the job, like a map (which you will have to find in a library or write yourself as it does not exist in the language).
#define ARRMINIDX 4
#define ARRMAXIDX 20
int arrmem[ARRMAXIDX+1-ARRMINIDX];
#define arr(x) arrmem[ARRMINIDX+(x)]
// process elements of arr
for( i = ARRMINIDX; i <= ARRMAXIDX; i++ )
dosomething(arr(i));
OTOH, this make not be what you want at all, given your comment
I want an array with 0-1 elements: a limited int or limited "numeric
int"--string mimicking an int.
which I can't make heads or tails of in this context. Are you saying that you want a string of 4-20 chars that represents an integer?

Resources