Length of array of strings - c

How can we determine the length of an array of strings when we don't know the length?
For example in this piece of code:
#include <stdio.h>
int main() {
int n;
char names[3][10] = { “Alex”, “Phillip”, “Collins” };
for (n = 0; n < 3; n++)
printf(“%s \n”, names[n]);
}
n < 3 is assuming you know the length of the array but how can you determine it's length when we don't know?
I have tried a few alternatives such as:
int arraySize() {
size_t size, i = 0;
int count = 0;
char names[3][10] = { “Alex”, “Phillip”, “Collins” };
size = sizeof(names) / sizeof(char*);
for (i = 0; i < size; i++) {
printf("%d - %s\n", count + 1, *(names + i));
count++;
}
printf("\n");
printf("The number of strings found are %d\n", count);
return 0;
}
or
for (n = 0; n < sizeof(names); n++)
but they all error out.
Any help is appreciated.

I am not sure what you mean by they all err out.
There is a syntax issue in the code posted as you use guillemet characters instead of double quotes: “Alex” should be "Alex". This could be a side effect of your cut/paste method to post the code, but nevertheless a potential issue.
Your approach using size = sizeof(names) / sizeof(char*); is right but the type is incorrect: names[0] is not a char *, it is an array of 10 characters. You should use size = sizeof(names) / sizeof(names[0]); which works for all arrays, regardless of the type.
Here is a modified version where the length of the array is determined by the compiler:
#include <stdio.h>
int main() {
char names[][10] = { "Alex", "Phillip", "Collins" };
int i, length = sizeof(names) / sizeof(names[0]);
for (i = 0; i < length; i++)
printf("%d: %s\n", i + 1, names[i]);
return 0;
}
Notes:
you could use size_t instead of int for array length and index variables, but it is only necessary for very large arrays and the printf conversion specifier would be %zu for a value of type size_t.
it is less confusing to use length for the length of an array and reserve size for sizes in bytes obtained from sizeof().

first every string is ended with a special character '\0'
means
{'A','L','E','X','\0'}
even you haven't put '\0' there but compiler put it there for it convenient
int lenght(char *str){
int count = 0 ;
for(int i=0;str[i]!='\0';i++){
count++ ;
}
return count ;
}
use this function to count your string length
like :
int main(){
char names[3][10] = {"Alex", "Phillip", "Collins"};
printf(“%d \n”,lenght(names[1] );
return 0 ;
}

Related

Find the difference between elements in an array and store the results in a new array

This is my current code:
#include <stdio.h>
int index_x[] = {0,0,1,0,1,0,0,0,1,0,0,1,0}; // any number of elements
int len = sizeof index_x / sizeof*index_x;
int main(void) {
int arr[len];
int j = 0;
for (int i = 0; i < len; i++)
if (index_x[i])
arr[j++] = i; // save and advance j only if value is "1"
for (int i = 0; i < j; i++) // only print below j !
printf("%d\n", arr[i]);
}
Output:
2
4
8
11
From this output, I would like to generate another array that is the difference between these elements. In this case the new array would be {2,4,3}. (2-4=2, 8-4=4, 11-8=3).
I am currently struggling with two things:
Saving the array generated from the current code arr[i] as a another array so I can manipulate it for future uses.
Generating the "differences array". The tricky part is that the number of elements will not be constant so I cannot specify an array size.
It may be helpful to break things out into functions.
int indexes_of_non_zero(int *source, size_t len, int **dest) {
*dest = malloc(sizeof(int) * len);
int count = 0;
for (int i = 0; i < len; i++) {
if (source[i] != 0) {
(*dest)[count++] = i;
}
}
*dest = realloc(*dest, sizeof(int) * count);
return count;
}
So we have a function indexes_of_non_zero that takes a source array of ints with size specified by argument len, and then a pointer to an array of ints that will be the destination for our output.
We can naively allocate the same amount of memory to the destination, then loop over the source array and store the indexes of non-zero elements. When we're done, we use count to know the size of destination array. We use realloc to shrink the array to just the needed size. And the key is we return the count so our main function knows how big the destination array is.
We can now create a diffs function to do basically the same thing for the differences.
int diffs(int *source, size_t len, int **dest) {
*dest = malloc(sizeof(int) * (len - 1));
for (int i = 0; i < (len - 1); i++) {
(*dest)[i] = abs(source[i] - source[i + 1]);
}
return len - 1;
}
Putting it all together (not copying and pasting the function implementations for terseness) with a main function, and remembering to free the memory we've used, we get:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int indexes_of_non_zero(int *source, size_t len, int **dest);
int diffs(int *source, size_t len, int **dest);
int main(void) {
int data[] = {0,0,1,0,1,0,0,0,1,0,0,1,0};
size_t len = sizeof(data) / sizeof(*data);
int *nz = NULL;
int *d = NULL;
int nzc = indexes_of_non_zero(data, len, &nz);
int dlen = diffs(nz, nzc, &d);
for (int i = 0; i < nzc; i++) {
printf("%d\n", nz[i]);
}
for (int i = 0; i < dlen; i++) {
printf("%d\n", d[i]);
}
free(nz);
free(d);
}
And compiling and running it, the output is:
2
4
8
11
2
4
3
I changed it to get the differences as direct as possible; the inner loop is very simple.
The size question, first part: I (still) tried to avoid size_t for the input but added some sanity check for the size. Just to show there is a limit.
part two: a first loop to get the sum of true values in advance. Also the booldata array consists of chars and is not called index_x. Index is i.
part three: the diffs VLA gets its exact size, which can be 0 even for huge inputs. Some test could be added here after counting, to rule out a (big) input full of "1".
I added the copying, with message and printout.
#include <stdio.h>
#include <string.h>
char booldata[] = { 0,0,1,0,1,0,0,0,1,0,0,1,0 };
char sz_overf = sizeof booldata > 0xffffL * 0xffff; // too-big-flag for exiting...
int len = sizeof booldata / sizeof * booldata; // ...to keep len below size_t
int sum_of_trues (char *booldata, int len) {
int sum = 0;
for (int i = 0; i < len; i++)
if (booldata[i])
sum++;
return sum;
}
void print_intarr(int *inta, int len) {
for (int i = 0; i < len; i++)
printf("%d\n", inta[i]);
}
int main(void)
{
if (sz_overf) return 100; // len might be overflowed
int unsigned // signed provokes VLA warning: 9 gazillions seems ok, but not 18
dsum = sum_of_trues(booldata, len) - 1; // Invest a counting loop
int diffs[dsum], // VLA
di = 0; // diffs' index
int sti = -1; // Stored last index containing true
for (int i = 0; i < len; i++)
if (booldata[i]) { // true?
if (sti >= 0) { // and is there a left neighbour?
int diff = i - sti; // how far away?
printf("%d\n", diff); // 1. on-the-fly result
diffs[di++] = diff; // 2. for keeps
}
sti = i; // remember last "true"
}
printf("Copying %zu bytes from Diff.-Array\n", sizeof diffs);
int diffscopy[sizeof diffs];
memcpy(diffscopy, diffs, sizeof diffs);
print_intarr(diffscopy, dsum); // dsum or sizeof diffs
return 0;
}
output:
2
4
3
Copying 12 bytes from Diff.-Array
2
4
3
The inner loop could look like this w/o multi-option:
if (booldata[i]) {
if (sti >= 0) // and is there a left neighbour?
diffs[di++] = i - st; // 2. for keeps
sti = i;
}
Two arrays and three variables. The rest is needed to make this work.
BUGS: all-false input segfaults. It takes one "true" to get zero diffs...

Why does sizeof() not return the length of an array?

#include <stdio.h>
int main() {
int test[3];
int i;
test[0]=5;
test[1]=10;
test[2]=7;
printf("array size: %d\n",sizeof(test));
sortArray(test);
for(i=0;i<sizeof(test);i++) {
printf(" %d ", test[i]);
}
printf("\n");
}
void sortArray(int number[]) {
int i,j,a;
int n = 5;
for (i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
if (number[j] < number[i]) {
a = number[i];
number[i] = number[j];
number[j] = a;
}
}
}
}
The array I am having problems with is "test"
When I run the program the "size" is always a multiple of 4 of the intended size. ex: test[3] would output a size of 12. What am I doing wrong? I am using code::blocks as an ide also.
sizeof returns the memory size of what you pass it. The return value is...
measured in the number of char-sized storage units required for the
type
In a typical 32-bit system, a char is one byte and int is four bytes so you'll get a multiple of four for an array of type int.
If you'd like the length of the array, just divide by the size of the type:
int a[3];
size_t n = sizeof(a) / sizeof(a[0]);
Note: As dbush mentioned in the comments below:
...this only works if the array is not a paramerer to a
function. In that case the array decays to a pointer and sizeof(array)
evaluates to the size of a pointer.

Remove members from an array of char *

I've written this function to remove count members from arr at index idx.
void remove_int(int (*arr)[], int idx, int count)
{
int i, j;
for (i = 0; i < count; i++)
for (j = idx; (*arr)[j]; j++)
(*arr)[j] = (*arr)[j+1];
}
I call it like this:
remove_int(&arr, index, cnt);
This works perfectly for local integers. Here's my problem. I have a header file like this:
struct {
/* other stuff */
char *array[100];
} global_struct;
Members in array are allocated and filled.
Someone figured I could just switch int to char and int (*arr)[] to char *(*arr)[], then call:
remove_char(&global_struct.array, index, cnt);
I tried it, but it doesn't actually modify global_struct.array. How should I change remove_int to work with global_struct.array?
global_struct.array is a pointer to char, and looks like it is intended to point to a string. So you need to change the function signature to something like:
void remove_strings(char *str[], size_t idx, size_t count);
I would suggest changing idx, count, i, and j to type size_t, as this is an unsigned integer type guaranteed to hold any array index. The size_t type has been available since C99.
Here is a demonstration program that incorporates a modified version of the remove_int() function:
#include <stdio.h>
struct {
char *array[100];
} global_struct;
void remove_strings(char *str[], size_t idx, size_t count);
int main(void)
{
global_struct.array[0] = "One";
global_struct.array[1] = "Two";
global_struct.array[2] = "Three";
global_struct.array[3] = "Four";
global_struct.array[4] = "Five";
global_struct.array[5] = NULL;
for (size_t i = 0; global_struct.array[i]; i++) {
printf("%s\n", global_struct.array[i]);
}
remove_strings(global_struct.array, 2, 2);
putchar('\n');
puts("After removal:");
for (size_t i = 0; global_struct.array[i]; i++) {
printf("%s\n", global_struct.array[i]);
}
return 0;
}
void remove_strings(char *str[], size_t idx, size_t count)
{
size_t i, j;
for (i = 0; i < count; i++)
for (j = idx; str[j]; j++)
str[j] = str[j+1];
}
Program output:
One
Two
Three
Four
Five
After removal:
One
Two
Five
Also, it appears that your function remove_int() only works on arrays of int that exclude 0 members, as 0 is used as a sentinel value in the inner loop of your function. It is common to terminate an array of pointers to char with a NULL pointer, as I have done, and of course a string is an array of chars terminated with a '\0'. But, it is not in general a good idea to terminate an array of ints with a zero. This feature of your code did make it a simple matter to adapt it to work with strings.
While your function may satisfy your current requirements, consider changing it to return the number of ints stored in the array. It makes sense to keep track of the number of ints stored in the array, and passing this value as an argument allows the function to iterate over the array without a sentinel value. Here is a revised version of your function:
size_t remove_ints(size_t idx, size_t count, int arr[], size_t arr_sz)
{
size_t i, j;
for (i = 0; i < count; i++)
for (j = idx; j < arr_sz; j++)
arr[j] = arr[j+1];
return arr_sz - count;
}
The purpose of "for (i = 0; i < count; i++)"?
As my understand I think you should:
void remove_int(int (*arr)[], int idx)
{
int j;
for (j = idx; (*arr)[j]; j++)
(*arr)[j] = (*arr)[j+1];
}

Output mistake in array

int BruteForceStringMatch(char Text[], char Pattern[]){
int TextSize = sizeof(Text) / sizeof(Text[0]); //get size of arrays
int PatternSize = sizeof(Pattern) / sizeof(Pattern[0]);
int i;
for(i = 0; i++; i < TextSize - PatternSize){
int j = 0;
while(j < PatternSize && Pattern[j] == Text[i + j]){
j = j + 1;
}
if(j = PatternSize){
return i;
}
}
return -1;
}
int main() {
char x [] = "if" ;
char y [] = "aslifee";
int c = BruteForceStringMatch(y,x);
printf("%d ",c);
getchar();
}
Hi everyone, I want to match text and pattern by using BruteForceStringMatch function but I get output -1 from computer. Here I should get 3 (because fourth element is matching) but why am I getting -1 which means there is no matching?
Here is what is wrong:
int TextSize = sizeof(Text)/sizeof(Text[0]); //get size of arrays
This does not give you the size of the array, because C passes arrays to functions as if they were pointers. The size of the array is stripped from it, so sizeof returns the size of the pointer.
Use strlen instead:
int TextSize = strlen(Text);
Same goes for the pattern size.
Note: I assume that you are doing this as a learning exercise, because C standard library supplies a function for finding strings within strings.

All Integers have the same value

So I am working on some homework, in which I have to create a global array of 500 random integers between 0 and 99. Then, I have to count how many are greater than 75, and how many are less than 50.
Here is my code:
#include <stdlib.h>
#include <stdio.h>
static int ARRAY[500];
static char str[1];
void main() {
int i = 0;
for (i = 0; i < 500; i++) {
int r = rand() % 99;
ARRAY[i] = r;
}
int gt75 = count75();
int lt50 = count50();
printf("%d\n", str, gt75);
printf("%d\n", str, lt50);
}
int count75() {
int i = 0, counter = 0;
for (i = 0; i < 500; i++) {
int n = ARRAY[i];
if (n > 75) {
counter += 1;
}
}
return counter;
}
int count50() {
int i = 0, counter = 0;
for (i = 0; i < 500; i ++) {
int n = ARRAY[i];
if (n < 50) {
counter += 1;
}
}
return counter;
}
However, after compiling and running my program, I get the following output:
4225008
4225008
This can't be right, as the list should only have 500 elements in the first place. What am I doing wrong?
You have two errors.
First, int r = rand() % 99; should be int r = rand() % 100; Otherwise you just get numbers between 0 and 98.
Second, your printf statements are odd. They should be:
printf("Greater than 75: %d\n", gt75);
printf("Less than 50: %d\n", lt50);
In the current printf statements, the str is cast to an int, which is interpreting the str pointer as an int, thus your strange output.
You're printing a char array with printf using "%d", which is for printing integers. Use "%s" for printing char arrays:
printf("%s\n", str, gt75);
Or, if you're trying to print the value of gt75 as an integer:
printf("%d\n", gt75);
I do not know why you would pass str in this case, though.
When you use "%d", you are telling printf to interpret the input as an int. Since str is actually a char array, it does not output correctly. Instead, you're printing the memory location of str, which is the value of an array.
You are always printing the value of str, which is not an int.

Resources