strcmp() return values in C [duplicate] - c

This question already has answers here:
How does strcmp() work?
(9 answers)
Closed 5 years ago.
I am learning about strcmp() in C. I understand that when two strings are equal, strcmp returns 0.
However, when the man pages state that strcmp returns less than 0 when the first string is less than the second string, is it referring to length, ASCII values, or something else?

In this sense, "less than" for strings means lexicographic (alphabetical) order.
So cat is less than dog because cat is alphabetically before dog.
Lexicographic order is, in some sense, an extension of alphabetical order to all ASCII (and UNICODE) characters.

A value greater than zero indicates that the first character that does not match has a greater value in the first string than in the second, and a value less than zero indicates the opposite.

C99 7.21.4:
The sign of a nonzero value returned by the comparison functions
memcmp, strcmp, and strncmp is determined by the sign of
the difference between the values of the first pair of characters (both
interpreted as unsigned char) that differ in the objects being
compared.
Note in particular that the result doesn't depend on the current locale; LC_COLLATE (see C99 7.11) affects strcoll() and strxfrm(), but not strcmp().

int strcmp (const char * s1, const char * s2)
{
for(; *s1 == *s2; ++s1, ++s2)
if(*s1 == 0)
return 0;
return *(unsigned char *)s1 < *(unsigned char *)s2 ? -1 : 1;
}

Look out the following program, here I am returning the value depending upon the string you have typed. The function strcmp retrun value according to ASCII value of whole string considered totally.
For eg. str1 = "aab" and str2 = "aaa" will return 1 as aab > aaa.
int main()
{
char str1[15], str2[15];
int n;
printf("Enter the str1 string: ");
gets(str1);
printf("Enter the str2 string : ");
gets(str2);
n = strcmp(str1, str2);
printf("Value returned = %d\n", n);
return 0;
}

Related

In C program, how do I check if the input string is a specific name or not? [duplicate]

This question already has answers here:
How do I properly compare strings in C?
(10 answers)
string comparison inside if condition malfunctioning [duplicate]
(2 answers)
Closed 5 years ago.
#include<stdio.h>
int main(){
char name[20];
scanf(" %s", name);
if (name == 'James'){
printf("Welcome James");
}else{
printf("You are not James");
}
}
Hope you got my idea. I know this doesn't work. But is there any way to do something like this?
Use
if (strcmp(name, "James") == 0)
instead of
if (name == 'James')
Man page of strcmp:
Return Value
The strcmp() and strncmp() functions return an integer less than,
equal to, or greater than zero if s1 (or the first n bytes thereof) is
found, respectively, to be less than, to match, or be greater than s2.
try: strcmp()
#include<stdio.h>
int main(){
char name[20];
scanf(" %s", name);
if (strcmp(name,"James")){
printf("Welcome James");
}else{
printf("You are not James");
}
}
Ref : How do I properly compare strings?
In C you have to use cmp string function:
strcmp(const char* s1, const char* s2);
Return values of function:
return value == 0 - s1 is equals s2
return value > 0 - s1 is longer than s2
return value < 0- s1 is smaller than s2
It is beacuse if you write:
char name_buff[20];
if (name_buff == "James")
{
...
It doesn't mean comparsion of strings but of address in memory.
So you have to use strcmp().

What does strcmp return if two similar strings are of different lengths?

I understand that if you have 'cat' (string1) and 'dog' (string2) in strcmp (this is a C question) then the return value of strcmp would be less than 0 (since 'cat' is lexically less than 'dog').
However, I am not sure what would happen with strcmp if this happened:
string1: 'dog'
string2: 'dog2'.
What would strcmp return? Less than zero, zero, or greater than? For context, I am trying to write a comparator function that compares strings and would like to account for strings starting with the same characters. One string may have an extension (such as '2' in 'dog2' in the example above).
EDIT: This is not a duplicate question. The question that this is allegedly similar to asks what the return type represents - I am saying what happens when the strings are identical up to a point but then one of them stops whilst the other continues.
It returns the difference at the octet that differs. In your example '\0' < '2' so something negative is returned.
It is defined in the C standard as the difference between the first two non matching characters, but the implementation is wild. The only common point is that the return value is zero for equal strings, then respectively <0 or >0 for str1<str2 and str1>str2.
From ISO/IEC 9899:201x, §7.23.4 Comparison functions:
The sign of a nonzero value returned by the comparison functions
memcmp, strcmp, and strncmp is determined by the sign of the
difference between the values of the first pair of characters (both
interpreted as unsigned char) that differ in the objects being
compared.
But some implementations take care to return typical values as 0, 1 and -1. See i.e. the Apple implementation (http://opensource.apple.com//source/Libc/Libc-262/ppc/gen/strcmp.c):
int
strcmp(const char *s1, const char *s2)
{
for ( ; *s1 == *s2; s1++, s2++)
if (*s1 == '\0')
return 0;
return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1);
}
EDIT:
In the Android boot library for Donut-release (https://android.googlesource.com/platform/bootable/bootloader/legacy/+/donut-release/libc/strcmp.c) the function returns 0 if strings are equal and 1 for the other 2 cases, and are used only logical operations:
int strcmp(const char *a, const char *b)
{
while(*a && *b) {
if(*a++ != *b++) return 1;
}
if(*a || *b) return 1;
return 0;
}
C11 quotes
C11 N1570 standard draft
I think "dog" < "dog2" is guaranteed by the following quotes:
7.23.4 Comparison functions
1
The sign of a nonzero value returned by the comparison functions memcmp, strcmp,
and strncmp is determined by the sign of the difference between the values of the first
pair of characters (both interpreted as unsigned char) that differ in the objects being
compared.
So the chars are interpreted as numbers, and '\0' is guaranteed to be 0:
Then:
7.23.4.2 The strcmp function
2
The strcmp function compares the string pointed to by s1 to the string pointed to by
s2.
says that, obviously, strings are compared, and:
7.1.1 Definitions of terms
1 A string is a contiguous sequence of characters terminated by and including the first null
character.
says that the null is part of the string.
Finally:
5.2.1 Character sets
2 [...] A byte with
all bits set to 0, called the null character, shall exist in the basic execution character set; it
is used to terminate a character string.
so '\0' is equal to zero.
Since the interpretation is as unsigned char, and all chars are different, zero is the smallest possible number.
From man strcmp:
The strcmp() and strncmp() functions return an integer less than,
equal to, or greater than zero if s1 (or the first n bytes thereof) is
found, respectively, to be less than, to match, or be greater than s2.
This would normally be implemented like #hroptatyr describes.
If you want to compare just the initial len characters of two strings, use strncmp instead of strcmp:
#include <string.h>
size_t len = 3;
int res = strncmp("dog", "dog2", len);
res will be 0 in this case.

How to identify a sequence in C

I would like to ask how to identify a sequence in C for example AAAAA & ddddd the sequence is all of the inputted characters must be the same.. How is it possible to achieve that? Do I need to use char ? Here is what i had try
#include<stdio.h>
int main() {
char ch;
scanf("%cccc", &ch);
if (ch = 'c')
printf(&ch);
else
printf("Character is Not the same sequence");
return (0);
}
To compare two characters:
char a = 'a';
char b = 'b';
return a == b; // this compares integer values of two characters
// and returns 1/0 if they do match/do not match
To compare strings:
char str1 = "AAAAA";
char str2 = "aaaaa";
return strcmp(str1, str2);
man strcmp(3):
The strcmp() function compares the two strings s1 and s2. It returns
an integer less than, equal
to, or greater than zero if s1 is found, respectively, to be less than, to match, or be greater
than s2.
The strncmp() function is similar, except it compares the only first (at most) n bytes of s1 and
s2.
Your code contains few bugs. %c format is for scanning single character, use %s for strings. Here:
if (ch = 'c')
you assigned 'c' to ch, not what you wanted. Use == in C for comparisons.
I would try this:
Accept a string as input (instead of a character)
Set up a loop to walk through the string, character by character
Your first character will be the "good" value
If at any time, you encounter a different character, fail out of the loop
If you reach the end of the string without failing, you succeed
Create a Macro for the pattern you want to find. typecast your input to the size of the pattern you want to recognise. Subtract both. If 0 pattern matched. Else,shift right 1 bit and repeat. Example, Pattern to find #define wPAT 0x1234. Input=> U32 dwInput=0x12345678. Result= (U16)dwInput - wPAT . If 0,pattern found. Else, dwInput>>1 and repeat Result= (U16)dwInput - wPAT. Repeat 16 times to find if pattern is present or not

I do not understand strcmp results

this is my implementation of strcmp ,
#include <stdio.h>
#include <string.h>
int ft_strcmp(const char *s1, const char *s2)
{
while (*s1 == *s2)
{
if (*s1 == '\0')
return (0);
s1++;
s2++;
}
return (*s1 - *s2);
}
int main()
{
char s1[100] = "bon";
char s2[100] = "BONN";
char str1[100] = "bon";
char str2[100] = "n";
printf("%d\n", ft_strcmp(s1, s2));
printf("%d\n", ft_strcmp(str1, str2));
return (0);
}
from the book kernighan and Ritchie but i use a while loop, instead of the for, i ve tested it many times and my strcmp geaves the same results as the original strcmp,
but i do not understand the results , i rode the man:
"The strcmp() and strncmp() functions lexicographically compare the null-terminated strings s1 and s2."
what does lexicography means ?
"return an integer greater than, equal to, or less than 0, according as the string s1 is greater than, equal to, or less than the string s2."
i understand this part but my questions are how can it come up with such results:
32
-12
s1 looks < s2 for me so how and why do i get 32 and how the calcul is made ?
str1 looks > str2 for me, how and why do i get -12 and how the calcul is made.
I ve compile it with the real STRCMP and i get the Same results..
last question why do i need to compare *s1 to '\0' won't it work fine without ?
thank you for your answers i m confused..
1) K&R are comparing the ascii values of those chars, that's why you get 32 and -12, check out an ascii table and you'll understand.
2)If you don't check for \0 , how can you know when the string end? That's the c strings terminator.
Capital letters in terms of ASCII codes actually precede lowercase letters, as you can see here.
So in terms of lexicographic ordering, s1 is treated as being bigger than s2, because the ascii value of the first letter that differs is the larger one.
SO we compare *s1 to '\0' to see when does the string ends,
and the results are made using the decimal value of the first characteres of each string.
int ft_strcmp(char *s1,char *s2)
{
int x;
x = 0;
while(s1[x] != '\0' && s2[x] != '\0' && s1[x] == s2[x])
i++;
return (s1[x] - s2[x]);
}
by mokgohloa ally

Can strcpy affect strcmp results in c language?

Edit: Changed title to reflect both methods in post.
I'm trying to compare two strings in c language as below but for some reason it's always printing that both strings are not equal
#include <stdio.h>
#include <string.h>
int main()
{
/* A nice long string */
char test[30]="hellow world";
char test2[30];
// to copy string from first array to second array
strcpy(test2, test);
/* now comparing two stering*/
if(strcmp(test2, test))
printf("strigs are equal ");
else
printf("not equal \n");
printf("value of first string is %s and second string is %s",test,test2);
printf("length of string1 is %zu and other string is %zu ",strlen(test2),strlen(test2));
}
I'm always getting output as
not equal
value of first string is hellow world and second string is hellow worldlength of string1 is 12 and other string is 12
Your problem is with how you're using strcmp. strcmp returns 0 (which evaluates as false) when the strings are equal (and returns a positive number when the strings are "in order" and a negative number when they're "out of order").
strcmp returns 0 when two strings are the same, and 0 evaluates to false in C. Try:
if(strcmp(test2, test)==0)
As per C++ reference
Return value of strcmp
-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; And a value less than zero indicates the opposite.
Alter your condition to if(!strcmp(test2, test)) and it should work.
strcmp() returns 0 if the strings are equal. See, for example, http://www.cplusplus.com/reference/clibrary/cstring/strcmp/
strcmp() returns 0 on equality
man strcmp: "The strcmp() function compares the two strings s1 and s2. It returns an integer less than, equal to, or greater than zero if s1 is found, respectively, to be less than, to match, or be greater than s2."
strcmp return 0 if the given two strings are equal.
I have also fixed few spelling mistakes and in the last printf() you have called strlen(test2) two times! - correct that as well
#include <stdio.h>
#include <string.h>
int main()
{
/* A nice long string */
char test[30]="hello world";
char test2[30];
// to copy string from first array to second array
strcpy(test2, test);
/* now comparing two stering*/
if(!strcmp(test2, test))
printf("strigs are equal \n");
else
printf("not equal \n");
printf("value of first string is %s \nsecond string is %s \n", test, test2);
printf("length of string1 is %zu \nsecond string is %zu \n",strlen(test), strlen(test2));
return 0;
}
Output:
$ ./a.out
strigs are equal
value of first string is hello world
second string is hello world
length of string1 is 11
second string is 11
$

Resources