I'm trying to write a little CLI Hangman game, just to create something in C using my very limited set of language features, making the information so far stick.
I haven't got to strings in the book yet, so I've created a so-called dictionary, which is a multi-dimensional array of characters, each row representing a word, and each column a letter. Therefore, if I want to put today's Dictionary.com word of the day ("prognosticate") in the dictionary, I write something like
dictionary[MAX_WORDS][MAX_CHARS] = {
...
{'p', 'r', 'o', 'g', 'n', 'o', 's', 't', 'i', 'c', 'a', 't', 'e'},
...
}
Next, I represent the word to be printed on screen as an array of characters, initially made of underscores.
The way I thought of it, when the player enter a letter, I check to see if it exists within the current word. If it does, I replace the underscores in the word[] array with the actual letter. I consider the word to be guessed when there are no underscores left in the word[] array.
The first thought was to write a function int in_array(char array[], char letter) which would return 0 or 1 based on whether the letter is found in the array. But then I figured out I couldn't pass it dictionary[][] as the first argument. I haven't figured out a solution so far, so I'll have to either use two functions, one for each array, or... rethink the whole idea.
So to sum this up, I need a function to check whether an element exists within either a one-dimensional or multi-dimensional array. Any solutions? Thanks in advance!
You can pass the entire dictionary via the somewhat janky
void foo(char dict[][MAX_CHARS], int whichWord);
i.e. by telling the compiler exactly how big each row of the 2D array is in this case, and which row you want as a separate parameter. Then you use your usual 2-subscript notation to access elements.
To pass one row of this array is easy too. Let's say you're doing guesses on the second word:
void foo(char[] word, int numChars);
foo(&(dict[1][0]), MAX_CHARS);
which might be little ahead of where you're at, but says "take the address in memory of the first character in the row I want, the second row (remember: 0-based indexing!), and treat it as the start of a one-dimensional array."
The problem you need to solve with this approach is telling the routine how many characters are in your word. If you use MAX_CHARS you have a problem, because presumably not every word is that length, and the characters you don't assign are uninitialized; i.e. you may have a bunch of garbage chars at the end of your row, one of which might even be the character you're looking for! The customary solution for this is to put a 0-valued character, written '\0', at the end of each word, so the function knows to stop when it sees it. You'd need to add this to the end of each word you're initializing, and you might need to bump MAX_CHARS up too to make room for it, because it is a character like everything else in your word.
A far better solution is to turn your dict into a one-dimensional array of strings, i.e.
char* dict[MAX_WORDS];
but that requires you be comfortable with pointers and strings, so come back to it when you're ready.
Related
Supposed I have an array of char {A,B,C,D,E,F} and the order number is 3
Then, the scrambled word is as follow :
The first 3rd (order number) character, C is removed and saved.
{A,B,D,E,F} , {C}
Start from the following character which is D, and the first third character would be F. So, F is removed and saved.
{A,B,D,E} , {C,F}
Start from the following character (since it reached end of array index, we go back to the beginning). So start from character A, and the first third character is D.
{A,B,E} , {C,F,D}
and so on.
The resulting will be an empty original char array, and the scrambled array
{ } , {C,F,D,B,E,A}
The above algorithm can be easily implemented. I have no problems with that. What I do have problem with is unscrambling it. I am given some unscrambled char array, and its ordering, and I have to find its original char array.
I have been trying for hours now and I can't seem to find a "formula" for it. I'm guessing I'm missing something crucial. Can anyone give me a clue or hint on how to approach this problem?
Make "map string" the same length as your original, but with all the letters in sequence, like "ABCDEFGH.."
Scramble it according to the given ordering
Now, iterate through your problem string and the map string at the same time. For each character in the problem string, the map string character will say where to put it. If you have map="SQEG..." and problem="DSEG...", then 'D' goes in the 'S' position, 'S' goes in the 'Q' position, etc.
That's it. If you prefer, or if your problem string is too long, use an array of integers instead of a string for the map.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
Transitioning myself from Python to C for an algorithms course, it has been really difficult for me to understand how common strings work in this new hell.
From what I've understood:
In C, there are no strings per se, but rather an array of characters.
Variable names of arrays point to the address of the first element in an array (which in memory is lined up), thus lacking the need to point out to every single character.
What confuses me is the following:
char greeting[] = "Hello world";
printf("%s", greeting);
1) How come there is no need to pass an array to greeting[ ] like {"H", "e", "l", "l", "o"} etc but a single string is enough?
2) Why does printf print out the whole message, when it's in actuality a simple array? Does using the string format in prinf go through a for loop, printing out each element without a new-line?
char *greeting = "Hello world";
printf("%s", greeting);
3) What? Let me get guess this... C takes the inserted string, gets its length, creates an array of characters and then does the point (2) magic? What kind of shenigans does the pointer variable do? Something something a[ ] == &a AND a[0] == *a???
char *moreGreetings[] = {"Hello", "Greetings", "Good morning"};
printf("%s", moreGreetings[0]); // Returns "Hello"
4) I just can't anymore... why does calling moreGreetings[0] call out the whole array of characters "Hello"???
Unless there is a bunch of shenigans going on under the hood, I have no idea how any of this makes sense. Could someone PLEASE explain what is going on?
Computers are aliens. They think nothing like we do. Computers don't know what strings are.
Programming languages are human-to-alien translators. Python is like reading an idiomatically translated book. C is like reading a literal translation, and even then it does a lot of work.
1) How come there is no need to pass an array to greeting[ ] like {"H", "e", "l", "l", "o"} etc but a single string is enough?
The compiler takes care of it for you. Also you're missing the null byte at the end. And those aren't characters.
C is the ultimate DIY language. Coming from Python it can be very disorienting. C gives you the bare minimum (yes, I see you Assembly programmers waving your arms in the back, don't complicate things). It does this A) to be very fast and B) to let you build anything. Unfortunately it doesn't always do this in the most obvious way. If you don't understand what's going on under the hood in C, the details of how computer memory works, you're in trouble.
For example, be careful of " vs '. 'H' is the single character H, really the short (ie. 1 byte) integer 72 (the exact number depends on your locale). "H" is a two character array, {'H', '\0'} which is really {72, 0}.
The key thing to understand about strings in C, and all arrays, is they're just a hunk of memory split into 1 byte chunks. That's it. They don't even store their own length, you have to either store that somewhere else (like in a struct) or terminate the list with something.
C strings are a hunk of memory split into 1 byte chunks terminated by a null byte (ie. 0). That's it. These are conceptually equivalent.
const char *string = "Hello";
char string[] = {'H', 'e', 'l', 'l', 'o', '\0'};
Both will contain the same bytes, they differ in how they're stored.
2) Why does printf print out the whole message, when it's in actuality a simple array? Does using the string format in prinf go through a for loop, printing out each element without a new-line?
printf is kinda like Python's str. You tell it how to convert the thing into characters, and it'll convert the thing. %s says it's a character array terminated by a null byte. %d says it's an integer. %f says a floating point number. All of these things are represented differently in memory and need different conversions to characters.
How printf actually works is an implementation detail, but it's a good exercise to implement it yourself. And you can do it with a for loop writing out one byte at a time and stopping at the null byte.
for( const char *pos = string; pos[0] != '\0'; pos++ ) {
putchar(pos[0]);
}
Note that rather than indexing through the array, I'm moving forward where the start of the array is. string is nothing more but a pointer to the start of the array. By copying it to pos I can change that pointer without affecting string. This avoids having to allocate an extra integer for the index, and it avoids having to do the extra math of an array lookup. pos[0] just reads 1 byte after pos.
And yes, if you forget that null byte it'll just keep on going reading the memory past the end of the string until it happens to see a 0 or the operating system smacks it for going out of the bounds of the process.
3) What? Let me get guess this... C takes the inserted string, gets its length, creates an array of characters and then does the point (2) magic? What kind of shenigans does the pointer variable do? Something something a[ ] == &a AND a[0] == *a???
No, C strings don't store the length. To get the length they'd have to iterate through the whole string, and then iterate through the whole string again to print it. Instead they print to the null byte.
4) I just can't anymore... why does calling moreGreetings[0] call out the whole array of characters "Hello"???
Because moreGreetings is an array of pointers to more character arrays. char *moreGreetings[] is roughly equivalent to char **moreGreetings. It's a pointer to a pointer to characters.
It's an array of strings and you asked for the first one, so you get a string out.
Keep in mind, Python is written in C (yeah, there's other implementations now). C is the bottom of the stack (almost). Python, and every other program, eventually has to deal with these same "shenanigans" C does, but really its dealing with the reality of how computers work.
Often they don't use C strings because they're so ungainly and error prone, they make up their own, but they're still filling fixed sized hunks of memory with numbers and calling them "strings".
The best advice I can give you is to turn on compiler warnings. All of them! C compiler warnings can shine a light on many simple mistakes, but they're off by default. The typical way you turn them on is with -Wall, but that's not all warnings. There's lots and lots of extras. This is the formula I use in my Makefile (have a Makefile).
CFLAGS += -Wall -Wshadow -Wwrite-strings -Wextra -Wconversion -std=c99 -pedantic $(OPTIMIZE)
That turns on "all" warnings, and "extra" warnings, and some additional specific warnings I've found useful. It says I'm using the ISO C standard from 1999 (more on that in a moment) and I want the compiler to be pedantic about following the standard so my code is portable between compilers and environments. I do a lot of Open Source work, but it's good when you're started so you don't get addicted to non-standard compiler extensions.
About the standard. C is quite old and was only standardized in 1990. Many, many people learned to code with non-standard C, and you see that in a lot of C teaching material. Even though there's a 2011 standard, many C programmers write and teach to C90 or even earlier. Even C99 is considered "new" by many. Visual Studio is particularly bad at standards compliance, but they're finally catching up in the latest versions.
1) How come there is no need to pass an array to greeting[ ] like {"H", "e", "l", "l", "o"} etc but a single string is enough?
Because the C syntax allows for "string" literals, which are a shorthand way of representing a C-style string.
Incidentally, {"H", "e", "l", "l", "o"} is an array of strings, not an array of chars. An array of characters would look like this: {'H', 'e', 'l', 'l', 'o'}, but "Hello" actually represents the array { 'H', 'e', 'l', 'l', 'o', '\0' } (strings work by having a string termination character \0 at the end).
2) Why does printf print out the whole message, when it's in actuality a simple array? Does using the string format in prinf go through a for loop, printing out each element without a new-line?
The %s token tells printf that you want it to treat the value as a "string", so it handles it as one, printing characters one by one until it encounters the string termination character \0, which is automatically at the end of any "string" you create using the string literal syntax.
3) What? Let me get guess this... C takes the inserted string, gets its length, creates an array of characters and then does the point (2) magic? What kind of shenigans does the pointer variable do? Something something a[ ] == &a AND a[0] == *a???
I have no idea what this question means.
4) I just can't anymore... why does calling moreGreetings[0] call out the whole array of characters "Hello"???
moreGreetings is an array of strings (or an array of pointers to arrays of chars, if you like). So moreGreetings[0] is the first element in that array, which is the "string" "Hello". If you pass that into printf and use %s to tell it to treat the value as a string, then it will.
How come there is no need to pass an array to greeting[ ] like {"H", "e", "l", "l", "o"} etc but a single string is enough?
It is indeed possible to assign "Hello" as an array.
char greetings[] = {'H', 'e', 'l', 'l', 'o', '\0'};
But this assignment is very hard to write so char greetings[] = "Hello" will be a shortcut. But the two assignments are the same.
Why does printf print out the whole message?
printf has different behaviors depending on the format argument it receives. When you ask printf to print a value in string format %s, it takes a pointer to a character and prints its value as well as its subsequent characters one by one until it reaches the null terminator \0.
Why does calling moreGreetings[0] call out the whole array of characters "Hello"?
A pointer to the array is a pointer to the first element of that array. So in both printf("%s", greetings[0]); and printf("%s", greetings); you are passing a pointer to the same memory location, which produces the same output.
It's a language feature - you can initialize an array of chars using a string literal, and it will do what you meant, i.e. char greeting[] = "foo" will be interpreted as char greeting[] = {'f', 'o', 'o', '\0'}. This comes without a price because otherwise char greeting[] = "foo" would be a compile-time error.
Google C array decay. In short, passing an array where a pointer is expected will behave as if the pointer to the first element of the array was passed. This is useful in many contexts, especially with strings.
See #2.
Because you declared an array of pointers to char (strings), and are passing the first of those pointers to printf. It is equivalent to writing printf("%s", "Hello").
1) How come there is no need to pass an array to greeting[ ] like {"H", "e", "l", "l", "o"} etc but a single string is enough?
When you pass an array or a string (it turns out that they are both the same thing), you are giving the memory address of the first element in the array. Because array elements are stored in memory, one after another, all that is needed to access the next element in the array (or character in string) is to increment the memory address that was passed.
2) Why does printf print out the whole message, when it's in actuality a simple array? Does using the string format in prinf go through a for loop, printing out each element without a new-line?
Usually, all the system supports is a simple putchar() function call. In order to use more convenient IO function, libraries were created. The printf function probably uses a for loop to print each element in the string.
3) What? Let me get guess this... C takes the inserted string, gets its length, creates an array of characters and then does the point (2) magic? What kind of shenigans does the pointer variable do? Something something a[ ] == &a AND a[0] == *a???
The C compiler does count the length of the string. I just want to clarify that this does not happen at runtime, it happens at compiletime. During runtime, the string is referred to by its pointer.
The pointer variable is just an ordinary variable. It just contains some memory address, somewhere. In order for the compiler to know how to treat the pointer, the pointer is given a type, i.e. int*, char*.
Note: There is such a thing as a void* without a referencing type.
When the program wants to access a memory location directly next to that pointed by some pointer, let's call it int*p, it just increments the value of p by p++ or p + 1.
I am trying to create a programme that is able to determine whether two inputted words are anagrams of each other.
The way in which I have been told to go by my tutor is to count how many of the first letter of one word there is, then compare to the other, then repeat for the rest of the letters. Therefore if the word gets to the end, then it considers them anagrams. However that is all he has helped me with, and I am really struggling with the problem.
The programme is required to print whether or not they are anagrams like so,
Success! "Carthorse" and "Orchestra" are anagrams!
Edit: Thanks guys for all of your responses, whilst I understand the whole idea behind them, I am finding it very difficult to put them into code, would anyone be able to simply writing the annotated code for me? It's not for a homework or anything, it's simply a personal project.
It sounds like you're new to C! Welcome :)
Tasks like that can seem complex, so the first step I'd do here is break it down into steps that you can google for how to do. So:
"count how many of the first letter of one word there is, then compare to the other, then repeat for the rest of the letter"
Read in the words/create variables of them
Create an array of length 26, to store each letter of the alphabet
Loop through the first word and for each letter, add one to the correct array index (a = 0, m = 12, etc)
e.g.
int index = string[i] - 'a'; // This will subtract the ascii value from the letter, getting a = 0 etc
letterCounts[index]++; // or letterCounts[index]--;
Loop through the second word, and for each letter, subtract one from the array index
If at the end any index is not 0, it is not an anagram.
Convert both strings to lowercase characters.
Create two arrays of 26 characters for the letters of the alphabet.
Run through each string counting the letters and incrementing the appropriate element in the alphabet arrays.
Then compare the two alphabet arrays and if they are equal for each character, your strings are anagrams.
1) Convert both strings to lowercase as necessary (use tolower from ctype.h).
2) Sort each string, e.g., by using qsort from stdlib.h:
static int cmp(const void *a, const void *b) { return *(char *)a - *(char *)b; }
qsort(str1, strlen(str1), 1, (cmp));
qsort(str2, strlen(str2), 1, (cmp));
3) Compare the sorted strings with strcmp from string.h - if equal, they are anagrams, otherwise not.
Hi everybody and thanks in advance for any help, this is the situation:
#define N 12
[..]
char vect[N][2];
char strng[2];
[..]
vect[i][0]=strng[2]; //this two lines are in a simple for cycle
vect[i][2]=strng[0];
Now, if in string[2] I have "c 2", what I expect in vect[i][0] is '2' and in vect[i][1] 'c'.
I use code::blocks and watching vect I have instead "2#", but it could be "2À" as well.
Can you help me? Where am I wrong?
Array indexes goes from zero up to the size minus one. So using e.g. strng[2] you access the third entry in the two-entry array. Accessing an array out of bounds leads to undefined behavior and the data will be indeterminate.
You should also remember that all strings in C are one more character than reported by e.g. strlen, and that extra character is a special terminator character. So if you want a two-character string, you really need three characters: Two for the string, and one for the terminator.
Rewrite these statements
vect[i][0]=strng[2]; //this two lines are in a simple for cycle
vect[i][2]=strng[0];
the following way
vect[i][0]=strng[1]; //this two lines are in a simple for cycle
vect[i][1]=strng[0];
provided that string contains two characters { 'c', '2' }.
Take into account that array string can not have string literal "c 2", because you defined it as
char strng[2];
that is it can contain only two characters.
If you want that the array would contain indeed "c 2" then you have to define it either as
char strng[3];
or as
char strng[4];
if you want to include the terminating zero.
In this case you may write
vect[i][0]=strng[2]; //this two lines are in a simple for cycle
vect[i][1]=strng[0];
Assuming strng literally contains "c 2", then your memory is the issue. strng[2] contains 3 cells iirc. 2 for holding chars and then a null terminator (ie \0). so when you try to access strng[2], (which you cant because you can only go to N-1 cells, where N is the number allocated for it) it contains undefined results, since it isnt null terminated and you are reaching beyond memory you allocated
Why don't the numeric arrays end with a null character?
For example,
char name[] = {'V', 'I', 'J', 'A', 'Y', '\0'};
But in case of numeric arrays there is no sign of null character at the end...
For example,
int marks[] = {20, 22, 23};
What is the reason behind that?
The question asked contains a hidden assumption, that all char arrays do end with a null character. This is in fact not always the case: this char array does not end with \0:
char no_zero[] = { 'f', 'o', 'o' };
The char arrays that must end with the null character are those meant for use as strings, which indeed require termination.
In your example, the char array only ends with a null character because you made it so. The single place where the compiler will insert the null character for you is when declaring a char array from a string literal, such as:
char name[] = "VIJAY";
// the above is sugar for:
char name[] = { 'V', 'I', 'J', 'A', 'Y', '\0' };
In that case, the null character is inserted automatically to make the resulting array a valid C string. No such requirement exists for arrays of other numeric types, nor can they be initialized from a string literal. In other words, appending a zero to a numeric array would serve no purpose whatsoever, because there is no code out there that uses the zero to look for the array end, since zero is a perfectly valid number.
Arrays of pointers are sometimes terminated with a NULL pointer, which makes sense because a NULL pointer cannot be confused with a valid pointer. The argv array of strings, received by main(), is an example of such an array.
An array can end in anything that is a valid value of the array element type. But only a \0 terminated char array is called a string.
For example
char name[]={'V','I','J','A','Y'};
Valid, but not a string, the limit is that you can't use it in functions expecting a string like strlen etc.
To clarify from OP's comment below, by the C standard, any character literals like 'a', '1', etc, including '\0' are type int. And you can put a '\0' at the end of an int array like this:
int arr[] = {20, 22, 23, '\0'};
But people usually don't do that because it's conventional that '\0' is only used to terminated strings. The above code is equivalent to
int arr[] = {20, 22, 23, 0};
A string ends with a 0 terminator, but a string is not the same thing as an array. We use arrays to store strings, but we also use arrays to store things that are not strings. That's why arrays in general don't automatically have a 0 appended to them.
Besides, in any generic array of int, 0 may be a valid (non-sentinel) value.
You can make an int array end with 0 as well, if you wish:
int iarray[] = {1, 2, 3, 0};
Since '\0' and 0 are exactly the same, you could even replace the 0 above by '\0'.
Your confusion might be due to the automatic insertion of '\0' in a declaration such as:
char s[] = "hello";
In the above, the definition of s is equivalent to char s[] = {'h', 'e', 'l', 'l', 'o', '\0'};. Think of this a a convenient shortcut provided by the C standard. If you want, you can force a non-zero terminated char array by being explicit about the size:
char s[5] = "hello";
In the above example, s won't be NUL terminated.
Also note that character literals in C are of type int, so '\0' is actually an int. (Also further, char is an integral type.)
There are three, maybe four decent ways of tracking an array's length, only two of which are common in C:
Keep track of the length yourself and pass it along with the pointer.
This is how arrays typically work. It doesn't require any special formatting, and makes sub-array views trivial to represent. (Add to the pointer, subtract from the length, and there ya go.)
Any function in the standard library that works with non-string arrays expects this already. And even some functions that mess with strings (like strncat or fgets) do it for safety's sake.
Terminate the array with some "sentinel" value.
This is how C strings work. Because nearly every character set/encoding in existence defines '\0' as a non-printable, "do nothing" control character, it's thus not a typical part of text, so using it to terminate a string makes sense.
Note that when you're using a char[] as a byte array, though, you still have to specify a length. That's because bytes aren't characters. Once you're dealing with bytes rather than characters, 0 loses its meaning as a sentinel value and goes back to being plain old data.
The big issue is that with most fundamental types, every possible arrangement of sizeof(type) bytes might represent a valid, useful value. For integral values, zero is particularly common; it is probably one of the most used and most useful numbers in all of computing. I fully expect to be able to put a 0 into an array of integers without appearing to lose half my data.
So then the question becomes, what would be a good sentinel value? What otherwise-legal number should be outlawed in arrays? And that question has no good, universal answer; it depends entirely on your data. So if you want to do such a thing, you're on your own.
Besides the lack of a decent sentinel value, this approach falls flat with non-character types for another reason: it's more complicated to represent subsets of the array. In order for a recursive function to pass part of the array to itself, it would have to insert the sentinel value, call itself, and then restore the old value. Either that, or it could pass a pointer to the start of the range and the length of the range. But wait...isn't that what you are trying to avoid? :P
For completeness, the two other methods:
Create a struct that can store the array's length along with a pointer to the data.
This is a more object-oriented approach, and is how arrays work in nearly every modern language (and how vectors work in C++). It works OK in C iff you have an API to manage such structs, and iff you use that API religiously. (Object-oriented languages provide a way to attach the API to the object itself. C doesn't, so it's up to you to stick to the API.) But any function that wasn't designed to work with your structs will need to be passed a pointer (and possibly a length) using one of the above two methods.
Pass two pointers.
This is a common way to pass a "range" in C++. You pass a pointer to the start of the array, and a pointer just past the end. It's less common in C, though, because with raw pointers, (start,length) and (start,end) represent the same data -- and C doesn't have the iterators and templates that make this so much more useful.
You need to end C strings with '\0' since this is how the library knows where the string ends.
The NUL-termination is what differentiates a char array from a string (a NUL-terminated char-array). Most string-manipulating functions relies on NUL to know when the string is finished (and its job is done), and won't work with simple char-array (eg. they will keep on working past the boundaries of the array, and continue until it finds a NUL somewhere in memory - often corrupting memory as it goes).
You do not have to have a '\0' char at at the end of character array! This is a wrong assumption. There is no rule which says you do. Characters (char type) are exactly like any other kind of data.
You do have to have a null terminated char array if you want to print the array using standard printf-family functions. But only because those functions depend on the ending of the character array - '\0' char.
Functions often have rules concerning the kind of data they expect. String (char[]) functions are not exception. But this is not a language requirement, it's the API you're using which has these requirements.
Char array ends with special char '\0' so that it can be treated as string.
And when you are manipulating string there must be some way to tell the length(boundary) of that string.
Look at function prototype of strcpy
char * strcpy ( char * destination, const char * source );
How does it know to copy how many chars from source to destination? The answer is by looking at the position of '\0'.
The '\0' char is prominent when dealing with string as a char *. Without '\0' as an end marker you wouldn't have been able to treat char * as string.
Arrays by themselves do not have to be 0\ terminated, it is the usage of the character arrays in a specific way that needs them to be \0 terminated. The standard library functions which act on character arrays will use the \0 to detect end of the array and hence treat it as a string, this behavior means the users of these functions will need to follow the \0 termination precondition. If your character array usage doesn't use any such functionality then it doesn't need the \0 terminator.
An array of char not necessarilly ends with \0.
It is a C convention that strings are ended with \0.
This is useful to find the end of the string.
But if you are only interested in holding data that is of type char, you can have a \0 at end or not.
If your array of char is intended to be used as a string, you should add \0 at the end of it.
EDIT: What is ended by \0 are the string literals, not the array of char.
The question is ill formulated.
An example to take the point that how \0 will confuse if taken in a integer array:-
int marks[]={20,22,23,0,93,'\0'};
^
So now your array will assume that 0(marked) is an end of the array which is not true.
\0 is usually used to terminate a string. In string \0 is regarded as the end of the string.
In your example you dont need to terminate it with '\0'
Found a very interesting wiki post:-
At the time C (and the languages that it was derived from) was
developed, memory was extremely limited, so using only one byte of
overhead to store the length of a string was attractive. The only
popular alternative at that time, usually called a "Pascal string"
(though also used by early versions of BASIC), used a leading byte to
store the length of the string. This allows the string to contain NUL
and made finding the length need only one memory access (O(1)
(constant) time). However, C designer Dennis Ritchie chose to follow
the convention of NUL-termination, already established in BCPL, to
avoid the limitation on the length of a string caused by holding the
count in an 8- or 9-bit slot, and partly because maintaining the count
seemed, in our experience, less convenient than using a terminator.
Also check a related post:- nul terminating a int array
We have a convention: special character '0' with numeric code 0, marks end of the string.
But if you want to mark end of int array, how will you know is that 0 is a valid array member or end-of-array mark? So, in general, it is not possible to have such a mark.
In other words:
The character '\0' (but not character '0', code 48) have no any sense in context of text string (by convention, it is a special character, that marks end), so it can be used as end-of-array mark:
Integer 0 or \0 (which is the same), are valid integer. It can have sense, and that is why it cannot be used as end-of-array mark:
int votesInThisThread[] = { 0, -1, 5, 0, 2, 0 }; // Zeroes here is a valid numbers of upvotes
If you'l try to detect end of this example array by searching 0, you'll get size of 0.
That is what question about?