I'm beginner of programmer. I not understande why can't copy some script from array to another one.
char array1[11];
char array2[2];
array1 = {'255 105 85'};
array2[0] = array1[0];
array2[1] = array1[1];
array2[2] = array1[2];
MessageBox(hwnd,array2,"mes",NULL);
I was get "5" instead of "255".
I using the code::blocks with GCC complier.The project created with win32 frame based.
Somebody has idea what cause the problem?
The following construct is not allowed in C:
array1 = {'255 105 85'};
Instead you might consider using the static array initialization like this:
char array1[11] = {255, 105, 85};
This will fill the array1 with 3 specified values and leave all the other elements set to 0 (i.e. elements starting with index 3 and ending with index 10).
It's rather surprising, why the compiler didn't issue a syntax error in your case
updated:
Please also note that you are manipulating with individual characters when you have an expression like this array1[2]. If you want to operate on strings (i.e. have 3 separate strings for the numbers you have specified), you will have to declare something like this:
char *array1[3] = {
"255",
"105",
"85"
};
char *array2[3];
array2[0] = array1[0];
array2[1] = array1[1];
array2[2] = array1[2];
Thus you will have an array of strings. Each entry of array1 will contain a pointer (address) of the memory where string "255" is located (please note that "255" is an array comprising 4 chars: '2', '5', '5', '\0').
Array1 should be declared like this:
char array1[] = {0x255, 0x105, 0x85};
single quotes are for single chars in ascii, like 'a' or '6' or '!'.
Also, array2 is of length 2, but you are assigning a value to the third value (array2[2]). This is probably an error.
Related
I have an array of strings in C:
char taula[15][15];
This table is filled with the sentences of a file. The maximum letters a word can have is 15. The maximum words a phrase can have is also 15. This is its content:
{ "may", "the", "force", "be", "with", "you." }
Now, I need to change the order of the words so they are not in this order (but that doesn't matter for the question).
I am new to C, and what my brain has though is this (this is what I would do in Java):
char aux[15] = "";
char frase_nova[15][15];
for(i=0;i<15;i=i+2) {
aux = taula[i];
taula[i] = taula[i+1];
i++;
}
I create an aux variable to store a word, and create a new array to store the disordered phrase. I store the 1st element to the aux variable. Assign the 0th element to the 1st, and finally I assign the aux to the 0th element, and so on. This way I should get this phrase as result:
the may be force you. with
This has caused me an error, so I searched why, and I changed that code to this code, using strcpy:
strcpy(aux,frase_nova[i+1]);
strcpy(frase_nova[i+1],frase_nova[i]);
strcpy(frase_nova[i],aux);
printf("%s",frase_nova[i]);
But this causes me a strange result. Something that I don't understand is happening with the pointers and the arrays or whatever it is.
the E�Ube you.��aE�URE�U
So I would like to know how to fill a new multidimensional char array with values of an original multidimensional char array in the order ([i]) I want.
The maximum letters a word can have is 15.
Then you should have size of words, in 2D char array, as 16 and not 15
char taula[15][16];
^^
because, in C, strings are actually one-dimensional array of characters terminated by a null character '\0'. Hence, you need space to accommodate null character '\0'.
Your array has 6 strings i.e. 3 pairs, so you need iterate loop only 3 times. But, looks at this for loop:
for(i=0;i<15;i=i+2) {
it will iterate for more than 3 times. May you can keep track of number of elements in your 2D array and use it instead of 15 in the loop condition.
As you understood that these statements, of for loop body, won't work:
aux = taula[i];
taula[i] = taula[i+1];
because both aux and taula are arrays. But there is one more problem in your loop body and which is this statement:
i++;
You are already incrementing i in loop - i=i+2 and if you do i++ in loop body then, in every iteration, i will be incremented by 3 and which will not give the desired results. You don't need to do i++ in loop body.
There is no problem with these statements:
strcpy(aux,frase_nova[i+1]);
strcpy(frase_nova[i+1],frase_nova[i]);
strcpy(frase_nova[i],aux);
printf("%s",frase_nova[i]);
provided
if the array frase_nova has elements { "may", "the", "force", "be", "with", "you." }, and.
loop variable i is incremented twice only in every iteration.
Check the following code:
#include <stdio.h>
#include <string.h>
#define WORDS 15
#define WORD_SZ 16
#define NUM_ELE 6
int main(void) {
char frase_nova[WORDS][WORD_SZ] = { "may", "the", "force", "be", "with", "you." };
char aux[WORD_SZ] = "";
for(int i = 0; i < NUM_ELE; i = i + 2) {
// using your posted statements as it is
strcpy(aux, frase_nova[i + 1]);
strcpy(frase_nova[i + 1], frase_nova[i]);
strcpy(frase_nova[i], aux);
printf("%s ", frase_nova[i]);
}
printf ("\n");
for (int i = 0; i < NUM_ELE; ++i) {
printf ("%s ", frase_nova[i]);
}
printf ("\n");
return 0;
}
Output:
# ./a.out
the be you.
the may be force you. with
So I would like to know how to fill a new multidimensional char array with values of an original multidimensional char array
This is not clear whether you want to fill the new multidimensional char array with the values of original multidimensional char array before swapping the strings of original array or after swapping the strings. But, whatever you want, you can simply achieve it by doing this - strcpy(frase_nova[i], taula[i]).
To swap 6 words you need to iterate 6 times, not 15 times. Unless you simply wish to shuffle words around according to some strange pattern.
Also the loop doesn't make any sense. I don't understand why you do i=i+2. Also any loop of the nature for(int i=0; i<n; i++) can never access item array[i+1] in the loop body, because that leads to out of bounds access.
I am still a C programming newbie.
I have heard the character string has always '0' or '\0' as the final character.
Then I have a one question. why the sample line below has '5' at the last position?
Why isn't it '0' or '\0'?
int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
The line above from How to initialize all members of an array to the same value?
char cArr1[] = {'a', 'b', 'c'};
char cArr2[] = "def";
int iArr3[] = {1, 2, 3};
int iArr4[5] = {1, 2, 3};
memory layout
=============
var name memory address value
cArr1 AAAA0000 'a'
AAAA0001 'b'
AAAA0002 'c'
AAAA0003 unknown (may have a '\0' by chance)
...
cArr2 BBBB0000 'd'
BBBB0001 'e'
BBBB0002 'f'
BBBB0003 '\0' is inserted by the compiler
...
iArr3 CCCC0000 1
CCCC0004 2
CCCC0008 3
CCCC000C unknown (may have any value)
...
iArr4 DDDD0000 1
DDDD0004 2
DDDD0008 3
DDDD000C 0 (not defined explicitly; initialized to 0)
DDDD0010 0 (not defined explicitly; initialized to 0)
...
Strings are character arrays the actual elements of which are terminated by zero character. And most standard C string functions relay on this convention.
This
int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
is an integer array. Zero is a valid integer value. And it is used very often as an actual value of an array among other integer values.
Of course you can make zero a sentinel value of an integer array. But there are no standard C functions that use zero as a sentinel value for integer arrays.
"Why can this sample line have not 0 OR '\0' character at the end of the array?"
Because myArray is an array of int (and does not contain a string)! A null terminator (for strings) can only be applied to char, but not int arrays.
And even an array of char does not a null terminator per se. Only if the array of char should contain a string and you want to use the content of the array as string, a null terminator is required.
Beside that, an array of int can of course hold the int value 0 inside of the last element but you currently intermix two different things here.
I have a char*. I want to parse it, character by character, and store the location of each in an int*.
With the dummy-string "abbcdc", the content should be as follows
char int*
-------------
'a' -> 0
'b' -> 1,2
'c' -> 3,5
'd' -> 4
I want this to be accessible through a char* containing the entire alphabet, so that each character in the alphabet-pointer points to each separate integer-pointer. This is where I'm lost.
I know I can point to a pointer using the double-asterisk syntax
int **a = &aLocations;
But I don't really know how to refer to the locations-pointer by using a character as a reference. I am pretty new to C, so all pointers (pun intended) are appreciated.
Update 1:
int *aLocations = malloc(3*sizeof(int));
aLocations[0] = 13;
aLocations[1] = 9;
aLocations[2] = 57;
int **a = &aLocations;
This seems to work as expected, but a obviously remains an integer, not a char. I was thinking of writing a function something along the lines of
int *getCharLocations(char c) {
// returns a pointer to the stored character locations
}
but I don't know how to proceed with implementing it.
Ok then.
Although it would be possible it would be pretty ugly and complicated.
So if you do not mind i would suggest to drop char and use integers exclusively.
It is possible since char is in fact just small integer.
So first you would need to create your two dimensional alphabet array:
int *alphabet[26]; // this will create 26 element array of integer pointers
Now we will fill it:
int i = 0;
for(i = 0; i < 26; i++) {
alphabet[i] = malloc(100 * sizeof(int)); //alloc memory for 100 integers (should be enough for human language if we're talking about single words here)
alphabet[i][0] = 'a' + i; // this will put a letter as first element of the array
alphabet[i][1] = 2 // here we will keep index of first available position in our indices array
}
So now we have array like this:
'a', 2, ... // '...' means here that we have space to fill here
'b', 2, ...
...
'z', 2, ...
And you can add indices of occurences of letter to such construction like this:
alphabet[index_of_letter][alphanet[index_of_letter][1]] = index_of_letter; //put index at the end of array
alphabet[index_of_letter][1]++; // increment our index of available position
That's pretty much it.
I didn't test it so it may need some polishing but such approach should do the trick.
PS.
Someone in comments above noted uppercase letters - in such case you would need to extend array to 52 characters to store also occurences of uppercase letters (also fill first element with uppercase letter in for loop for such records). But i guess you will manage from now on
In MATLAB, when code like this is implemented:
c = ['a','b','c','d'];
you can't really do anything with the elements. To illustrate my example:
>> c
c =
abcd
and when you do c(1,1) it returns A. But for c(2,1) it returns Index exceeds matrix dimensions.
To combat this problem, is there any way I could get around it? Or perhaps a different type of array?
You need to store each string in a different row, like so:
c = ['a';'b';'c';'d'];
What you have done above is use the [], which is the string concatenation operator. What it outputs is a single string, 'abcd', stored in c(1), which is why c(2) throws an index error.
Alternatively, you could use cell arrays :
c{1} = 'a';
c{2} = 'b';
This is my code
#include <stdio.h>
int main()
{
char *fruit[] = {
"Water",
"banana",
"pear",
"apple",
"coconut",
"grape",
"blueberry"
};
int x;
int g;
for(x=0;*(fruit+x)!='\0';x++)
{
for (g=0; *(*fruit)++; g++)
{
putchar(*(*(fruit+x)+g));
}
putchar('\n');
}
return(0);
}
And this is what the code returns...
aeaa
banana
pear
apple
coconut
grape
blueberry
Program ended with exit code: 0
I don't understand what I'm doing wrong... Why the first point goes wrong and the others pointers display as I expect.
Can anyone please explain? I'm using Xcode.
To understand what is going on you should place a breakpoint on your first for line, run the code till it stops and then step through watching the values of fruit, x & g. If you do this you'll notice something strange - after the first time around the outer loop the first element of fruit changes to banana (the remaining entries stay the same, so you now have two bananas).
Do this now and watch. If you can't use the debugger stop now and figure it out.
So what is happening?
First let's look at what your code outputs:
ae?aa (? is actually upside down on my run)
banana
etc.
Where could those characters be coming from? Well if the compiler packs your strings into memory, remembering that each string ends in a null byte which we will represent by ? then packed into memory you have:
Water?banana?pear?apple
etc. Your program is printing out 5 characters, the number in Water, and they are the 2nd, 4th, 6th, 8th and 10th in memory...
So now we know what we're seeing, why are we seeing it?
Let's look at fruit, it is a 1-dimensional array of char * - pointers into memory containing the characters in the strings. If we look at the first few pointers in this array when I run your code they are (actual values may differ):
0x100000e24
0x100000e2a
0x100000e31
Looking at just the last two digits, and converting from hexadecimal, we have 36, 42, 49. The first difference is 6, the number of bytes needed to store "Water" (including the trailing null byte), the next is 7, the number of bytes needed to store "banana", and so it goes on.
Now let's look at your first for loop:
for(x=0; *(fruit+x) != '\0'; x++)
Now *(fruit+x) is the same as writing fruit[x], so in each iteration of the loop you are looking at an element of fruit starting with the first (index 0). Now fruit contains values of type char * but you are comparing the value to a char - they are not the same thing!
When C constructs an array with unspecified bounds (the empty [] in the declaration of fruit) from a literal as you've done here it does not add anything after the last element of the array to indicate there are no more elements. There are two common ways to deal with this: you can calculate the number of elements using two calls to sizeof (see #Lundin's answer); or you can use a sentinel - a value which will not occur in the array otherwise. For arrays of pointer values the standard sentinel is NULL - the pre-declared pointer to nothing. So to make this part of your code work we change the code to:
char *fruit[] =
{
"Water",
"banana",
"pear",
"apple",
"coconut",
"grape",
"blueberry",
NULL
};
int x;
int g;
for(x=0; *(fruit+x) != NULL; x++)
This loop will now set x to the values 0 through 6.
Now let's look at your inner loop:
for (g=0; *(*fruit)++; g++)
To reduce the stars circling our heads, let's replace *first by first[0]:
for (g=0; *(fruit[0])++; g++)
So *(fruit[0])++:
Obtains the value in the first element of the array (fruit[0]), which is a pointer (char *) to the first character of the string "Water";
Indirects via that pointer (*(fruit[0]) to obtain a single character, which is W;
Implicitly compares that character to the null byte - the test part of the for; and
Increments the pointer stored in the first element of the array
So after the first iteration of this loop the fruit array contains (assuming values as above):
0x100000e25
0x100000e2a
0x100000e31
The first element has now changed to point at the a in "Water". As you are reading the array to print it you are also changing it - probably not a good idea.
Also note that this loop always references the first element of the array, it never moves past it however many iterations of the outer loop occur - this loop is not stepping through the elements of fruit either - to do that you would need to reference x somewhere, which you do not in the for itself, but you do in the body:
putchar(*(*(fruit+x)+g))
which re-written using indexing is:
putchar(fruit[x][g])
which outputs the g'th character of the x'th element of fruit. This would make sense if the array fruit was not being modified, however as we've just determined the first element of fruit now references the a in "Water", x & g are both zero, so this outputs a and not W as you hoped.
Now consider the second iteration, the for loop examines the a and find it is not the null byte, so fruit[0] is incremented to reference the t in "Water" and g is incremented to 1. Now the putchar looks up the first element of fruit, which is referencing "ter..." having been incremented twice, g is 1 so the second character is selected, which is e, and that is output.
In each iteration you are incrementing the pointer in fruit[0] and incrementing g, so the sum increments by 2 each time and the putchar outputs the 2nd, 4th, 6th, 8th and 10th characters in memory... As the strings follow each other you get a, e and the null byte from "Water" and two a's from "banana".
As your program continues fruit[0] marches through memory but as the putchar uses x and so references the unchanged pointers in fruit[1] onwards the remaining strings, by luck, print out correctly. If you don't add the sentinel to the array the outer loop keeps marching through memory until a zero byte is found - so you may get garbage printed after blueberry as well.
So how do you fix this?
Well you should never have been altering fruit[0] in there first place, and you should be referencing x in your inner for to step through the array.
Keeping close to your original code a solution is to copy the pointer stored in fruit into a local variable and increment that to walk through the string:
char *fruit[] =
{ "Water",
"banana",
"pear",
"apple",
"coconut",
"grape",
"blueberry",
NULL
};
int x;
int g;
for(x=0; *(fruit+x) != NULL; x++)
{
char *p = *(fruit+x); // copy the x'th pointer from fruit and store it in p
for (g=0; *(p+g); g++) // step through the string incrementing p (not the x'th element of fruit)
{
putchar(*(p+g));
}
putchar('\n');
}
HTH
You forgot to NULL terminate your array:
char *fruit[] = {
"Water",
"banana",
"pear",
"apple",
"coconut",
"grape",
"blueberry",
NULL
};
You have been hit by undefined behavior.
Then use just puts like
for(x=0;fruit[x]!=NULL;x++)
puts(fruit[x]);
Please compile with all warnings and debug info (perhaps gcc -Wall -g) and use the debugger (gdb probably) - run your code step by step and print or display some relevant variables (like x or fruit)
The code is needlessly complicated. Is there a reason why you can't simply do like this?
#include <stdio.h>
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(*arr))
int main()
{
const char *fruit[] =
{
"Water",
"banana",
"pear",
"apple",
"coconut",
"grape",
"blueberry"
};
for(int i=0; i<ARRAY_SIZE(fruit); i++)
{
puts(fruit[i]);
}
return 0;
}