C string length - c

when I explicitly state the value of a string, then compare it to itself, system returns FALSE. Does this have something to do with the extra '\0' character added by the system? And how should I refine my code to make it TRUE?
char name[5] = "hello";
if(name == "hello")
{
...
}

You can't (usefully) compare strings using != or ==, you need to use strcmp The reason for this is because != and == will only compare the base addresses of those strings. Not the contents of the strings.
don't use predefined array size like char name[5] = "hello"; instead of you can use char name[] = "hello"; or char name[6] = "hello"; when use
#include <stdio.h>
#include <string.h>
int main()
{
char a[] = "hello";
char b[] = "hello";
if (strcmp(a,b) == 0)
printf("strings are equal.\n");
else
printf("strings are not equal.\n");
return 0;
}

Continuing from my comment, you need char name[6] = "hello"; to hold 'hello (plus the nul-terminating character) Even better, you can use
char name[] = "hello";
That will properly initialize name to contain 6-character (including the nul-byte).
All string.h functions expect a nul-terminated string as a parameter when they take char * or const char * as parameters passed to the functions.
Lastly, as correctly noted in Anuvansh's answer, you cannot use a inequality condition to determine if two strings equal or differ. You either us the normal comparison functions strcmp, strncmp, memcmp or you walk a pointer down each string stopping at the first char the strings differ on, or on the nul-byte if the strings are equivalent.
Look things over and let me know if you have any further questions. Gook luck with your coding.

The strcmp() returns 0 if both argument are equal.
char name[]="hello";
if(strcmp(name,"hello") == 0)
return TRUE;
else
return FALSE;

Actually, name is a pointer that points to the address of the string "hello". You can't compare them. So you can try strcmp function instead. Also include the string.h library.
like:
strcmp(name,"hello");
also as one of the comment points out, take a char array of 6 to include '\0'.
Hope that helps.

In C ,the array name is actually the pointer to the first element of that array.
in your case:
if(name == "hello")
you compare pointer to the string so it will return false
You can see the same concept in this article
why is array name a pointer to the first element of the array?
You can simply include "string.h" library and use strcmp() function
code like this:
char name[]="hello";
if(strcmp(name,"hello")==0){
.....
}
to make it Ture

Related

Usage of pointers as parameters in the strcpy function. Trying to understand code from book

From my book:
void strcpy (char *s, char *t)
{
int i=0;
while ((s[i] = t[i]) != ’\0’)
++i;
}
I'm trying to understand this snippet of code from my textbook. They give no main function so I'm trying to wrap my head around how the parameters would be used in a call to the function. As I understand it, the "i-number" of characters of string t[ ] are being copied to the string s[ ] until there are no longer characters to read, from the \0 escape sequence. I don't really understand how the parameters would be defined outside of the function. Any help is greatly appreciated. Thank you.
Two things to remember here:
Strings in C are arrays of chars
Arrays are passed to functions as pointers
So you would call this like so:
char destination[16];
char source[] = "Hello world!";
strcpy(destination, source);
printf("%s", destination);
i is just an internal variable, it has no meaning outside the strcpy function (it's not a parameter or anything). This function copies the entire string t to s, and stops when it sees a \0 character (which marks the end of a string by C convention).
EDIT: Also, strcpy is a standard library function, so weird things might happen if you try to redefine it. Give your copy a new name and all will be well.
Here's a main for you:
int main()
{
char buf[30];
strcpy(buf, "Hi!");
puts(buf);
strcpy(buf, "Hello there.");
puts(buf);
}
The point of s and t are to accept character arrays that exist elsewhere in the program. They are defined elsewhere, at this level usually by the immediate caller or one more caller above. Their meanings are replaced at runtime.
Your get compile problems because your book is wrong. Should read
const strcpy (char *s, const char *t)
{
...
return s;
}
Where const means will not modify. Because strcpy is a standard function you really do need it to be correct.
Here is how you might use the function (note you should change the function name as it will conflict with the standard library)
void my_strcpy (char *s, char *t)
{
int i=0;
while ((s[i] = t[i]) != ’\0’)
++i;
}
int main()
{
char *dataToCopy = "This is the data to copy";
char buffer[81]; // This buffer should be at least big enough to hold the data from the
// source string (dataToCopy) plus 1 for the null terminator
// call your strcpy function
my_strcpy(buffer, dataToCopy);
printf("%s", buffer);
}
In the code, the i variable is pointing to the character in the character array. So when i is 0 you are pointing to the first character of s and t. s[i] = t[i]copies the i'th character from t to the i'th character of s. This assignment in C is self an expression and returns the character that was copied, which allows you to compare that to the null terminator 0 ie. (s[i] = t[i]) != ’\0’ which indicates the end of the string, if the copied character is not a null terminator the loop continues otherwise it will end.

comparing string gone wrong

I got the output as unequal can you please explain me why
#include <stdio.h>
int main()
{
char str1[] = "hello";
char str2[] = "hello";
if (str1 == str2)
printf("equal");
else
printf("unequal");
return 0;
}
That's because == is comparing the addresses of str1 and str2 and not the
contents of the string. You have to use strcmp for this:
#include <stdio.h>
#include <string.h>
int main()
{
char str1[]="hello";
char str2[]="hello";
if(strcmp(str1, str2) == 0)
puts("equal");
else
puts("unequal");
return 0;
}
would be the correct version. See https://ideone.com/wJpL2I
Note that in C a string is just a sequence of characters that end with the
'\0'-terminating byte. str1 and str2 are both arrays, but when you do
str1 == str2 they decay into pointers and what you are comparing is the memory
location of where the arrays are stored in memory. They are two different arrays
(although they have the same content), so they memory address will be of course different, that's why you get unequal. That's why you need the
strcmp function in order to compare the contents of the char arrays.
You are comparing the data container’s address which are str1 and str2, if you know java then there is that equals method and contentEquals method, if you use equals method it compares the object references, but if you do contentEquals it compares the content(data) resides in the objects.
In c as you should have already known that that the name of the string has the base address in it. That’s the reason you don’t need to put &(address of operator) while using the scanf this is the soul reason when you do the str1==str2 it compares the address not the data inside the string.
In c str1 and str2 are simply 2 character array which has the \0 at the end. Now when you do
if(str1==str2) //it compares the address of
//variables not the content as
//you are comparing the base address
//of the strings str1 and str2.
The right version should be:
#include <stdio.h>
#include <string.h>
int main()
{
char str1[]="hello";
char str2[]="hello";
if(strcmp(str1, str2) == 0)
puts("equal");
else
puts("unequal");
return 0;
}
If you want to verify that you can use this, printf(“%d”, &str1); printf(“%d”, &str2); they both will not be equal.
When you want to compare two strings, you actually want to see if each character in one string is in the corresponding position of the other string.
The strings variables used here (str1 and str 2) are just pointers to the base addresses of those strings.
Hence, str1 == str2 means you are just comparing if both strings have the same base addresses, which, of course, is incorrect.
Here, you can make use of the string.h file which has the strcmp() or string compare function.
It works like this:
It iterates through the string, and checks the difference in the ascii values of individual characters in corresponding positions(same index value). If all characters are the same, it will return 0.
Otherwise, a positive or negative value is encountered based on the order of passing the strings to strcmp.
But in this case, it is of little importance if you get a positive or a negative value.
usage:
if (!strcmp(str1, str2))
puts("equal");
else
puts("unequal");

Char pointers and strings

I found this program on-line, that claims to split a string on the format "firstName/lastName". I tested, and it works:
char *splitString(char* ptrS, char c){
while( *ptrS != c ){
if( *ptrS == '\0'){
return NULL;
}
ptrS++;
}
return ptrS;
}
int main(){
char word[100];
char* firstName;
char* lastName;
printf("Please insert a word : ");
fgets(word, sizeof(word), stdin);
word[strlen(word)-1] = '\0';
firstName = word;
lastName = splitString(word, '/');
if(lastName == NULL ){
printf("Error: / not found in string\n");
exit(-1);
}
*lastName = '\0';
lastName++;
printf("First name %s, Last name %s\n",firstName, lastName);
return(0);
}
What I'm seeing here however, is only one char array being created, and the firstName and lastName pointers being placed properly.Maybe it is because I'm a little confused about the relation between pointers and arrays but I have a few questions about this program:
How many strings -as char arrays- are produced after the program is executed?
Are the char pointers used in this program the same as strings?
Why I can use those char pointers used as strings in printf? I can use char pointers as strings on every C program?
As a corollary, what's the relationship between pointers and arrays? Can they be used interchangeably?
How many strings -as char arrays- are produced after the program is executed?
You have one char[], of size 100. However, at the end of the program's execution, you actually have two strings stored in it.
A string is a set of chars stored contiguously in memory terminated with '\0' (null/0).
In this program we take the input, and search for the '/' character. When found, it is replaced with the string terminator:
"John/Smith\0"
"John\0Smith\0"
The pointer to the beginning of the array will allow us to access the first string ("John"), and the pointer that previously pointed to the '/' character is incremented, so that it now points to "Smith"
initialisation:
"John/Smith\0"
^
|
word/firstname
after lastName = splitString(word, '/');:
"John/Smith\0"
^ ^
| lastname
word/firstname
after *lastName = '\0'; lastName++;:
"John\0Smith\0"
^ ^
| lastname
word/firstname
So there is still only one array (word) but you have two pointers (firstname &lastname) to the strings within.
Are the char pointers used in this program the same as strings?
The char* pointers are not strings, but they point to them. You can pass the pointers to any function that is expecting a string (I expand a bit below)
Why I can use those char pointers used as strings in printf? I can use char pointers as strings on every C program?
In C (and C++) functions cannot pass arrays of data. A function like this:
int func(char string[]){}
will not actually be passed the array itself, but instead, it will be passed a pointer to the beginning of the array.
It is often the case that the [] notation is used where the function will be operating on an array (in function headers char* str and char str[] are equivalent) as it removes any ambiguity that the pointer isn't there to reference a single char (or int etc).
Printf() takes pointers to the string, and knowing that it is a string (thanks to the %s identifier in the format string) it will print out each char from the memory location that the pointer identifies until it hits the '\0' character.
A valid string always has this terminator, and so when working with strings, this is safe.
You will often see functions that take an array, and an additional parameter to denote the size of the array:
int do_something_with_array(int array[], size_t array_length){}
This is because without a terminating value or knowing the size of the array, there is no way to know that you have left the array and started processing out of bounds which isn't allowed and can cause memory corruption or cause the runtime to kill your program (crash).
It is a common misconception that pointers and arrays are the same.
In most cases you handle arrays via pointers, so that handling the data is the same whether you have an array or a pointer to one. There are some things to keep in mind however; this as an example.
How many strings -as char arrays- are produced after the program is executed?
There are 1 char array in this program, namely word[100], others like firstName and last Name are just char pointers..
Are the char pointers used in this program the same as strings?
Char pointers are very different to Strings, Char pointers are something you can use to point at a char or a string. In this program firstName and lastName are only char pointers that are used to point at different places of the character array word[] to split the array

Char x[50] and Char x[100] Output

I'm not used to C as I'm primarily a Java guy, with some knowledge of C++, so forgive me if this is a trivial question. I could not seem to find an answer while searching online.
I'm initializing a char array...
char tcp[50];
So that I can concatenate a const char and a char. In examples I saw an easy way to do this was by creating that empty char array and then using...
strcat(x,y);
To stick them together.
Problem is, printing out the blank char array when it is set to "50" gives me a result of:
X??|?
When I change it to...
char tcp[100];
And print it, its blank. Why is this?
The array contents are undefined, assuming it is a local (automatic) array.
Use:
char tcp[50] = "";
Or:
char tcp[50] = {0};
Or:
char tcp[50];
tcp[0] = 0;
Or:
char tcp[50];
memset(tcp, 0, sizeof(tcp));
As you like.
Always null terminate you char arrays before doing anything:
tcp[0] = '\0';
C happily allocates the space for the array you declare, but it does not set its content to 0.
Therefore, the content of the array you're printing is random (or rather depending in the previous contents of the memory)
When creating an array, the compiler puts it somewhere in memory but does not initialize it, so whatever is in that memory when the program is started will be the initial "string".
Terminate the string manually after you created the array, either by making the whole array "zeroed" out, or just put zero as the first character:
char tcp[50] = { '\0' };
Or
char tcp[50];
/* ... */
tcp[0] = '\0';
The difference here is, you're essentially working with two empty arrays trying to merge them in the memory space of one (not sure if that makes sense for you).
First of all, in C you have to terminate strings with \0. That's something not exposed or visible in Java. Also you essentially used two undefined strings (as there's no value set).
#include <stdio.h>
#include <string.h>
char target[256];
const char source_a[] = "Hello";
const char source_b[] = "World!";
int void(main)
{
target[0] = '\0'; // this essentially empties the string as we set the first entry to be the end. Depending on your language version of C, you might as well write "char target[256] = {'\0'};" above.
strcat(target, source_a); // append the first string/char array
strcat(target, " "); // append a const string literal
strcat(target, source_b); // append the second string
printf("%s\n", target);
return 0;
}
Important: Using strcat() can be unsave, as there's no length check performed, and other than Java, these "strings" have a fixed length (the one you set when defining the variables). If there's no length given, but you copy a string on initialization, that length is taken (e.g. char test[] = "Hello!"; will be 7 chars long (due to terminating \0)).
If you'd like a more Java like approach on strings, use C++ and the std::string class, that performs a lot more similar to Java's strings.

C comparing pointers (with chars)

Good evening, I have 2 functions and each of them accepts as argument a pointer to char:
char pointer[255];
func1(char* pointer)
{
...
memcpy(pointer,some_char,strlen(something));
return;
}
func2(char* pointer)
{
...
if (pointer==someother_char) exit(0); //FAILs
//also I have
if(pointer==someother_pointer2char); // FAILs
}
Now I've tried strstr,strcmp etc... doesn't work. Wanted to try memcmp but I don't have static len. As I have to compare char* to char and char* to char* I would be needing two solutions right?
So, how to compare these pointers (actually pointees) in shortest possible way?
Thanks.
E D I T
Thanks to wallacer and Code Monkey now for char* to char comparison I use following:
func1(char* ptr){
char someother_char[255];
char *ptr_char = NULL; //I have to strcmp a few values so this is why I initialize it first
...
ptr_char = someother_char;
if (strcmp(ptr,ptr_char) == 0) //gtfo and it does...
...
ptr_char = some2nd;
if(strcmp...
Any suggestions maybe... (hmm external function for comparing?)
Suggestion1(by Code Monkey)
#include <stdio.h>
int main(void) {
char tempchar[255];
tempchar[0] = 'a';
tempchar[1] = 'b';
tempchar[2] = '\0';
char *ptr_char;
ptr_char = &tempchar[0];
printf("%s", ptr_char);
return 0;
}
You need to use strcmp. Not seeing how you tried to use it, this is how you should use it:
char *someother_char = "a";
char *pointer = "a";
if (strcmp(pointer, someother_char) == 0) { // match!
}
else { // not matched
}
to then do the comparison with a char, you have to promote to a char*:
char *someother_char1;
char test = 'a';
char *pointer = "a";
strncpy((char*)test,someother_char1,sizeof(test));
if (strcmp(pointer, someother_char1) == 0) { // match!
}
else { // not matched
}
if you want to use the char array then you have to de-reference:
char char_array[255];
// don't forget to fill your array
// and add a null-terminating char somewhere, such as char_array[255] = '\0';
char *ptr_somechar = &char_array[0];
char *pointer = "a";
if (strcmp(pointer, ptr_somechar) == 0) { // match!
} else { // not matched
}
Well right off the bat, if you want to compare the pointees, you need to dereference them. This means to compare the actual char value, you'll have to call
if (*pointer == someother_char)
However this will only compare the first char in the array, which is probably not what you want to do.
To compare the whole thing strcmp should work
char* someother_str = "hello strstr";
if(strcmp(pointer, someother_str) == 0) {
// do something
}
Make sure your other string is declared as a char*
More info: http://www.cplusplus.com/reference/clibrary/cstring/strcmp/
Edit: as per your comment. comparing char* and char doesn't really make sense. One is a character value, the other is an address in memory. Do do so, you can either dereference the char* or reference the value variable.
char c;
char* ptr;
// dereference ptr
if ( c == *ptr ) {
...
}
// reference the value
if ( &c == ptr ) {
}
The first method checks if the values are the same. The second checks if ptr is in fact pointing to the memory containing c ie. is ptr a pointer to c
Hope that helps
Use function srtncmp no srtcmp.
int res = strncmp(str, "¿Cuál es tu nombre? ", 100);
See the next link
compare strings
Strings are null terminated. When you use such kind of strings, it's not a good idea to mixing with other memory copy functions.
Once you do the memcpy operation, please note that your destination string will not be null terminated.
memcmp is a fast operations. Otherwise yo can simply loop through each character and quit upon finding a difference.
To use strcmp, please make sure that both the strings are null terminated. Otherwise it will lead to some crash.
I suggest you to use string functions like strcmp,strlen, strcpy to deal with strings because for that it's actually implemented.
You can't compare two pointers unless both pointers are referring to same memory location. Pointer is just a address to a memory location. What you really want to do is that, to compare the contents rather than compare the address where it's stored. So please use strcmp but again I warn you make sure that it's null terminated.

Resources