So I have a structure, and one of its members is a string.
struct Output {
char *axis;
int value;
};
struct Output Jsoutput;
My question is, how do I store a string in axis?
char whichaxis[4][3] = {"LX","LY","RY","RX"};
// Store which axis and value of the joystick position in Jsoutput
Jsoutput.axis = whichaxis[jse.number];
printf("%s\n",Jsoutput.axis);
I feel like there should be some & somewhere, but not sure where.
Just use strdup
Jsoutput.axis = strdup(whichaxis[jse.number]);
You can copy a String with the function strcpy(destination, source)from string.h
see http://www.cplusplus.com/reference/cstring/strcpy/
Jsoutput.axis = malloc(3);
strcpy(Jsoutput.axis,whichaxis[jse.number]);
You don't have to "store" the string a second time.
char whichaxis[4][3] = {"LX","LY","RY","RX"};
Stores the string.
char *axis;
Says "I'm going to point at a string".
If you wanted a & in there, you could do:
Jsoutput.axis = & (whichaxis[jse.number][0]) ;
But the original designers of C were very pragmatic and let arrays turn into pointers all the time for convenience. See What is array decaying for more details.
Related
I have been rethinking my way of asking. so i edited the question.
i know beforehand how many strings there will be in the array because it is menu text.
suppose i have an array of strings declared as so:char *menu_item[4];
this should give me an array that can hold 4 strings right?
i want to be able to pass the string array to other functions so is this the way to do it?
This array is not declared in main. but in a function that is called from main.
will i have to allocate memory to use fx strcpy(menu_item[1],"some text");
and if yes. what should i allocate??
or is menu_item[0] = "some text"okay??
i have a function in a function to print out the strings which takes a char *string as parameter. and the function itself takes a string array as so char *items[] it looks like this:
void scroll_menu(char *items[], int size){
for(int i = 0; i < size; i++){
print_out(items[i]);
}
}
is the parameter correct for a string array?
i have been looking through a lot of question online. and cant seem to find anything that solves my problem.
if any doubt i will recap what it is i want:
i want to declare an array of strings which holds a known number of strings. sometimes the strings can be initialized in the declaration of the array. and other times i have to look up somewhere and then "assign" or copy the result to the array.
i want to be able to copy or assign strings to it from functions returning a char *string like so strcpy(menu_item[0], some_function_returning_string());
my problem is that i have tried so many different things that i am left confused. and have misunderstood the string array operations.
i have also tried with char menu_items[4][20]; and then strcpy(menu_items[0], "some text"); without any luck. and then there is the issue with how to make the function accept an array declared like this.
any suggestions on how to accomplish what i want would be very nice.
EDIT
i took some time reading the c programming book and found what i was looking for.
if i declare an array of pointers to strings as so char *menu_items[4] i will have an array that can take 4 pointers to strings or char arrays char *string
if i want to assign a string from a function returning a char * i have a function as so:
char *function_returning_string(int x){
static char *strings[3] = {"this","is","strings"};
if(x <= 2){
return strings[0];
}
else if(x > 2){
return string[1];
}
else{
return strings[2];
}
}
the code from where i call this function i have the following:
static char *other_strings = {"yes", "no"};
char *menu_item[3];
menu_item[0] = "ok";
menu_item[1] = other_strings[0];
menu_item[2] = function_returning_string(3);
then i can just pass the entire string array to functions that takes a *string_array[] as parameter as so function_takin_string_array(menu_item); or any string inside to functions taking char *string as parameter as so function_taking_string(menu_item[2]);
the code compiles without errors and works. if anybody think there is something wrong about the code or if have have misunderstood something please let me know.
As MFisherKDX noted this part of a code is incorrect:
static char *addr;
sprintf(addr, "S %d", i + 1);
return addr;
How do you think what are you returning here? It should be failed on sprintf() call because you try to assign some value to unallocated memory. It should be like this:
static char addr[128];
sprintf(addr, "S %d", i + 1);
return addr;
And how PeterJ_01 mentioned above try to use gdb to figure out what is wrong and where you have other mistakes.
I made a simple structure with both integer and char types, I am facing an Lvalue required error when assigning "Structures" to my LE structure string. I don't understand why because that's normally how I would assign a string.
#include<stdio>
#include<conio>
struct Lesson{
int lessonNumber;
char lessonName[80];
}LE;
main(){
LE.lessonName = "Structures";
LE.lessonNumber = 1;
printf("%s",LE.lessonName);
printf("%d",LE.lessonNumber);
getch();
}
One easy way to go about is (If you don't want to call strcpy):
#include<stdio.h>
struct Lesson{
int lessonNumber;
char *lessonName;
}LE;
int main(void){
LE.lessonName = "Structures";
LE.lessonNumber = 1;
printf("%s",LE.lessonName);
printf("%d",LE.lessonNumber);
}
Here lessonName is a pointer and not an array. With the assignment operator here: LE.lessonName = "Structures", you are assigning the address of where the string "Structures" is stored to LE.lessonName.
i don't understand why. because thats normally how i would assign a
string
There are a couple of things to keep in mind here. If you declare lessonName as an array (as you have done), you should keep in mind that an array is not something you can assign to. What you can assign to is a specific place / index in an array using the = operator. Thus you could build your c-string character-by-character or, you could call the strcpy function to copy a string character-by-character (including the \0) to lessonName.
When you use a pointer (char *lessonName) and say something like LE.lessonName = "Structure", this piece of string can't be modified. You can't do LE.lessonName[0] = 'g'. Of course you could modify LE.lessonName to point to some other string later on like LE.lessonName = "cat";.
Let's consider following piece of code:
int len = 100;
char *buf = (char*)malloc(sizeof(char)*len);
printf("Appended: %s\n",struct_to_string(some_struct,buf,len));
Someone allocated amount of memory in order to get it filled with string data. The problem is that string data taken from some_struct could be ANY length. So what i want to achieve is to make struct_to_string function do the following:
Do not allocate any memory that goes outside (so, buf has to be allocated outside of the function, and passed)
Inside the struct_to_string I want to do something like:
char* struct_to_string(const struct type* some_struct, char* buf, int len) {
//it will be more like pseudo code to show the idea :)
char var1_name[] = "int l1";
buf += var1_name + " = " + some_struct->l1;
//when l1 is a int or some non char, I need to cast it
char var2_name[] = "bool t1";
buf += var2_name + " = " + some_struct->t1;
// buf+= (I mean appending function) should check if there is a place in a buf,
//if there is not it should fill buf with
//as many characters as possible (without writting to memory) and stop
//etc.
return buf;
}
Output should be like:
Appended: int l1 = 10 bool t1 = 20 //if there was good amount of memory allocated or
ex: Appended: int l1 = 10 bo //if there was not enough memory allocated
To sum up:
I need a function (or couple of functions) that adds given strings to the base string without overwritting base string;
do nothing when base string memory is full
I can not use C++ libraries
Another things that I could ask but are not so important right now:
Is there a way (in C) iterate through structure variable list to get their names, or at least to get their values without their names? (for example iterate through structure like through array ;d)
I do not normally use C, but for now I'm obligated to do, so I have very basic knowledge.
(sorry for my English)
Edit:
Good way to solve that problem is shown in post below: stackoverflow.com/a/2674354/2630520
I'd say all you need is the standard strncat function defined in the string.h header.
About the 'iterate through structure variable list' part, I'm not exactly sure what you mean. If your talking about iterating over the structure's members, a short answer would be : you can't introspect C structs for free.
You need to know beforehand what structure type you're using so that the compiler know at what offset in the memory it can find each member of your struct. Otherwise it's just an array of bytes like any other.
Don't mind asking if I wasn't clear enough or if you want more details.
Good luck.
So basically I did it like here: stackoverflow.com/a/2674354/2630520
int struct_to_string(const struct struct_type* struct_var, char* buf, const int len)
{
unsigned int length = 0;
unsigned int i;
length += snprintf(buf+length, len-length, "v0[%d]", struct_var->v0);
length += other_struct_to_string(struct_var->sub, buf+length, len-length);
length += snprintf(buf+length, len-length, "v2[%d]", struct_var->v2);
length += snprintf(buf+length, len-length, "v3[%d]", struct_var->v3);
....
return length;
}
snprintf writes as much as possible and discards everything left, so it was exactly what I was looking for.
My post tries to kill 2 birds with 1 stone. Sorry in advance for the ignorance.
I'm trying to create an array of strings that I can index[0] or use ptr++ to advance the array. I'm not sure if I should create an array of char pointers, or a pointer to a char array. The variables will be stored in a struct. Forgive the ignorance, I'm just having a hard time with the order of precedence of when and where to use (). I understand a basic struct, it was when I started using a pointer to a string when I started to loose syntax structure. If I can understand the syntax for this, I could apply it further to dimensional structures of arrays.
Assuming I had the assignment of the variables correct, I think I rather use ptr++ in regards to something like printf("%s", ptr++). If I understand correctly, ptr++ would move the pointer to the next string, or some for of ptr++ could. This correct? Seems like that would be faster for many, many things.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Umbrella {
char *name[10];
} Umbrella;
int main ()
{
struct Umbrella * ptr;
// Not understanding this way...
ptr->name[0] = "Some name";
// or this way. Well name++ as long as it wasn't the first string.
ptr->name++ = "Some name";
return 0;
}
Boot note: I have read "C Primer Plus" by Prata. He does well in explaining things, it is just when you start bending things to your will when you start to fall short on applying the syntax. In example, it never covered using pointers to structures to access multidimensional arrays, and it didn't cover pointer arithmetic in a manner of syntax where you would actual use it. Can anyone recommend another book that might at least braze by such approaches?
P.S. This is my second post, and I forgot to say I really like this sites text input design. Had to say it :-).
Well, there's char *name[10] which is really just something like :
char *name0;
char *name1;
char *name2;
// .. etc
Accessing it as ptr->name[0] will just pick the ptr->name0 as a char*.
ptr->name++ = "asdf"; is a pretty bad idea here. What it basically does is :
*(ptr->name) = "asdf";
ptr->name += 1;
Of course, you can't increase name by one here (it's an array, not a pointer) so the compiler won't allow it.
The ++ operator can be useful when iterating past objects. Example :
ptr->name[9] = nullptr; // Make sure the last element is a NULL pointer.
// Take the first element
char **it = ptr->name;
char *current;
// Loop until we reach the NULL
while ((current = *(it++)) != nullptr) {
printf("%s\n", current);
}
The above is a (pretty ugly) way of iterating through an array.
Inserting things in a pre-allocated array:
char **it = ptr->name; // Start at the first element
*(it++) = "Hi!";
*(it++) = "This is the second message.";
*(it++) = "Hello world!";
*(it++) = nullptr; // End the array
Of course, all of this iteration stuff is from a dark past: nowadays we have C++ which takes care of most of these things for us, via std::vector, etc.
I am working on a simple filesystem, which (obviously) contains folders, files, etc.
A (simplified version of a) folder is represented by a structure while in RAM like so:
typedef struct{
char label[20];
unsigned int id;
t_node contents[50];
} folder;
Now, i obviously want label to contain the raw byte string with in it the name (even better would be the raw string without trailing 0, but that's a sacrifice I am willing to make).
No,here's how I create and use a struct:
folder* myFolder = (folder *) malloc(sizeof(folder));
myFolder->label = "name";
//Which doesn't work, if I try this:
char name[20] = "name";
myFolder->label = name;
//this too, doesn't work.
The error message says "incompatible types when assigning to type ‘char[20]’ from type ‘char *’".
Which I understand, but don't know how to resolve.
Thanks in advance
Use strncpy():
char name[20] = "name";
strncpy(myFolder->label, name, sizeof(myFolder->label) - 1);
myFolder->label[sizeof(myFolder->label) - 1] = 0;
Try using strncpy():
strncpy( myFolder->label, "name", 20 );
instead of
myFolder->label = "name";
You cannot use the assignment operator to fill the array, in this case the right hand side of "name" will resolve to a char pointer.
Also I would suggest replacing the constant 20 with some defined constant indicating what the value is (ie MAX_FOLDER_LABEL_LEN).
You need to use strcpy
strcpy(myFolder->label, "name");
An array is not a modifiable lvalue, so you can't assign a value to it. You have several solutions:
declares label as pointer to char;
use strcpy (or equivalent).