C: Iterate through an array of strings - c

I'm currently learning C and am struggling with how to iterate through an array of strings.
Let's just say I define an array, like so:
char* argv_custom[] = {"--debug", "--verbose", "--test", "--ultimate"};
Now, how would I go about determining the number of strings within argv_custom? (e.g. argc_custom)
Am I going the right way about this in the first place? Also, is it possible to do something like:
Pseudocode
if ('--debug' in argv_custom) { // do stuff }

Now, how would I go about determining the number of strings within argv_custom?
The canonical way:
int argc_custom = sizeof(argv_custom) / sizeof(argv_custom[0]);
Note: This only works on the array itself, as soon as you have a pointer (such as if you pass argv_custom to a function), it no longer works:
char **p = argv_custom;
int argc_custom = sizeof(p) / sizeof(p[0]); // No me gusta
is it possible to do something like: ...
There's no shortcut. You would have to iterate over each string, and do strcmp. Of course, you could (and probably should) wrap this behaviour into a function.

you can do sizeof(argv_custom)/sizeof(argv_custom[0]). This calculates the total length of the array divided by the size of every single element.

I've had this question quite a few times and from what I've found my favorite solution is to just iterate through the pointer until null. sizeof stops working as soon as you start using functions and passing the arrays around.
Here's a paradigm I've used time and time again in my assignments and it's been really helpful. The exact same thing can be used for getting the length of a cstring or iterating through its characters.
char* argv_custom[] = {"--debug", "--verbose", "--test", "--ultimate"};
char **temp = argv_custom;
int size = 0;
while (*temp) {
++size;
++temp;
}
This is not preferred over using sizeof, however it's an alternative when you want to loop through it.

Related

Why do C command line arguments include argc? [duplicate]

This is well known code to compute array length in C:
sizeof(array)/sizeof(type)
But I can't seem to find out the length of the array passed as an argument to a function:
#include <stdio.h>
int length(const char* array[]) {
return sizeof(array)/sizeof(char*);
}
int main() {
const char* friends[] = { "John", "Jack", "Jim" };
printf("%d %d", sizeof(friends)/sizeof(char*), length(friends)); // 3 1
}
I assume that array is copied by value to the function argument as constant pointer and reference to it should solve this, but this declaration is not valid:
int length(const char**& array);
I find passing the array length as second argument to be redundant information, but why is the standard declaration of main like this:
int main(int argc, char** argv);
Please explain if it is possible to find out the array length in function argument, and if so, why is there the redundancy in main.
sizeof only works to find the length of the array if you apply it to the original array.
int a[5]; //real array. NOT a pointer
sizeof(a); // :)
However, by the time the array decays into a pointer, sizeof will give the size of the pointer and not of the array.
int a[5];
int * p = a;
sizeof(p); // :(
As you have already smartly pointed out main receives the length of the array as an argument (argc). Yes, this is out of necessity and is not redundant. (Well, it is kind of reduntant since argv is conveniently terminated by a null pointer but I digress)
There is some reasoning as to why this would take place. How could we make things so that a C array also knows its length?
A first idea would be not having arrays decaying into pointers when they are passed to a function and continuing to keep the array length in the type system. The bad thing about this is that you would need to have a separate function for every possible array length and doing so is not a good idea. (Pascal did this and some people think this is one of the reasons it "lost" to C)
A second idea is storing the array length next to the array, just like any modern programming language does:
a -> [5];[0,0,0,0,0]
But then you are just creating an invisible struct behind the scenes and the C philosophy does not approve of this kind of overhead. That said, creating such a struct yourself is often a good idea for some sorts of problems:
struct {
size_t length;
int * elements;
}
Another thing you can think about is how strings in C are null terminated instead of storing a length (as in Pascal). To store a length without worrying about limits need a whopping four bytes, an unimaginably expensive amount (at least back then). One could wonder if arrays could be also null terminated like that but then how would you allow the array to store a null?
The array decays to a pointer when passed.
Section 6.4 of the C FAQ covers this very well and provides the K&R references etc.
That aside, imagine it were possible for the function to know the size of the memory allocated in a pointer. You could call the function two or more times, each time with different input arrays that were potentially different lengths; the length would therefore have to be passed in as a secret hidden variable somehow. And then consider if you passed in an offset into another array, or an array allocated on the heap (malloc and all being library functions - something the compiler links to, rather than sees and reasons about the body of).
Its getting difficult to imagine how this might work without some behind-the-scenes slice objects and such right?
Symbian did have a AllocSize() function that returned the size of an allocation with malloc(); this only worked for the literal pointer returned by the malloc, and you'd get gobbledygook or a crash if you asked it to know the size of an invalid pointer or a pointer offset from one.
You don't want to believe its not possible, but it genuinely isn't. The only way to know the length of something passed into a function is to track the length yourself and pass it in yourself as a separate explicit parameter.
As stated by #Will, the decay happens during the parameter passing. One way to get around it is to pass the number of elements. To add onto this, you may find the _countof() macro useful - it does the equivalent of what you've done ;)
First, a better usage to compute number of elements when the actual array declaration is in scope is:
sizeof array / sizeof array[0]
This way you don't repeat the type name, which of course could change in the declaration and make you end up with an incorrect length computation. This is a typical case of don't repeat yourself.
Second, as a minor point, please note that sizeof is not a function, so the expression above doesn't need any parenthesis around the argument to sizeof.
Third, C doesn't have references so your usage of & in a declaration won't work.
I agree that the proper C solution is to pass the length (using the size_t type) as a separate argument, and use sizeof at the place the call is being made if the argument is a "real" array.
Note that often you work with memory returned by e.g. malloc(), and in those cases you never have a "true" array to compute the size off of, so designing the function to use an element count is more flexible.
Regarding int main():
According to the Standard, argv points to a NULL-terminated array (of pointers to null-terminated strings). (5.1.2.2.1:1).
That is, argv = (char **){ argv[0], ..., argv[argc - 1], 0 };.
Hence, size calculation is performed by a function which is a trivial modification of strlen().
argc is only there to make argv length calculation O(1).
The count-until-NULL method will NOT work for generic array input. You will need to manually specify size as a second argument.
This is a old question, and the OP seems to mix C++ and C in his intends/examples. In C, when you pass a array to a function, it's decayed to pointer. So, there is no way to pass the array size except by using a second argument in your function that stores the array size:
void func(int A[])
// should be instead: void func(int * A, const size_t elemCountInA)
They are very few cases, where you don't need this, like when you're using multidimensional arrays:
void func(int A[3][whatever here]) // That's almost as if read "int* A[3]"
Using the array notation in a function signature is still useful, for the developer, as it might be an help to tell how many elements your functions expects. For example:
void vec_add(float out[3], float in0[3], float in1[3])
is easier to understand than this one (although, nothing prevent accessing the 4th element in the function in both functions):
void vec_add(float * out, float * in0, float * in1)
If you were to use C++, then you can actually capture the array size and get what you expect:
template <size_t N>
void vec_add(float (&out)[N], float (&in0)[N], float (&in1)[N])
{
for (size_t i = 0; i < N; i++)
out[i] = in0[i] + in1[i];
}
In that case, the compiler will ensure that you're not adding a 4D vector with a 2D vector (which is not possible in C without passing the dimension of each dimension as arguments of the function). There will be as many instance of the vec_add function as the number of dimensions used for your vectors.
int arsize(int st1[]) {
int i = 0;
for (i; !(st1[i] & (1 << 30)); i++);
return i;
}
This works for me :)
length of an array(type int) with sizeof:
sizeof(array)/sizeof(int)
Best example is here
thanks #define SIZE 10
void size(int arr[SIZE])
{
printf("size of array is:%d\n",sizeof(arr));
}
int main()
{
int arr[SIZE];
size(arr);
return 0;
}

Insertion Sort of an array of strings in C

For one of my assignments I have to have a user input a list of names and while they are inputting them, they have to be sorted alphabetically as they go. I was wondering (1) when declaring an array of strings which is best to use:
char test[10][10];
or
char *test[10];
and (2) the best way to write an insertion method, I know how to write an insertion sort method and there are many examples online on it but they deal mainly with just 1D arrays, so I'm a little lost on how to do this. Thanks!
The declarations you show are very different. The first is an array of arrays of char, and the second is an array of pointers to char (also known as a jagged array).
Both could be treated similarly, like arrays of strings, but there are quite a few semantic differences. For example, in the first your strings are limited to nine character (plus terminator) while in the second the strings could be of any length (fitting in memory).
There's also a difference in how the two arrays decays (what happens when you use plain test when a pointer is expected). The first will decay to a pointer to an array of char, i.e. char (*)[10]. The second will decay to pointer to pointer to char, i.e. char **.
Now for the big question: Which should you use? Well that really depends on use-case. Will you have only fixed-sized strings where the size is known from the start (and the total size is small enough to fit on the stack where local variables normally are stored)? Then you can use the first. If you don't know the length of the strings, or if they could differ by more than a few characters, then the second is probably a better choice.
The second question depends a lot on the choice of arrays. If you have arrays of arrays (the first declaration) then you need to copy strings around using strcpy. If you chose array of pointers (the second declaration) you could just assign the pointers around.
I don't want to solve assignments here, so I'll just give a brief push into the right direction:
What you want is a linked list; then, whenever the user enters a new name, you can insert the new entry directly into it at the correct position.
A first start could look like this:
struct entry { char name[10]; struct entry* next; };
struct entry* root = NULL;
void addname(char* na) {
if (root == NULL) {
root = (struct entry*)malloc(sizeof(struct entry));
sprintf(entry->name, "%s", na);
}else{
// HERE, walk through all entries! Once you reach one, where next is lex. greater then you create a new entry, and link it into that position of the chain
}
}

How do I calculate the no. of strings in a string array?

I came around this similar question.
But the advantage I have is that i know that each string is 260 char long.
Any hope?
int noOfStrings = sizeof(stringArray)/sizeof(stringArray[0]);
This doesn't work.
As it says. You cannot (unless it's a variable local to the function). Because of the way arrays are passed they degrade to pointers and all size information is lost (outside of the context of where the array was created because the compiler cannot make assumptions about it anymore).
You must explicitly pass the size (or always pass the same size).
What you posted would work if stringArray were declared globally or that statement was inside the function where you declared it.
It depends on how stringArray was declared.
That works when:
int main()
{
char stringArray[500];
int noOfStrings = sizeof(stringArray)/sizeof(stringArray[0]);
...
}
but not in:
int function(char *stringArray)
{
int noOfStrings = sizeof(stringArray)/sizeof(stringArray[0]);
...
}
In the first case, stringArray is a constant of type char[500], and the sizeof gives the number of bytes allocated for the array.
In the second case, stringArray is a pointer to char, and sizeof gives the size of the pointer.
They are two completely different things, just look similar.
Please post your code. Your specific solution which wants to compute a value at run time is not possible at first glance.
However, you might be able to code/define a macro as:
#define strsize sizeof(stringArray) / sizeof(char *)
if stringArray is an array of char pointers, but without seeing your source it is difficult to recommend a specific solution.
Sometimes a solution while not directly possible is still achievable but by other methods!!

Dynamic Array printing

I am trying to print a dynamic array, but I am having trouble with the bounds for the array.
For a simple example, lets say I'm trying to loop through an array of ints. How can I get the size of the array? I was trying to divide the size of the array by the size of the type like this sizeof(list)/sizeof(int) but that was not working correctly. I understand that I was trying to divide the size of the pointer by the type.
int *list
// Populate list
int i;
for(i = 0; i < ????; i++)
printf("%d", list[i]);
With dynamic arrays you need to maintain a pointer to the beginning address of the array and a value that holds the number of elements in that array. There may be other ways, but this is the easiest way I can think of.
sizeof(list) will also return 4 because the compiler is calculating the size of an integer pointer, not the size of your array, and this will always be four bytes (depending on your compiler).
YOU should know the size of the array, as you are who allocated it.
sizeof is an operator, which means it does its job at compile time. It will give you the size of an object, but not the length of an array.
So, sizeof(int*) is 32/62-bit depending on architecture.
Take a look at std::vector.
There is no standardized method to get the size of allocated memory block. You should keep size of list in unsigned listSize like this:
int *list;
unsigned listSize;
list = malloc(x * sizeof(int));
listSize = x;
If you are coding in C++, then it is better to use STL container like std::vector<>
As you wrote, you really did tried to divide the size of a pointer since list is declared as a pointer, and not an array. In those cases, you should keep the size of the list during the build of it, or finish the list with a special cell, say NULL, or anything else that will not be used in the array.
Seeing some of the inapropriate links to C++ tools for a C question, here is an answer for modern C.
Your ideas of what went wrong are quite correct, as you did it you only have a pointer, no size information about the allocation.
Modern C has variable length arrays (VLA) that you can either use directly or via malloc. Direcly:
int list[n];
and then your idea with the sizeof works out of the box, even if you changed your n in the mean time. This use is to be taken with a bit of care, since this is allocated on the stack. You shouldn't reserve too much, here. For a use with malloc:
int (list*)[n] = malloc(*list);
Then you'd have to adapt your code a bit basically putting a (*list) everywhere you had just list.
If by size you mean the number of elements then you could keep it in a counter that gets a ++ each time you push an element or if you dont mind the lost cycles you could make a function that gets a copy of the pointer to the first location, runs thru the list keeping a counter until it finds a k.next==null. or you could keep a list that as a next and a prev that way you wouldnt care if you lost the beginning.

Length of an `int` array in Objective C

I am passing an Integer array to a function.
Next I want to traverse through the array.
In C and C++ this worked by simply using arrayname.length which gave the number of elements in array. What is the way to find that in Objective-C?
[NSArrayObject length] works for NSArray type but I want it for int[]. Not even [XYZ count] works (an already suggested answer) so I'm looking for another way here.
You can use [XYZ count] to get the length of the array
There isn't anything specific to Objective-C with an array of ints. You would use the same technique as if you were using C.
sz = (sizeof foo) / (sizeof foo[0]);
There is no such thing as array.length in C. An int array in Objective-C is exactly the same as an int array in C. If it's statically defined like int foo[5], then you can do sizeof(foo) to get the size — but only in the same function foo is defined in (to other functions, it's just an int pointer, not an array per se). Otherwise, there is no inherent way to get this information. You need to either pass the size around or use sentinel values (like the terminating '\0' in C strings, which are just arrays of char).
Huh? In C, there's no such thing as "arrayname.length". An array of a primitive type, such as int[], does not have any length information associated with it at runtime.
[array count] this appears to work the easiest in objective-c
this code can be use when the total number of element in array are not known.
main()
{
int a[]={1,2,3,4,5,6,7}
int i;
clrscr();
for (i=0;i<=((sizeof(a)/sizeof(int));i++)
{
puts(a[i]);
}
getch();
}
There is no such thing as arrayname.length in C. That is why so many functions take argument pairs, one argument with the array and one argument with the length of the array. The most obvious case for this is the main function. You can find this function is all your iPhone projects in a file named main.m, it will look something like this:
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
Notice how the argv agument is a vector, or array of strings, and the argc argument is a count of how many items that are in this array.
You will have to do the same thing for all primitive types, this is the C part of Objective-C. If you stay in the Objective parts using NSArray or subclasses works fine, but requires all elements to be objects.
looks like a job for NSMutableArray. is there a reason why you need to work with a C array? if not, consider NSMutableArray.
i may be wrong (so please correct me if i am), but there's no easy way in C to get the size of int[] at runtime. you would have to do something like create a struct to hold your array and an int where you can keep track of how many items in your array yourself.
even fancier, you can make your struct hold your array and a block. then you can design the block to do the tracking for you.
but this is more a C question, not an objective-c quesiton.
If you want an array of integers, wrap them in NSNumber objects and place them into an NSArray.
What you are asking to do, is not really supported well in C though there is a method on the mac you could try (malloc_size):
determine size of dynamically allocated memory in c
You should try the following approach:
float ptArray[] = {97.8, 92.3, 89.4, 85.7, 81.0, 73.4, 53.0, 42.3, 29.4, 14.1};
int x = sizeof(ptArray)/sizeof(ptArray[0]);
NSLog(#"array count = %d", x);
Output:
array count = 10

Resources