Sort Strings by first letter [C] - c

I have a program which places structures in a linked list based on the 'name' they have stored in them.
To find their place in the list, i need to figure out if the name im inserting is earlier or later in the alphabet then those in the structures beside it.
The names are inside the structures, which i have access to.
I don't need a full comaparison if that is more work, even just the first letter is fine.
Thanks for the help!

It's not clear to me what your question is, but something like this would work:
if (node1->name[0] <= node2->name[0]) {
...
} else {
...
}
This will compare the first letter of the name in each of the nodes.

If you have two C strings, a and b, you can simply compare their first elements:
*a == *b
Where == can be any of the six relational operators.
Remember that with C strings, the char* points to the first character in the string.

strcmp() compares two C strings and will tell you what order they're in, or if they're the same. If you don't care about case, you can use strcasecmp(). These functions won't compare any more of the strings than necessary to determine what order to return.
strcmp man page
strcasecmp man page

You can simply iterate through the list and insert the new element in the correct place based on comparisons you do while passing each element. The simplest case sensitive version can be done just by comparing the numeric values of the letters (e.g. a[0] < b[0]), or you can convert both to a common case if you want to be case-insensitive (see ctype.h). Or you can compare the whole words with strcmp.

Related

Two identical chains do not identify themselves as equals in C

I've two character strings, one with the first line of a file (which is "WORKING"), and a second with the word "WORKING". The problem is that when I try to put them in an IF, it says they're not the same!
I've tried to read both of them with printf command but they're the same. I've also tried to use '\n' in the second string but there's not any change.
Here's the code, have a look:
FILE *fl;
fl=fopen("test.txt", "r");
char line_working[100];
fscanf(fl, "%s\n", line_working);
fclose(fl);
printf("%s", line_working); //HERE IT PRINTS: WORKING
char* workinger="WORKING";
printf("\n%s", workinger); //HERE IT ALSO PRINTS: WORKING
getch();
if(workinger==line_working){
printf("OK");
getch();
}
And nothing happens...
if(workinger==line_working){
compares the pointers.
workinger is a pointer and the array line_working used in the expression (comparison) gets converted to the pointer to its first element, which is equal to &line_working[0]. So it does address comparison. But this is not what you want. Unfortunately, this comparison is perfectly valid in C. So compiler can't help you here.
Use strcmp() to compare C strings.
== compares the pointer addresses.
To compare null-terminated character arrays (aka C-strings), use strcmp:
if(strcmp(workinger, line_working) == 0)
Your code does not compare the strings that you correctly try to compare with the assumption that the result should be they are equal, but the memory location where the strings are stored. By using '==' you do compare the value of workinger (which is a pointer so the variables value is a memory address) and line_working (which is an array so the corresponding value equals the memory address of the 1st element)
if (workinger==line_working)
To compare the strings that are stored at the corresponding memory locations you should make use of the string compare functions (see this question How do I properly compare strings? )

If statement in C always returning false [duplicate]

This question already has answers here:
Issue with main arguments handling
(3 answers)
Closed 7 years ago.
I am fairly new to C, so am not overly familiar with it's syntax, however I have debugged my code and researched for the correct syntax, and it seems to be correct, I have also changed the scope of the variables to see if this was causing the error.
The if statement should compare two variables, which both hold strings, I have even printed both the variables out to ensure they are the same, however it is still skipping straight to the else section of the if statement. Can anyone give me any pointers on why it will not run the if statement, it just skips straight to 'incorrect'.
The correctWord variable is defined at a different section in the code.
Find full code here.
-UPDATE-
I have now updated the syntax of the code, however it is still returning false.
char correctWord[20];
void userGuess(){
char userWordGuess[20];
printf("Anagram: ");
printf(anagramWord);
printf("Your Guess: ");
scanf("%s",userWordGuess); //Reads in user input
printf(correctWord);
printf(userWordGuess);
if(strcmp(userWordGuess, correctWord) == 0){
printf("Congratulations, you guessed correctly!");
}else{
printf("Incorrect, try again or skip this question");
}
}
You cannot compare strings in C using ==, because this compares the addresses of the strings, not the contents of the string. (which you certainly don't require, and obviously, the addresses of the two strings are not equal too.)
C has a pretty nice function for it : strcmp() which returns 0 if both the strings are equal.
Try using this in your if condition:
if (!strcmp(userWordGuess,correctWord))
{
//Yay! Strings are equal. Do what you want to here.
}
Be sure to #include <string.h> before using strcmp().
In C, you can't compare strings using ==. You will end up comparing the addresses of the strings, which is not the same.
You need to call the strmcp() function, which will return 0 if its arguments (two strings) are equal.
So the code should be if(strcmp(userWordGuess, correctWord) == 0).
You're comparing addresses of different arrays, which will always be unequal.
You need to use strcmp or some other strings library function to compare strings character by character.
userWordGuess == correctWord will compare the pointers (i.e. the locations in memory of the arrays), which are probably not equal.
For string comparision in C, use strcmp (or strncmp):
if (!strcmp(userWordGuess, correctWord)){
/*Strings are equal*/
Use
if(strcmp(userWordGuess, correctWord) == 0) // strings are equal
{
printf("Congratulations, you guessed correctly!");
}
else // not equal
{
printf("Incorrect, try again or skip this question");
}
if both string are equal than if condition will run. otherwise it wil run else
The strings are not first-class citizens in the C language. The strings are represented as either arrays of characters or pointers to such arrays.
In both cases, the variable you use to access the string is a synonym for the address in memory of the first character of the string.
What you compare with userWordGuess == correctWord is not the strings but their addresses in memory. Since userWordGuess and correctWord are two different arrays of characters, their addresses in memory are always different and their comparison will always produce FALSE.
In order to compare the actual string values you have to use the standard function strcmp() or one of its variants (find them at the bottom of the documentation page).
Change in the code:
/** Need to include the header that declares the strcmp() function */
#include <string.h>
char correctWord[20];
void userGuess(){
char userWordGuess[20];
/** stripped some lines here ... */
/** compare the strings, not their addresses in memory */
if (strcmp(userWordGuess, correctWord) == 0) {
/** the rest of your code */
What you are doing here is comparing two pointers. userWordGuess and correctWord point each to the beginning of an array of characters (which is what you defined at the beginning of your example code).
So if you want to compare the two arrays of chars you can use the strcmp function defined in string.h
It is important that you learn the relation between arrays and pointers. Pointer arithmetic is as well important here. Check this out: Arrays, Pointers, Pointer Arithmetic

How to check if two words are anagrams in c

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.

Copying and comparing individual element from 2D array to another array in C

char first_array[5][4] = {"aaa","bbb","ccc","ddd","eee"};
char second_array[1][4];
How would I copy, for example, the third element in first_array ("ccc") and save it to second_array?
The syntax below is clearly wrong, but this is what I'm asking for:
second_array[0] = first_array[2];
Also, after copying, I also want to know how to compare elements in the two arrays. Again, the syntax below might be wrong, I'm just explaining what I'm trying to do:
if(second_array[0] == first_array[2]){ printf("yes"); } //should print yes
You can't assign to arrays in c, you can fill arrays with some library functions like strcpy(), so
second_array[0] = first_array[2];
would be
strcpy(second_array[0], first_array[2]);
you must however ensure that the destination array fits the number of characters you are copying to it.
If you try to compare two strings in c, you can't do it through the == operator, because strings in c are arrays of char which contain a sequence of non-nul characters followed by a nul character, so if you write this
if (second_array[0] == first_array[2])
even when you succeeded at copying the data, the result will be most likely false, because you are not comparing the contents of the arrays, but their addresses, so to compare them correctly there is also a function strcmp() then the correct way of comparing the strings is
if (strcmp(second_array[0], first_array[2]) == 0)
The functions above require you to include the string.h header, and also that the passed strings are strings in the c sense, i.e what I described above.
I was recently trying to do this, as well: it is not possible to do this sort of direct assignment in C.
When you write first_array[0], the compiler will read that as an address which points to the first element (character) of first_array[2], not the entire string. When you run the assignment, if it were to work, it would only set the first character.
The easiest way is to use strncpy or memcpy (or a loop to cycle through the string.

C Strings Comparison with Equal Sign

I have this code:
char *name = "George"
if(name == "George")
printf("It's George")
I thought that c strings could not be compared with == sign and I have to use strcmp. For unknown reason when I compile with gcc (version 4.7.3) this code works. I though that this was wrong because it is like comparing pointers so I searched in google and many people say that it's wrong and comparing with == can't be done. So why this comparing method works ?
I thought that c strings could not be compared with == sign and I have to use strcmp
Right.
I though that this was wrong because it is like comparing pointers so I searched in google and many people say that it's wrong and comparing with == can't be done
That's right too.
So why this comparing method works ?
It doesn't "work". It only appears to be working.
The reason why this happens is probably a compiler optimization: the two string literals are identical, so the compiler really generates only one instance of them, and uses that very same pointer/array whenever the string literal is referenced.
Just to provide a reference to #H2CO3's answer:
C11 6.4.5 String literals
It is unspecified whether these arrays are distinct provided their elements have the
appropriate values. If the program attempts to modify such an array, the behavior is
undefined.
This means that in your example, name(a string literal "George") and "George" may and may not share the same location, it's up to the implementation. So don't count on this, it may results differently in other machines.
The comparison you have done compares the location of the two strings, rather than their content. It just so happens that your compiler decided to only create one string literal containing the characters "George". This means that the location of the string stored in name and the location of the second "George" are the same, so the comparison returns non-zero.
The compiler is not required to do this, however - it could just as easily create two different string literals, with different locations but the same content, and the comparison would then return zero.
This will fail, since you are comparing two different pointers of two separate strings.
If this code still works, then this is a result of a heavy optimization of GCC, that keeps only one copy for size optimization.
Use strcmp(). Link.
If you compare two stings that you are comparing base addresses of those strings not actual characters in those strings. for comparing strings use strcmp() and strcasecmp() library functions or write program like this. below is not a full code just logic required for string comparison.
void mystrcmp(const char *source,char *dest)
{
for(i=0;source[i] != '\0';i++)
dest[i] = source[i];
dest[i] = 0;
}

Resources