I want to implement a queue which holds 10 elements of char * array. I searched on the internet but couldn't find enough solutions.
I have a char array:
char str[50]:
char *arr[5];
And the user enters some string with backspace character e.g "Hello I am computer". The string is in str[] array. I token them with strtok() function and assign it to the arr[].Then it becomes:
//arr[0] = "Hello"
//arr[1] = "I"
//arr[2] = "am"
//arr[3] = "computer"
It is ok until now, I am doing it correctly.
Now my question is how to hold this whole arr array in queue's first node or element. There are lots of examples about queue that holding int values and they are easy to understand, but I couldn't do the char * version.
As far as I understood your question you need to implement a queue of type string.
You can do it as you do with any other queue.But instead of int it would of type char* you would also need to pass length of the word so you could dereference that many number of char starting from the char pointer till length of the word.
void Enqueue(char* x, int len)
{
// if empty
front = rear = 0;
// else
rear = (rear+1);
char ch[100];
for(int i=0;i<len;i++) {
ch[i] = *(x+i);
}
Arr[rear] = ch;
}
First of all you have to be careful when saving an address to a variable that you want to use later. You have to ensure that the address hold by the pointer is still valid when you read from it:
int main()
{
char str[] = "Hello I am computer"; // "Hello I am computer" is stored on the stack
AddStringToQueue(str[0]);
}
// str could be overwritten by another function who allocates local variables
As you said in the comment you should use void* malloc(sizeof("Hello I am computer")) which return the start pointer of your allocated memory.
The other thing is why you want to store the string as tokens? Wouldn't it be easier to store the whole string ("Hello I am computer") and use the first character as your start address for the string? If you need it as tokens you maybe can call strtok() after you read out the queue.
Let me make an example:
#define QUEUE_MAX 10
int QueuePos = 0;
char* Queue[QUEUE_MAX];
memset(Queue, NULL, sizeof(Queue));
// call AddStringToQueue("Hello I am computer"); anywhere
void AddStringToQueue(char* string)
{
char* ptr = (char*)malloc(sizeof(string));
memcpy(ptr, string, sizeof(string));
Queue[QueuePos++] = ptr;
if (QueuePos == QUEUE_MAX) QueuePos = 0; // overwrites Queue if max. is reached
}
I am not sure if you mean this.
Hope it helps.
PS: I didn't compiled this so i am not sure if it works, it should just be an example.
Related
tearing my hair out over C strings over here. I have a function in a project which returns a char * pointer.
I need to change an element of that string before using it. Everything I read says just use a char array with the char[] format, but this is not compatible with my project in its current state, if at all.
I have desperately been looking for someway to copy the first n characters to a second char pointer, add the updated value and then concat the remainder of the initial pointer (minus the original value that was updated) that doesnt take 40 lines of code.
Every attempt to use fgetc for this has failed to write the unsigned int to the 'updated pointer'. Do I need to sprintf the unsigned int into a char buffer or something? why does this feel so ridiculously complicated?
An example of a failed attempt at the first steps of the desired behavior:
int main() {
char *s;
s = "babado = lubidee = popop =pew";
char * s1;
s1 = malloc(10);
memset(s1,'0',9);
strcpy(s1,fgetc(s));
for (int i = 0; i<4; i++){
strcat(s1,fgetc(s));
}
printf("%s",s1);
return 0;
}
If you need to just copy a string to another pointer,
.
.
char *newptr;
//Allocate memory for new pointer
int i=0;
while(i<n) //first n characters
*(newptr+i)=*(returnedptr+i);. //returnedptr is your initial ptr
//Add new value
i++;
while( *(returnedptr+i)!='\0')
*(newptr+i)=*(returnedptr+i);
.
.
I'm currently playing around with passing char array to a char pointer. Lots of the examples I see show how you need to allocate the memory that the string pointer will use before copying the char array to it. And when copying, you iterate through the array to store each address into the allocated char pointer.
In the example below I don't initialize the char pointer and neither do iterate through the array. I just pass the pointer of the first element.
int main()
{
char c[10] = "something";
// char* new_c = (char *)malloc(strlen(c)+1);
char *new_c = NULL;
new_c = c;
printf("%s", new_c);
return 0;
}
Why is new_c still printing the entire string? Why do people even bother iterating through the entire array to copy?
Run this program and you will get a clear picture of what is happening
#include <stdio.h>
#include <string.h>
int main(void) {
char c[10] = "something";
char *new_c = NULL;
char new_c_2[10] = "";
new_c = c; // copies address of 'c' to 'new_c'
for(int i=0; c[i]!='\0'; i++) {
new_c_2[i] = c[i]; // copies value of 'c' to 'new_c_2'
}
// Data before changing the value of 'c'
printf("\nData before changing the value of \'c\'\n");
printf("new_c = %s\n", new_c);
printf("new_c_2 = %s\n", new_c_2);
strcpy(c, "changed");
// Data after changing the value of 'c'
printf("\nData after changing the value of \'c\'\n");
printf("new_c = %s\n", new_c);
printf("new_c_2 = %s\n", new_c_2);
return 0;
}
OUTPUT:
Data before changing the value of 'c'
new_c = something
new_c_2 = something
Data after changing the value of 'c'
new_c = changed
new_c_2 = something
char *new_c = NULL;
new_c = c;
These statements are just pointing 'new_c' to the address of 'c'.
So, if you change the value of 'c', and use 'new_c' it will go to the address of 'c' and give the updated value.
We copy the string into another so that we can use the old value even if we change the value of 'c'.
Please refer to call by value and call by reference in C programming for further details.
You say "I don't initialize the char pointer". You do, with
new_c = c;
The array c decays to a pointer, just as if you had passed c directly to printf. And then it is printf which iterates through the array until the zero terminator is found.
Why do people even bother iterating through the entire array to copy?
well, maybe to be sure the original reference isn't deleted/overwritten after a while.
For instance, if the original buffer is a local/automatic variable, which will be invalid after returning from the function.
Or if I just do c[0] = '\0';. new_c doesn't display a thing now because I just killed the only copy of the string.
Both copy & referencing another string through a "shallow" pointer are useful, depending on the use cases.
I wish to split a "string" by the character ','.
The string holds a GPS NMEA encoded string, but that is of no matter.
My problem is that sometimes the parameter from the function that processes this char array is empty... Like nothing is in the array.
How should I correctly pass a "char string[]" to a function so that I may operate on a that parameter as I sent it(as a char array, not a char pointer to an array).
I also need to specify that I'm using mikroC for PIC.
Here is my code as of right now:
char* GPS_sateliti;
char CsatInView[] =
"$GPGSV,3,2,11,14,25,170,00,16,57,208,39,18,67,296,40,19,40,246,00*74";
GPS_sateliti = GrupeazaDupaVirgule(CsatInView, 2);
char* GrupeazaDupaVirgule( char deGasit[],int nrVirgule ){
int cVirgule = 1;
char* pch = strtok (deGasit,",");
while (pch != 0)
{
pch = strtok (0, ",");
cVirgule++;
if(nrVirgule == cVirgule){
break;
}
}
return pch;
}
The function that operates on the char array received as a parameter in debug mode, before entering the function the char array is fine, after entering it, it seems to be empty
It may be that I should receive a pointer to an array of chars??
Any sort of advice is welcome.
Thank you
How should I correctly pass a "char string[]" to a function so that I may operate on a that parameter as I sent it(as a char array, not a char pointer to an array).
You can't. A function parameter of an array type always decays as the corresponding pointer type.
There are two idiomatic solutions to this.
1. a sentinel:
The last value in the array is a special value that marks the end. This is done in C with strings. They always end with a \0 character, that is guaranteed not to occur inside the string. The function can search for that character to know where the data ends.
(Note: with this info I have to add I'm not sure what your problem is. If you pass an "empty string", as literally "", the \0 will be there, so you shouldn't have a problem)
2. explicitly passing the size:
instead of just
void foo(int bar[]);
you define a function
void foo(size_t barSize, int bar[]);
The caller knows the size of the array, so it can just pass it along.
With a pointer :
char* arr;
yourFunction(arr);
If you wish to initialize it before :
char* arr = malloc(51 * sizeof(char)); // Allocate a memory place of 50 because strings are null terminated in C
yourFunction(arr);
An other way to allocate memory to an array :
char* arr = calloc(50, sizeof(char)); // Allocate 50 memory place which size if the size of a char
With a string :
char arr[50];
char* ptr = arr;
yourFunction(ptr);
You have to know that it is impossible in C to know the size of an array when using pointer. The only thing you can do is to parse the size of the string as a parameter :
size_t size = 50;
char arr[size];
char* ptr = arr;
yourFunction(ptr, size);
If you wish to understand in detail how pointer works and how to iterate them, may be this post can help you. I think it is very interesting.
Globally, you iterate through an array via a pointer like this :
for ( int i = 0; i < size; i++)
printf("Current pointed value in the array : %c\n", ptr[i]); // or arr[i]
I guess you understand why giving the size of a pointed array as a parameter is important. Sometimes you can avoid using this parameter like this :
for ( int i = 0; i != '\0'; i++) // Because strings are null-terminated in C.
// Do something
I have a pointer:
char * name;
it contains the string "test:case"
And I'm calling another function with it, and trying to store it in a structure. However, I want to capitalize the entire string first, but It doesn't seem to work.
void func(char * name) {
int i;
List * l;
l = malloc(sizeof(List));
for(i=0; i< strlen(name); i++) {
name[i] = toupper(name[i]);
}
l->name = name;
//CALL A FUNCTION TO LATER FREE ALLOCATED MEMORY
}
Where List is a struct that has a member (char *) named name.
This however, seg faults. I can't go about using non pointers in my case. As I have to use pointers and not character arrays, I'm trying to use toupper in every value of the char pointer, however this doesn't seem to work.
You're getting a segfault because the original string is presumably a literal, and it's not modifiable. You need to make a copy of it first.
void func(char * name) {
List * l;
l = malloc(sizeof(List));
name = strdup(name); // make a copy of name
for (char *p = name; *p; p++) {
*p = toupper(*p);
}
l->name = name;
}
Note that when you later free l, you'll first need to free l->name.
Since you only set the pointer l->name to name, this will crash the moment the original name is no longer there (maybe it was only on the stack?) and l->name is accessed. You need to malloc() space the size of strlen(name)+1, copy name there and set l->name to that address.
You have allocated the List, but not the name string itself.
You need to do:
l=malloc(sizeof(List));
l->name=(char*)malloc(strlen(name)+1); // You need to cater for the the final null char.
There are a few additional issues with your code, here is the correct one (didn't compile it, probably close to okay):
void func(char *name) {
List * l;
l = (List*)malloc(sizeof(List));
l->name = (char*)malloc(strlen(name)+1);
for(char *r=name, char *w=l->name; *r; ++r,++w) {
*w = toupper(*r);
}
*++w='\0';
}
And at every iteration, this code does not evaluate again and again strlen, which would be very bad.
There are two mistakes in the code.
char * name
The variable name contains a pointer to a string (i.e., an array of char).
When you write this:
name[i] = toupper(name[i]);
you are changing the original char itens of the string, if it is not a pointer to a constant string. If that is the case, it is a segmentation fault.
The other mistake is here:
l->name = name;
You are just assigning to the variable within the structure the pointer which was passed on through the variable name to the function. You should make a copy, like this:
strcpy(l->name, name);
This functions copies all the contents from the second argument to the first.
But that's not a good solution. If name contains a pointer to a constant string, it's still segmentation fault.
I'll rewrite your code:
void func(char * name) {
int i;
List * l;
l = malloc(sizeof(List));
char *buffer[strlen(name)]; //buffer of the contents pointed by *name* to upper case, initialized as empty string
for(i=0; i< strlen(name); i++) {
buffer[i] = toupper(name[i]);
}
buffer[i] = '\0'; //closing the string in i = strlen(name)
strcpy(l->name, buffer);
//CALL A FUNCTION TO LATER FREE ALLOCATED MEMORY
}
That way, you manipulate a copy of the original string, and than you make a copy of the buffer to the variable in the structure.
If you do this:
l->name = buffer;
you're only copying a local pointer, which will be gone with the end of the function.
I suggest you learn more about pointers, arrays and strings in C. In essence, a string is a array of char, with a '\0' in the final position. An empty string s has '\0' in s[0].
Edit: if you're used to languages which makes a copy of the string like this:
string1 = string2
you should always have in mind that, in C, that's pointer assignment. So, in C, that code would have to be written like this:
strcpy(string1, string2);
Hope that helps.
I have an array of characters declared as:
char *array[size];
When I perform a
printf("%s", array);
it gives me some garbage characters, why it is so?
http://www.cplusplus.com/reference/clibrary/cstdio/printf/
This url indicates printf takes in the format of: `int printf ( const char * format, ... );
#include <stdio.h>
#include <string.h>
#define size 20
#define buff 100
char line[buff];
int main ()
{
char *array[100];
char *sep = " \t\n";
fgets(line, buff, stdin);
int i;
array[0] = strtok(line, sep);
for (i = 1; i < size; i++) {
array[i] = strtok(NULL, sep);
if (array[i] == NULL)
break;
}
return 0;
}
You declare an array of characters like so:
char foo[size];
You seem to have it mixed up with char *, which is a pointer to a character. You could say
char *bar = foo;
which would make bar point to the contents of foo. (Or, actually, to the first character of foo.)
To then print the contents of the array, you can do one of the following:
// either print directly from foo:
printf("%s", foo);
// or print through bar:
printf("%s", bar);
Note, however, that C performs no initialization of the contents of variables, so unless you specifically set the contents to something, you'll get garbage. In addition, if that garbage doesn't happen to contain a \0; that is, a char with value 0, it will keep on outputting past the end of the array.
Your array is not initialized, and also you have an array of pointers, instead of an array of char's. It should be char* array = (char*)malloc(sizeof(char)*size);, if you want an array of char's. Now you have a pointer to the first element of the array.
Why are we making such a simple thing sound so difficult?
char array[SIZE];
... /* initialize array */
puts(array); /* prints the string/char array and a new line */
/* OR */
printf("%s", array); /* prints the string as is, without a new line */
The char in array after the end of what you want to be your string (ie. if you want your string to read "Hello" that would be the next char after the 'o') must be the terminating NUL character '\0'. If you use a C function to read input that would automatically be appended to the end of your buffer. You would only need to worry about doing it manually if you were individually writing characters to your buffer or something for some reason.
EDIT: As with pmg's comment, the '\0' goes wherever you want the string to end, so if you wanted to shorten your string you could just move it up closer to the front, or to have an empty string you just have array[0] = '\0';. Doing so can also be used to tokenise smaller strings inside a single buffer, just as strtok does. ie. "Part1\0Part2\0Part3\0". But I think this is getting away from the scope of the question.
ie. you wanted to store the first 3 chars of the alphabet as a string (don't know why anyone would do it this way but it's just an example):
char array[4];
array[0] = 'a';
array[1] = 'b';
array[2] = 'c';
array[3] = '\0';
printf("%s\n", array);
If you have something like char array[] = "Hello"; the '\0' is automatically added for you.
char *array[size];
array is not a char * with that, it's more like a char ** (pointer to an array of chars, with is similar to pointer to pointer to char).
If all you need is a C string, either:
char array[size];
and make sure you 0-terminate it properly, or
char *array;
and make sure you properly allocate and free storage for it (and 0-terminate it too).