I am creating a program and part of it needs to take a word, and jumble the letters.
I know that there is officially no string data type within C, so technically the characters in the word are already in array? They just need sorting. (That is my understanding anyway).
I also know that C isn't very good for actual random numbers, I normally use the time as the seed, not sure if this would affect shuffling the letters.
For instance:
The word Hello
Split into Characters H/E/L/L/O
Shuffled E/L/O/H/L
New word Elohl
technically the characters in the word are already in array?
You can treat them like a null-terminated array of characters. Apply your favorite shuffle algorithm to the portion of the string between 0, inclusive, and strlen(str), exclusive to produce a shuffled string.
The only catch here is that not all strings can be shuffled in place. Specifically, strings representing string literals are not writable. Trying to change them would lead to undefined behavior.
For example, if you do
char *word = "hello";
shuffle(word);
and try to modify word's characters inside shuffle, you would get undefined behavior. You need to copy the content into a writable array before you can shuffle the content - for example, like this:
char word[] = "hello";
shuffle(word);
int compare(const void *a, const void *b){
return *(const char *)a - *(const char *)b;
}
char arr[] = "dbaurjvgeofx";
printf("Unsorted: %s\n", arr);
qsort(arr, strlen(arr), 1, compare);
printf("Sorted: %s\n", arr);
Related
I have an array of pointers to string:
char *TAB[3] = { "dafafa", "alfkasf", "bafgr" };
I would like to sort characters in in each of those strings.
My compare function:
int cmp(const void *a, const void *b)
{
return *(char *)a - *(char *)b;
}
and while trying qsort on one of these:
qsort(TAB[0], 6, sizeof(char), cmp);
The program doesn't work.
After many efforts I found that the reason of the problem is in delivering TAB[0] to qsort().
Can anyone explain why it doesn't work and how to fix that?
If you want to sort characters inside each string, the first thing you must ensure is that your strings can be written to. As it currently stands, your strings are read-only, so you cannot sort their characters without copying their content into memory that allows writing.
Next thing is that you need a loop. Since you are sorting each string individually, you need to loop through the array, and call qsort on each item. The initial item is TAB[i], and the length is strlen(TAB[i]). Your cmp function will work.
Newbie to programming (school) and I'm a little confused on what/why this is happening.
I have a loop that is iterating over an array of elements, for each element I am taking the integer of the array, converting it to a char using the function getelementsymbol, and using strcat to append to my temp array. The problem I am having is that the elements of my temp array contain the residual of the element proceeding it. This is the snippet of my code. The output I receive is this:
word1
word1word2
word1word2word3
char* elementsBuildWord(const int symbols[], int nbSymbols){
/* ROLE takes a list of elements' atomic numbers and allocate a new string made
of the symbols of each of these elements
PARAMETERS symbols an array of nbSymbols int which each represent the atomic number
of an element
nbSymbols symbols array's size
RETURN VALUE NULL if the array is of size <= 0
or if one of the symbols is not found by our getElementSymbol function
other the address of a newly allocated string representing the concatenation
of the names of all symbols
*/
char s1[MAX_GENERATED_WORD_LENGTH];
int y;
char *s2;
size_t i;
for (i = 0; i < nbSymbols; i++){
y = symbols[i];
s2 = getElementSymbol(y);
strcat(s1, s2);
}
printf("%s ", s1);
}
Firstly, your s1 is not initialized. strcat function append a new string to an existing string. This means that your s1 has to be a string from the very beginning. An uninitialized char array is not a string. A good idea would be to declare your s1 as
char s1[MAX_GENERATED_WORD_LENGTH] = { 0 };
or at least do
s1[0] = '\0';
before starting your cycle.
Secondly, your getElementSymbol function returns a char * pointer. Where does that pointer point to? Who manages the memory it points to? This is non-obvious from your code. It is possible that the function returns an invalid pointer (like a pointer to a local buffer), which is why might see various anomalies. There's no way to say without seeing how it is implemented.
strcat is supposed to append to a string. use strcpy if you want to overwrite the existing string. You could also use s1[0] = '\0'; before strcat to "blank" the string if you really want to, but looks like you really want strcpy.
From the snippet above it's not even clear why you need s1 - you could just print s2...
How would i get the lengths of the belowed strings, as well as the array size?
char str [] = {};
str[0] = "He";
str[1] = "llo";
str[2] = " Wor";
str[3] ="ld";
And how i could store them in a multidimension array? So this array would look something like this:
char strstr [size of str][string length of str];
The strstr[][] array-dimensions should be
1.number of array-elements of str and
2.number of all chars in str. In the case of strstr[3][1], this would be "d".
Would that be possible without initializing the str-array in the first place?
[edit]
I see, the second dimension of strstr doesn't make sense. It should be the length of every element from *str and not the complete number of chars in *str
[/edit]
This will probably do what you want, but it wasn't exactly what you asked for.
#include <stdio.h>
char *strs[] = {
"foo",
"bar",
"bazy"
};
int main() {
printf("%d - %s\n", strlen(strs[0]), strs[0]);
printf("%d - %s\n", strlen(strs[1]), strs[1]);
printf("%d - %s\n", strlen(strs[2]), strs[2]);
return 0;
}
Output:
3 - foo
3 - bar
4 - bazy
Note that you only have a few possibilities for storing arrays of arrays. You can either do what this solution does (make an array of pointers to arrays), make a "compressed" list of arrays in a large array, or make an overly large 2-D array.
The "compressed" array would take the format:
char strs[] = "foo\0bar\0bazy"; // array is {f,o,o,\0,b,a,r,\0,b,a,z,y,\0}
The problem with this format is that it's somewhat tricky to access anything after the first element, and usually involves searching linearly through the array. (or keeping a seperate table of addresses... rather like the first solution)
The 2-D array requires that you specify all sizes, and looks like this:
char strs[3][5] = {
"foo",
"baz",
"baxy"
};
int main() {
printf("%d - %s\n", strlen(strs[0]), strs[0]);
printf("%d - %s\n", strlen(strs[1]), strs[1]);
printf("%d - %s\n", strlen(strs[2]), strs[2]);
return 0;
}
This is probably laid out in memory like this:
{f,o,o,\0,*,b,a,z,\0,*,b,a,x,y,\0} (the *'s could be anything, most dependent on your compiler)
Since the compiler knows that each string takes exactly 5 bytes, it can easily calculate the location of the later elements.
When declaring an array in C, you must declare its size unless you are simultaneously providing initializing values. This is because arrays are laid out sequentially in memory, and so the computer needs to know how much space to set aside.
Further, char str [] = {....} will declare an array of characters, not an array of strings. A string is an array of characters, so str is just a single string.
To create an array of strings, you need to do something like this:
char strs[num_of_strings][max_length_of_strings+1];
strcpy(strs[0],"string1");
strcpy(strs[1],"string2");
...
There's a more in depth discussion of other options at this question.
If you're specifying max_length_of_strings but then copying from source strings that you can't guarantee are shorter than max_length_of_strings, you want to use strncpy instead of strcpy. In that case you also want to ensure that the resulting strings are null terminated, which you can do by looping
strs[i][max_length_of_strings] = '\0';
To get the length of a null-terminated string, you use the function strlen.
As to the second part of your question, the above should make it clear how to create a higher-dimensional array. I'd provide more detail, but I'm not exactly sure what you want this array to do. When you say "number of all chars in str" do you mean the max length of the strings stored in your strs array?
If so, you don't need to worry about that. Programming your strs array like I explained it above will already give you this functionality: since strings are just arrays of char's, you can index into strings in the same way that you index into char's.
Let me know if any of the above isn't clear, and I'll try to explain it better.
If you want an actual array, something like this:
char str[4][5]; // holds up to 4 characters in each
strcpy(str[0], "He");
strcpy(str[1], "llo");
strcpy(str[2], " Wor");
strcpy(str[3], "ld");
To get the length of a string in C you'd use strlen and pass the string.
int len = strlen(array[0]);
As a learning technique, i'm suppose to make my own copy of the following string function in
char * mystrcpy(char *a, char *b);
// string copy. destroys a but not b.
// identical to strcpy in <string.h>
// running time O(mystrlen(b))
I've come with this
char * mystrcpy(char *a, char *b){
a = b;
return a;
}
since string a is a random chuck in memory I'm thinking to assign just to string b ... is my interpretation correct ?
accessing a specific char [in index i] in string is done using a[i], just like an array. [remember that in C, a string is actually an array of chars].
You should iterate the strings until you "see" a '\0' char - which indicate the end of string.
Yes, comparing to chars with operator< is comparing them by their ascii value - which is probably what you need.
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.