Strcmp() function isn't returning 0 - c

i was trying to compare two strings using strcmp() , and in the case they're equal the function returns -1 (meaning they are not equal) , i dont know whats wrong .
int main()
{
char password[]={'6','6','6','6','6','6'};
char passmatch[6];
int i =0;
for(i ; i<6 ; i++)
{
passmatch[i]='6';
}
printf("\n");
if(strcmp(password,passmatch)==0)
{
printf("Strings are equal");
}
else
{
printf("String are'nt equal");
}
return 0;
}

In C, strings need to be null terminated in order to be used with the standard library. Try putting a '\0' at the end, or make a string literal in the "normal" way, e.g. char password[] = "666666";, then the language will automatically put \0 at the end.

The problem is that in C '6' (with quotes) is not the same as 6 (without quotes). That's why this loop
for(i ; i<6 ; i++) {
passmatch[i]=6; // <<== Should be '6', not 6
}
is not assigning what you want it to assign. If you put quotes around this 6 as well, you would get the right content, but your program would remain broken, because strcmp requires null termination.
You can fix it in two ways:
Add null termination to both C strings, either manually or by initializing with a string literal,
Switch to using memcmp, which takes length, and therefore does not require null termination.

Related

Compare character by character 2 strings

I am trying to code a program that tells me if 2 strings are identcal. If they have one different chracter they are not.
I have this code, but it does not work, why?
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main() {
char str1[30], str2[30];
int i;
printf("\nEnter two strings :");
gets(str1);
gets(str2);
for (i=0;str1[i]==str2[i];i++)
if (str1[i]!=str2[i]){
printf("They are not identical");
}
else continue;
return (0);
}
It compiles with 0 errors and 0 warnings, but when I introduce 2 not identical strings it returns nothing. (The same happens when I introduce 2 identical strings, but that is how is supposed to be)
What should I do to fix it?
There is one important thing wrong here. First of all: The classic "c style string" is null terminated. Allthough there are other alternatives (like storing the length outside of the string), the null terminated string is part of the language (as string literals in code are null terminated by the compiler), and the runtime library (most string functions handle the \0 at the end of the string).
gets also appends a \0 at the end of the entered string:
http://www.cplusplus.com/reference/cstdio/gets/
You are comparing not only the entered strings, but also anything (random) after that string in memory.
It should look like this:
for(int i=0;str1[i]==str2[i];i++){
if(str1[i]==0) {
printf("equal");
}
}
printf("not equal");
There are other alternative, like using pointer. But on modern compilers they should produce roughly the same machine code.
Please note that there are C runtime library functions to compare strings:
strcmp is the most basic one, just two char *:
strncmp allows to specify the maximium chars to compare, do compare a part of a string:
There are other, just check out the links.
Please note that it's better to use the library functions, because even if in such a "simple" function. There are optimized ways to compare string. Like comparing in native word sizes. On 32 bit platforms you spend four time more time in comparation, not including the masking needed to perform byte wise operations.
Your for loop is:
for (i=0;str1[i]==str2[i];i++)
if (str1[i]!=str2[i]){
printf("They are not identical");
}
else continue;
Let's say str1 is "abc" and str2 is "xyz".
The conditional in the for loop will evaluate to false for i = 0. Hence, you will never get to the statement:
if (str1[i]!=str2[i]){
Consequently, you will never execute:
printf("They are not identical");
You can fix the logic error by using:
for (i=0; str1[i] != '\0' && str2[i] != '\0'; i++)
{
if (str1[i]!=str2[i]) {
break;
}
}
// If at end of the loop, we have reached the ends
// of both strings, then they are identical. If we
// haven't reached the end of at least one string,
// then they are not identical.
if ( str1[i] != '\0' || str2[i] != '\0' )
{
printf("They are not identical");
}
I have this code, but it does not work, why?
Because your looping condition str1[i]==str2[i] will make the inner if condition be always false.
What should I do to fix it?
Simple code:
for ( i=0; str1[i]==str2[i] && str1[i]!='\0'; i++) {
}
if ( str1[i]!=str2[i] ) {
printf("They are not identical");
}
or
i=0;
while ( str1[i]==str2[i] && str1[i]!='\0' ) {
i++;
}
if ( str1[i]!=str2[i] ) {
printf("They are not identical");
}
Let's say you have two string in which the first character is different. then you will not enter the loop as the condition of the loop (str1[i]==str2[i]) fails, therefore the condition should be ( str1[i]!='\0' && str2[i]!='\0' ). The '\0' is the last character of the c-style string.
You can also use string built in functions like " strcmp(str1,str2) ".

Check if a string is the substring of another string

I was having some problem when trying to check if a string is the substring of another string. Here is the expected output:
Enter a source string: abc
Enter the target string: abcde
findSubstring(): 1
Enter a source string: abcde
Enter the target string: cdef
findSubstring(): -1
And here is my code which used the strstr standard string library:
int main()
{
char sourceStr[40], targetStr[40];
printf("Enter a source string: ");
gets(sourceStr);
printf("Enter the target string: ");
gets(targetStr);
printf("findSubstring(): %d\n", findSubstring(sourceStr, targetStr));
return 0;
}
int findSubstring(char *s, char *t) {
if (strstr(s, t) != NULL) {
return 1;
}
return 0;
}
With these code, it works perfectly. However, I was told that I am not supposed to use any standard string library, so I was thinking how should I modify it?
Sorry for posting the question with no error but I seriously need a head start, as I googled for quite a while and I still have no idea how to do it.
Thanks in advance.
The key here is that when working in C, strings do not exist as an actual data structure as they do in, say, C++'s STL (std::string) or Java's String objects.
Instead, you should be treating them as a sequence of individual characters, whose end is denoted by an agreed-upon convention, which in this case is the 'NULL' character, which is the value 0 and can be represented in a string literal using the escaping symbol.
This is why strings are passed around as pointers to char in C, which actually point to the first character in the sequence.
Therefore, you can use pointer arithmetic to check the subsequent characters, until you find a value of 0, which means the string has ended.
By using a snippet like this, you can check any given string character by character.
char * pointer_to_string; //Pointer to start of string
char * pointer_to_character = pointer_to_string; //Start at the first character
while (*pointer_to_character != '\0'){ // Repeat while we haven't found the end
char c = *pointer_to_character; // The character the pointer is pointing to.
//do what you need to with the character
pointer_to_character++; //Now it points to the next character
}
// We exit the loop once the end of the string is found
HOWEVER:
This means you must be careful since this kind of string manipulation has its risks, since you are depending on finding an actual NULL character that ends the string, and if it's not present, the loop would run indefinitely, and in more complex examples, would easily lead to a segmentation fault and a crash.
In short, when using raw pointers in C, gotta be extra careful with what you do with the underlying memory, and certainly using known libraries and not reinventing the wheel tends to be the best option, but since I'm inclined to believe the purpose of the assignment is learning about string representation and pointer arithmetic, we'll do with that.
With this, you should be able to figure out what you need to do to solve the problem.
Well, if you don't want to use standard library, here is one way to do it.
This is simple code that satisfies the purpose:
int FindString(char *Str,const char *SubStr)
{
size_t count = 0 , x , y ;
size_t Str_len = strlen( Str ) ;
size_t SubStr_len = strlen( SubStr );
size_t diff = Str_len - SubStr_len;
if( SubStr_len > Str_len )
return 0;
for( x = 0 ; x <= diff ; x++ )
{
for( y = 0 ; y < SubStr_len ; y++ )
{
if( Str[ x + y ] == SubStr[ y ] )
count++;
else
{
count = 0;
break;
}
}
if( count == SubStr_len )
return 1;
}
return 0;
}
Also, if you want the version that compares insensitively, notify me in a comment.

Array point 0 doesn't reset content

I've made use of an array, and want to delete the content by placing null in array[0] but it doesn't work. Example... If I type Jesper, then the serial.print(nameBuffer[1]) returns e.
A temporary solution I use is a for-loop to place null in all it's spaces.
char name1[9] = "Jesper";
char nameBuffer[9];
void setup()
{
Serial.begin(9600);
}
void loop()
{
int i = 0;
nameBuffer[0] = 0;
Serial.print(nameBuffer[1]);
Serial.println(" All reset\n");
while(Serial.available() == 0)
{
// wait for data to be send
}
while(Serial.available() > 0)
{
int inByte = Serial.read();
delay(50);
nameBuffer[i] = char(inByte);
i++;
Serial.print("Recieved bytes: ");
Serial.println(inByte,DEC);
}
Serial.print("Searching for: ");
Serial.println(nameBuffer);
}
nameBuffer is an array of 9 char elements. Each of those elements has a value of type char.
Setting a char object to 0 doesn't remove it from the array (0 or '\0', the null character, is as valid a char value as any other), nor does it affect the elements that follow it.
Now if you're treating the contents of nameBuffer as a string (defined by the C standard as "a contiguous sequence of characters terminated by and including the first null
character"), then storing '\0' in nameBuffer[0] will cause it to contain an empty string. It has a length of 0, but there are still 9 char values stored in the array. So this:
printf("%s", nameBuffer);
won't print anything, but namebuffer[1] is still a valid char object holding whatever value was last stored in it.
Don't assume that printing a null character, or sending it over a serial port, will do nothing. If you don't want to print each character in your array, you'll need some logic to avoid printing the characters you don't want.
Incidentally, your code appears to be C++, not C. You have overloaded versions of Serial.print, one taking a char argument and one taking a char*; C doesn't support overloading. And char(inByte) is C++; it's a syntax error in C. (BTW, a cast isn't necessary there; the value will be converted implicitly.)

How to use the character array to identify a string

For my class we use char arrays for strings. If I was to use an if else statement, would something like this work if I had it modified to do so?
I know an array like this would make every character broken down to simple letters. And to use an if else statement I have to go like array[1] == 'H' and so on.
Is there a way to modify the code below to spit out the information I want if I type up "Alas". Right now, it only goes to the else part.
int main()
{
char s[10];
printf("Yo, this is a string: ");
gets_s(s);
if (s == "Alas")
{
printf("B ");
}
else
{
printf("A");
}
system("pause");
}
Use the strncmp standard library function to compare two strings. Include the <string.h> header.
strncmp(const char *s1, const char *s2, size_t n)
RETURN VALUE:
Upon successful completion, strncmp() shall return an integer greater than, equal to, or less than 0, if the possibly null-terminated array pointed to by s1 is greater than, equal to, or less than the possibly null-terminated array pointed to by s2 respectively.
Now in your code s is pointer and "Alas" is treated as pointer. Pointer to another memory area. This is a reason why they are always different. Use
if (!strcmp(s, "Alas"))
Something like:
int main()
{
char s[10];
printf("Yo, this is a string: ");
gets_s(s);
if (strcmp(s, "Alas") == 0)
{
printf("B ");
}
else
{
printf("A");
}
system("pause");
}
If the only thing you want to know is whether two strings are identical or not, you can define a function yourself to check each character of two strings, returning a 0 as soon as you encounter a difference, returning a 1 only if it encounters the terminating zero on both at the same time:
SameStrings( char * s1, char * s2 ) {
for ( int i = 0; s1[i] && s2[i]; i++ )
if ( s1[i] != s2[i] )
return 0;
// if the programme advanced this far
// either one of both should be 0
return s1[i] == s2[i];
// if they are equal, then both must be 0, in which case it will return 1
// else it will return a 0
}
You can add one more argument to that function, an integer that will limit the maximum number of characters to be checked, in case, for example, you want SameStrings( "lalaqwe", "lalaasd", 4 ) to return true.
This is good if you don't want to include a library for a function that does much more than you need...

Counting characters not working

#include <stdio.h>
int main()
{
int x=getlength("Hello",10);
printf("%d",x);
}
int getlength(char line[],int limit)
{
int x;
for(x=0;x<limit-1 && line[x]!=EOF && line[x]!='\n';++x)
printf("%c",line[x]) ;
printf("\n");
return x;
}
So this code seems to output this:
Hello%d then it outputs on a new line 9
What I don't understand is where the %d came from and how length of Hello%d is equal to 9
If anyone can explain I'd be happy.
A character string in C is terminated with a null character, '\0'. Change your for loop to test for the null character instead of EOF:
for (x=0; x < limit - 1 && line[x] != '\0' && line[x] != '\n'; ++x)
A function uses the constant EOF to signal the end of a file, but it's not used to terminate strings. That's because binary files can contain (unsigned) characters with values from 0 to 255. In order for a function to signal end-of-file, it must return a value that cannot appear within the file. Every implementation I've seen uses EOF = -1, because unsigned characters can never be negative.
A string, on the other hand, can only contain valid (unsigned) characters, so it can't use EOF to mark its end. Instead, it uses '\0', which is equivalent to the integer 0 and is a vailid—but unprintable—character.
A very common pitfall for programmers is to forget this, and either neglect to terminate a string with a null character (in which case a program will often scan past the end into invalid memory), or to try to manipulate strings that contain binary data (which sometimes includes a null character and terminates the string unexpectedly).
You for loop just counts to 9 as it never finds a EOF or a newline in the string "Hello".
The string "Hello" is terminated with a null character '\0', so change a part of for loop to line[x]!='\0'
The length of 'Hello' is 5. My hunch is you are reading those characters from the stack frame.
You are reading from location even after 'hello' on the stack. This is what is there on the stack.
Probably from the '%d' in the printf.
Try testing the NUL character value:
int getlength(char line[],int limit)
{
int x;
for(x=0;x<limit-1 && line[x]!='\n' && line[x]!='\0'; ++x)
{
printf("%c",line[x]) ;
}
printf("\n");
return x;
}

Resources