This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 4 years ago.
Is there any better way of getting the right length of array containing digits?
I have an array of digits: 0, 0, 1 and I try to get length of it. It obviously breaks and returns 0. I am new to C but I tried to make custom strlen function:
int custom_strlen(char *str) {
for(int i = 1; ;i++) {
if (str[i] == 0) {
return i;
}
}
return -47;
}
but it is not that efficient and in some cases returns unexpected values as well. The expected out put would be 3 in this case.
Is there any function to use?
An array of integers is not a string. C arrays do not contain length information inherently. The way strlen works is that C strings are null terminated, meaning the last character is NUL (null character), which is 0. Otherwise, there is just no way to know how long an array is.
I think you may be wanting to do an array of '0','0','1'. Can you post the array you are using?
As mentioned, C strings are null terminated.
The only choices are
Using a string terminated with some special character that you watch for (like a null) or
Keeping track of how long the string is when you create it.
FWIW, if it's not null terminated, it's not actually a string in C, it's just memory that contains chars that you happen to be interpreting as a string.
Related
This question already has answers here:
Are negative array indexes allowed in C?
(9 answers)
Closed 5 years ago.
I just want to know is it a good way of programming style.
I know what is happening in this piece of code. look for the first occurrence of href save it next_next and then look for the first occurrence of "}" and save it end_marker.
Here my question is end_marker[-1] = '\0'; is needed? Because strstr, upon successful completion, strstr() shall return a pointer to the located string or a null pointer if the string is not found.
I know the endmarker '\0' is for string but don't know is it good to index the array in the negative number?
Code:
char *end_marker;
char *next_next = strstr(links_ptr, "href");
if (next_next != NULL) {
next_next += 7;
end_marker= strstr(next_next, "}");
end_marker[-1] = '\0'; // :)
}
EDIT: links_ptr contains this data
"links": [
{
"rel": "next",
"href": "https://www.randomstuff.com/blabla"
}
]
This usage of strstr assumes much about the input. Given input it doesn't expect, it can scan memory out of the string bounds, write to bad addresses, or try to dereference a null pointer.
If links_ptr is different - if it's part of user input or data downloaded on the internet - then it's a definite bug and security issue.
next_next += 7 assumes that strlen(next_next) >= 7. If the string is shorter you'll be scanning memory that doesn't belong to the string until the first '\0' or '}' is found.
if the previous scan finds '}' it will write '\0' to an unrelated address
if '}' isn't found, end_marker will be NULL and end_marker[-1] should crash
In C/C++, there's nothing evil in using a negative array index. In this way you are addressing the slot BEFORE the pointer represented by end_marker. However, you need to ensure that there's valid memory at this address.
In this case it would be undefined behaviour, you should do
if (end_marker != NULL)
{
end_marker[strlen(end_marker) - 1] = '\0';
}
Using negative number isnt good practice and you should do it.
To do it you have to be sure there is still this array.
This question already has answers here:
How do I determine the size of my array in C?
(24 answers)
Closed 6 years ago.
my professor has assigned a project where we need to make a reverse polish calculator in C (input in postscript syntax). I'm currently working on a method to find the length of the array of values I have scanned in (via .txt file). My current method is
int length(int list[]) {
int c = 0;
while(0 == 0) {
if(list[c] != '\0') {c++;}
else {break;}
}
return c;
}
and the call for it is
int sizeA = length(list);
printf("\n%d\n", sizeA);
It's currently only outputting the length as 0. Does anyone know why that might be and a fix to this method?
Thanks
The notion of "length" is a sort of tricky one in C (and low-level programming in general). If you have an array, the C compiler knows how large it is and provides an interface to the programmer to get that value in bytes: sizeof. The thing is, arrays are passed via pointers in C and determining the size via pointers is impossible without certain meta-information. Common methods to determine the length of an array are
appending an end marker to the array. Determining the length is simply a matter of iterating until the end marker is found and returning the number of iterations. Note that this renders the end marker's value unavailable for use as a value in the array.
just passing the size of the array around. Take the write system call as an example. Besides the file handle, it needs a pointer to the data and its length. Why its length as well? Because the pointer doesn't contain information about the length. So, either use a terminator like a null byte or pass the length explicitly. The former idea can be abandoned because the write system call is supposed to be generic; and to yield genericity, a null byte must be expected to be a possible value in the array, so it cannot be used as a terminator for reasons I uttered above.
Which one you actually end up using totally depends on the particular use case.
Apparently you decided to use the terminator-variant. \0 is the null byte, an ASCII character with code value 0x0. It's commonly used for terminating C-strings. strlen uses it to determine a C-string's length, for example. For int arrays, there is no such predefined terminator, so you need to come up with your own one. If you decide on \0, so be it, but I'd use the literal 0x0 instead because strictly-speaking, \0 is a character literal and that's just unfitting for ints.
To actually implement this, you'd need to append the terminating value to every int array, whose size you want to determine this way. Then write your function to get the length of such an int array just as you do, i.e., by iterating until the terminator is found.
This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 6 years ago.
How do I compare these two character arrays to make sure they are identical?
char test[10] = "idrinkcoke"
char test2[10] = "idrinknote"
I'm thinking of using for loop, but I read somewhere else that I couldnt do test[i] == test2[i] in C.
I would really appreciate if someone could help this. Thank you.
but I read somewhere else that I couldnt do test[i] == test2[i] in C.
That would be really painful to compare character-by-character like that. As you want to compare two character arrays (strings) here, you should use strcmp instead:
if( strcmp(test, test2) == 0)
{
printf("equal");
}
Edit:
There is no need to specify the size when you initialise the character arrays. This would be better:
char test[] = "idrinkcoke";
char test2[] = "idrinknote";
It'd also be better if you use strncmp - which is safer in general (if a character array happens to be NOT NULL-terminated).
if(strncmp(test, test2, sizeof(test)) == 0)
You can use the C library function strcmp
Like this:
if strcmp(test, test2) == 0
From the documentation on strcmp:
Compares the C string str1 to the C string str2.
This function starts comparing the first character of each string. If
they are equal to each other, it continues with the following pairs
until the characters differ or until a terminating null-character is
reached.
This function performs a binary comparison of the characters. For a
function that takes into account locale-specific rules, see strcoll.
and on the return value:
returns 0 if the contents of both strings are equal
This question already has answers here:
Using the equality operator == to compare two strings for equality in C [duplicate]
(9 answers)
Closed 9 years ago.
Got a small problem with C. Restricting myself to simple C (i.e. OS instructions), and two strings seem to not be the same. Here is my code:
char inputData[256];
int rid;
rid = read(0,inputData,256);
// Strip input
char command[rid];
int i;
for (i = 0; i<=rid-2; i++) {
command[i] = inputData[i];
}
command[rid-1] = '\0';
if (command == "exit") {
write(1,"exit",sizeof("exit"));
}
Now, if a user enters "exit" into the terminal when queried and hits enter, the if for detecting "exit" never gets run. Any ideas?
Thanks,
EDIT: I am commiting to git as I go, so the current version can be found at github.com/samheather/octo-os. It's very obviously not complete code, but it demonstrates the problem.
You can't compare strings with ==. You need to use strcmp.
if (strcmp(command, "exit") == 0) {
C strings are actually character arrays. You can think of "command" as a pointer to the first character. You want to compare every character in the string, not just the location of the first characters.
You should use strcmp to compare strings in C.
if(strcmp(command, "exit") == 0) //strcmp returns 0 if strings are equal
To quote:
A zero value indicates that both strings are equal. A value greater than zero indicates
that the first character that does not match has a greater value in str1 than in str2.
a value less than zero indicates the opposite.
As it stands right now, you're comparing the address of command with the address of the string literal "exit", which pretty much can't be the same.
You want to compare the contents, with either strcmp, or (if "only OS instructions" means no standard library functions) an equivalent you write yourself that walks through the strings and compares characters they contain.
As others said, == doesn't work with strings. The reason is that it would compare the pointers given.
In the expression
command == "exit"
command is a pointer to your array variable, while "exit" is a pointer to that string which resides in read-only data space. They can never be identical, so the comparison always is false.
That's why strcmp() is the way to go.
Use strcmp from the standard library.
This question already has answers here:
Why are strings in C++ usually terminated with '\0'?
(5 answers)
Why do we need to add a '\0' (null) at the end of a character array in C?
(9 answers)
Closed 9 years ago.
I know that we have to use a null character to terminate a string array like this:
char str[5] = { 'A','N','S','\0' };
But I just wanted to know why is it essential to use a null character to terminate an array like this?
Also why don't we add a null charater to terminate these :-
char str1[5]="ANS";
The NULL-termination is what differentiates a char array from a string (a NULL-terminated char-array) in C. Most string-manipulating functions relies on NULL to know when the string is finished (and its job is done), and won't work with simple char-array (eg. they'll keep on working past the boundaries of the array, and continue until it finds a NULL somewhere in memory - often corrupting memory as it goes).
In C, 0 (the integer value) is considered boolean FALSE - all other values are considered TRUE. if, for and while uses 0 (FALSE) or non-zero (TRUE) to determent how to branch or if to loop. char is an integer type, an the NULL-character (\0) is actually and simply a char with the decimal integer value 0 - ie. FALSE. This make it very simple to make functions for things like manipulating or copying strings, as they can safely loop as long as the character it's working on is non-zero (ie. TRUE) and stop when it encounters the NULL-character (ie. FALSE) - as this signifies the end of the string. It makes very simple loops, since we don't have to compare, we just need to know if it's 0 (FALSE) or not (TRUE).
Example:
char source[]="Test"; // Actually: T e s t \0 ('\0' is the NULL-character)
char dest[8];
int i=0;
char curr;
do {
curr = source[i];
dest[i] = curr;
i++;
} while(curr); //Will loop as long as condition is TRUE, ie. non-zero, all chars but NULL.
It isnt essential but if you are using any of the standard libraries, they all expect it.