How do I edit a certain char in the following? [duplicate] - c

This question already has answers here:
how to replace a char in char *
(3 answers)
Closed 6 years ago.
So I have the following code:
char *something = (char *) calloc(LENGTH, sizeof(char));
The length is defined as 10.
I'm imaging it like this in memory:
| [0] | [1] | [2] | [3] | [4] | [5] | [6] | [7] | [8] | [9] | \0 |
How would I change [1] without defining the whole char? And then be able to define [2], and so on...
Each change must not affect the previous change!
Thank you!

The length is defined as 10. I'm imaging it like this in memory
Incorrect. First, there are only 10 bytes (your picture shows 11) and second, all of them are filled with '\0' (which calloc() does).
How would I change [1] without defining the whole char? And then be able to define [2], and so on...
By "change" if you mean assigning values then you can index them like:
something[1] = 'a';
something[5] = 'q';
and so on.
But do remember, using it as a C-string may not work (for example, printing something using printf("%s", something);) since there are intermediate zero bytes.

Your code
char *something = (char *) calloc(LENGTH, sizeof(char));
gives you 10 (not 11) bytes, all initialised to 0.
You can change any byte in here you want
something[1] ='?';
If you use standard routine to e.g. printf this it will of course then find '0' in the first byte and interpret it as the end of a string.
Don't forget to free it when you are done
free(something);

Related

Addresses of elements of type char* in C

If we create a char array:
char strings[3][10] = {"Apple","Banana","Grape"};
and a pointer of type char:
char *pstrings[] = {"Apple","Banana","Grape"};
If we print the addresses of the elements, the char array elements will be 10 bytes apart and the elements of the pointer don't seem to follow one another.
How does your program know where to find the next element of the char pointer if the elements do not follow each other in memory?
Well you are initializing the array of char* with that information.
In fact char*[] contains individual char* pointing to the respective string literal. How does it come? Well "abc" is basically a null terminated char array that decays into pointer to first element of the array which is 'a' and now if that is known it isn't hard to access them. The addresses are being stored basically. In the second case you are initializing the char* array wit those value. Those string literals need not be from contiguous memory.
+-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+
ADDRESS |Random | |Random | |Random |
+-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+
|A|p|p|l|e| |B|a|n|a|n|a| |G|r|a|p|e|
+-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+
\ | /
\ | /
\ | /
+-+-+-+-+-+-+-+-+-+
| 0 | 1 | 2 |
+-+-+-+-+-+-+-+-+-+
That's why you got different values when you printed strings[0], strings[1] etc.
Program just uses the initialized values that is stored in pstrings and that contains the address of those string literals. That's how we use it.
In the first case, same content as your string literals - we are initializing them in the char array which are in turn contiguous.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
ADDRESS |strings + 0 |strings + 10 |strings + 20 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
|A|p|p|l|e| | | | | |B|a|n|a|n|a| | | | |G|r|a|p|e| | | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
| 0 | 1 | 2 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
As a result we can have those modifiable strings each being stored in an array of 10 chars. char p[]="abc"; is equivalent to char p[]={'a','b','c','\0'} same happens here.
Also know one thing, the second case also the pointer values are stored in contiguous memory.
These wonderful ascii-art explanation is provided by Keine Lust.

function to zero array elements

I wrote this code that check suduko answers and for some reason my the array which I sum the squares of the suduko into is all zeros in the functions I zero it in, but when I use it in my check function it isn't all zeros
if i move the exact same code of my array zeroing function to my other function and run it it works.
(i am using c99, dont know if it matters)
Any ideas?
int squareSum[5][5];
//set array elements to zero
setArrayToZero(squareSize, squareSize, squareSum);
/*for(int i = 0; i<squareSize; i++){
for(int j = 0; j<squareSize; j++)
squareSum[i][j] = 0;
}*/
printf("%d, %d\n%d, %d\n\n", squareSum[0][0], squareSum[0][1], squareSum[1][0], squareSum[1][1]);
this is the array is case squareSize is two
if i add the for in the comments in, the array isall zeros, and as you can see below its the exact same as the function i call.
void setArrayToZero(int rows, int columns, int array[][columns]){
for(int i = 0; i<rows; i++)
for(int j = 0; j<columns; j++)
array[i][j] = 0;\\if i print the array in function its all zeros.
p.s
i know i am using only part of the array, its an assignment from the university and we are not allowed to use malloc so i am creating the array at thier max size - 25.
thank you in advance.
full c file:
https://drive.google.com/open?id=1L00L3lvMYNcaz2SswEBnmi9KO-79oaHg
all the print functions, are part of the demand for the course (for auto checking)
A reference to an object of type array-of-T which appears in an
expression decays (with three exceptions) into a pointer to its first
element; the type of the resultant pointer is pointer-to-T.
So that means in this case also (this is not one of those 3 exceptions) your passed array will decay into pointers and now you change to the array by accessing the address, that's why it will be retained in the callee function.
You are doing it the right way. The problem is not with passing or anything. Maybe you are accessing it wrong or maybe you didn't initialize it properly. But there is nothing wrong with the zeroing out.
And for further information everything is pass by value in C. There is nothing called pass by reference in C. The pointer workings makes us think that there is something called pass by reference in C but that's not the case, here also pointer variables are copied into some local variable in the called function. but as we have those addresses in the called function and we access them and make changes - they retain in callee function.
After OP posted the sample code
Apaprt from the overly complicated sudoku checking logic there is much more going wrong.
I will just mention the printing part.
In C elements of 2d-arrays are stored sequentially. When we pass the 2d array to the function we need to specify the column size so that we can determine the correct element.
Suppose you want to access a[4][7] in 10x13 array. The element would be at the address &a[0][0]+4*13+7. That's why the column part is passed as an argument.
Now what you did :
int squareSum[5][5], rowColSum[25][2];
//set arrays elements to zero
setArrayToZero(size, 2, rowColSum);
setArrayToZero(squareSize, squareSize, squareSum);
The first one is alright. As there are 2 columns. But what about the second one?
here you are telling the function that you are passing an array with column size = 2 but that is not the case. It is still the 2d array with 5 columns.
That's where you had the problem. Suppose you initialize the array with 10,21,34,14
Suppose grid is 5x5 array (in your case it's 25x25)
grid[5][5] array
And you do this
for(int i = 0; i<squareSize; i++)
for(int j = 0; j<squareSize; j++)
scanf("%d",&grid[i][j]);
/*
Input is 13 17 19 23
*/
+-----+-----+-----+------+-----+-----+-----+----+----+----+--...\
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
+-----+-----+-----+------+-----+-----+-----+----+----+----+--...\
/ \ \ / \ \
13 17 19 23
Now you access it like this
You pass it to the function with this call print2dArray(int row, int col, int g[][col])
You call like this `print2dArray(2,2,grid);``
...
for(int i = 0; i<row; i++)
for(int j = 0; j<col; j++)
printf("%d",&grid[i][j]);
Now you will print these elements (i) : denotes the order
+-----+-----+-----+------+-----+-----+-----+----+----+----+--...\
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
+-----+-----+-----+------+-----+-----+-----+----+----+----+--...\
/ \ \ ^ ^ / \ \
13 17 | | 19 23
(1) (2) (3) (4)
Similarly, those were uninitialized in your case. That's why you got those weird results. You were initializing some elements of the 2d array to 0 but when you are reading the array then you were accessing some different elements. That's why the wrong result.
Solution for this:
Call int correctSum = inputGrid(squareSize, 25, grid); Note that it should be squareSize. Accordingly change the storage of digitsCounter in inputGrid.
The function signature for inputGrid would be inputGrid(size, col, grid[][col]);
Same when calling the
setArrayToZero(size, 2, rowColSum); and
setArrayToZero(squareSize, 5, squareSum);
I simply didn't check the logic. The answer deals with explaining the printing behavior of the 2d array.

How to print a single character from an array of strings using printf?

Let's say I have
char *names[] = { "Tom", "Jerry" };
and I want to print the "e" in "Jerry" using printf. My first instinct was
printf("%c\n", *names[5]);
but when I applied what I've been learning about pointers, I realized this is total junk code because the 5 refers to the nonexistent fifth pointer in names, not the "e" in "Jerry". The pointers contained in names will only ever refer to the memory addresses of the first characters in their respective strings.
So it seems what I really need to do is to add one byte to names[1] to point to, and print the "e" in "Jerry". But I'm not sure how to do this, or whether it's even allowed in C.
What is the best way to accomplish this? Thank you in advance.
I think what you're looking for is printf("%c\n", names[1][1]);.
The thing is that you don't have a multi-dimensional array, you have a single-dimension array containing pointers to arrays.
In memory your array looks something like this:
+----------+----------+
| names[0] | names[1] |
+----------+----------+
| |
| V
| +---------+
| | "Jerry" |
| +---------+
V
+-------+
| "Tom" |
+-------+
The above image should make it clear that when you do *names[5] you first of all must remember that the compiler deciphers that as *(names[5]), which means that you try to dereference the sixth entry in an array of only two entries. That will lead to undefined behavior.
Take the second string: names[1], add one to point to the second character: names[1]+1, and dereference to get what you point at: *(names[1]+1), which also equals to names[1][1]
names[1] -----v
names[1]+0 ---v
v
"Jerry"
^
names[1]+1 ----^
*(names[1]+1) == 'e'
names[1][1] == 'e'
Access the jth character of the ith string as (0-indexed) :
names[i][j];
names[ nameIndex ][ characterIndex ]
So if you want to print the "e" of "Jerry" :
printf("%c\n", names[1][1]);
Or the "m" of "Tom" : printf("%c\n", names[0][2]);
the best way with pointers to print 'e'(second char of value) of Jerry(second value in the array) is *(array[1]+1) (1 for second value and char because we start with 0 in c )

Trouble with array pointers in C

I was solving last years GATE question paper where i am stuck with this question
What does the following fragment of C-program print?
char c[]="GATE2011";
char *p =c;
printf ("%s", p+p[3]-p[1]);
The answer is '2011'
I am aware that in c, array variables are pointer to first address of the array. My logical answer was 'E2011', but the output is 2011
Can someone explain the pointer mathematics involved in this?
This problem has much more to do with ASCII values than it does with pointers.
p[3] == 'E' == 69 (decimal)
p[1] == 'A' == 65
p[3]-p[1] = 4
p+4 = A string starting at the 4th character.
p[] = [0] [1] [2] [3] [4] [5] [6] [7] [8]
G A T E 2 0 1 1 \0
Hence, p[4] = 2011
p[3] = A
p[1] = E
E - A = 4
hence p + 4 = address of 2
hence it prints 2011

Dynamic Multidimensional array

I need a multidimensional array of chars that is dynamic in only one dimension...
I have to store a pair of strings with a length of 10 (or less) chars each, but with a variable number of "pairs".
My idea was this
char (*instrucao)[2][10];
Which gives me a pointer to a 2x10 array of chars, but this is not working properly when i do something like this:
char strInstrucoes[117], *conjunto = calloc(21, sizeof(char));
instrucao = calloc(1, sizeof(char[2][10]));
conjunto = strtok(strInstrucoes,"() ");
for(i = 0; conjunto != NULL; i++){
realloc(instrucao, i+1*sizeof(char[2][10]));
sscanf(conjunto,"%[^,],%s", instrucao[i][0], instrucao[i][1]);
printf("%s | %s\n", instrucao[i][0], instrucao[i][1]);
conjunto = strtok(NULL, "() ");
}
Having strInstrucoes as (abc,123) (def,456) (ghi,789), I don't matrix with 3 lines of 2 pairs each like this:
abc | 123
def | 456
ghi | 789
but instead this is what I'm getting:
abc | 123
def | 45def | 45de
ghi | 789
What's the right way to do this?
Thanks!
You should assign the pointer the new address realloc returns
instrucao = realloc(instrucao, (i+1)*sizeof(char[2][10]));
Note that for error checking, you may desire to assign to a new pointer and check for NULL. Also note the parens - you basically just added i instead of multiplying with the required size. Easily overseen.
Note that there is no need for the initial calloc. Just initialize instrucao to NULL, and realloc will behave like malloc when first passed a null pointer.
You would do much better to find a library with a container that will meet your needs. At the very worst, using none of the much better libraries, you could have two separate arrays, each of them holding half of the pair.

Resources