good way to map enums to strings in C - c

I have a bunch of enums (from libvirt library if you are wondering) that look like this:
enum whatever {
VAL_A = 1
VAL_B = 2
...
}
How do I convert these to meaningful strings? That is, VAL_A has a state meaning "meaning_A", VAL_B has a state meaning "meaning_B" and so on. In php or perl or python, I would generate a key:val pair and return the results in O(1) time. Is there an efficient way to map these to meaningful strings in C? I was thinking of a switch statement, but was wondering about better approaches.
Thanks,
Vik.

Try using it as an array index:
char *strs[] = {"meaning_A", "meaning_B", "etc."};
strs[(int)enumvar - 1];

Related

Actionscript/Animate - Fill in next array spot if this one is already filled

so I am working on a graphical calculator (bit more of a challenge than the basic windows one), and I want to be able to do the entire "math" in one textfield, just like typing in "5+3-5*11/3" and it gives you the solution when you press '='
I decided to make it with arrays of numbers and symbols, but I have no idea how to make it to fill the next array if this one already is used:
var numbers:Array = new Array("","","","","","","","","","","","","","","","");
var actions:Array = new Array("","","","","","","","","","","","","","","","");
I am using split to split the numbers I input with symbols, and I want the numbers to be placed in the arrays. Example: I type in 555+666 and then I need to have something like
if (numbers[0] = "") {numbers[0] = 555}
else if (numbers[1] = "") {numbers[1] = 555}
else if.....
Know what I mean?
Pretty hard to describe...
something like... When I type in a number, if the numbers[0] is already filled, go fill in numbers[1], if numbers[1] is filled, go to numbers[2] etc
Even if I agree with #Nbooo and the Reverse Polish Notation
However Vectors may have a fixed length.
This is not an answer but just an example (if the length of Your Array must be defined):
//Just for information..
var numbs:Vector.<Number> = new Vector.<Number>(10,true);
var count:uint = 1;
for (var i in numbs){
numbs[i] = count++
}
trace(numbs);
// If You try to add an element to a Vector,
// You will get the following Error at compile time :
/*
RangeError: Error #1126: Cannot change the length of a fixed Vector.
at Vector$double/http://adobe.com/AS3/2006/builtin::push()
at Untitled_fla::MainTimeline/frame1()
*/
numbs.push(11);
// Will throw an Error #1126
trace(numbs);
If You use this code to update a fixed Vector, this will not throw an ERROR :
numbs[4]=11;
trace(numbs);
Output :
1,2,3,4,5,6,7,8,9,10
1,2,3,4,11,6,7,8,9,10
// length is 10, so no issue...
If You consider the performance between Arrays and vectors check this reference : Vector class versus Array class
I hope this may be helpful.
[EDIT]
I suggest you to check at those links too :
ActionScript 3 fundamentals: Arrays
ActionScript 3 fundamentals: Associative arrays, maps, and dictionaries
ActionScript 3 fundamentals: Vectors and ByteArrays
[/EDIT]
Best regards.
Nicolas.
What you want to implement is the Reverse Polish Notation. In actionscript3 arrays are dynamic, not fixed size, that means you can add elements to the array without concern about capacity (at least in your case).
const array:Array = new Array();
trace(array.length); // prints 0
array.push(1);
array.push(2);
trace(array.length); // prints 2
I suggest using "push" and "pop" methods of Array/Vector, since it's much more natural for such task. Using those methods will simplify your implementation, since you'll get rid of unnecessary checks like
if (numbers[1] == "") {...}
and replace it just with:
numbers.push(value);
and then to take a value from the top:
const value:String = numbers.pop();

I am not able to create arrays in Nes-C language. any suggestions ?

Can anyone tell me how to create arrays in nes-c. Also i would like to print them. I just saw on google that this is a way but its giving me errors.
uint8_t i;*
uint8_t in[16] =
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
A bit late to the party, but maybe it's still useful to answer this.
Creating an array
Arrays in nesC are defined the same way as in normal C language, since nesC is simply an extension of C:
type arrayName [ arraySize ];
I use tutorialspoint for concise tutorials on C, but you can find explanations on a multitude of websites. In your case I would define the array like this:
uint8_t in[16];
Initializing the array with zeroes is best done with the command memset:
memset(in, 0, sizeof(in));
Why? It's clean code, works efficiently, and doesn't need adjusting when you decide to increase the size of the array.
Printing an array
For this I'll refer you to the TinyOS Printf Library tutorial, this explains how you print stuff to the console in TinyOS. I assume you're working with this since you're asking a nesC question.
Printing an array can be done through a simple for-loop.
for (i = 0; i < sizeof(in); ++i) {
printf("%u", in[i]);
}
printfflush();
Good luck!

Indexing sliced array in matlab??? [duplicate]

For example, if I want to read the middle value from magic(5), I can do so like this:
M = magic(5);
value = M(3,3);
to get value == 13. I'd like to be able to do something like one of these:
value = magic(5)(3,3);
value = (magic(5))(3,3);
to dispense with the intermediate variable. However, MATLAB complains about Unbalanced or unexpected parenthesis or bracket on the first parenthesis before the 3.
Is it possible to read values from an array/matrix without first assigning it to a variable?
It actually is possible to do what you want, but you have to use the functional form of the indexing operator. When you perform an indexing operation using (), you are actually making a call to the subsref function. So, even though you can't do this:
value = magic(5)(3, 3);
You can do this:
value = subsref(magic(5), struct('type', '()', 'subs', {{3, 3}}));
Ugly, but possible. ;)
In general, you just have to change the indexing step to a function call so you don't have two sets of parentheses immediately following one another. Another way to do this would be to define your own anonymous function to do the subscripted indexing. For example:
subindex = #(A, r, c) A(r, c); % An anonymous function for 2-D indexing
value = subindex(magic(5), 3, 3); % Use the function to index the matrix
However, when all is said and done the temporary local variable solution is much more readable, and definitely what I would suggest.
There was just good blog post on Loren on the Art of Matlab a couple days ago with a couple gems that might help. In particular, using helper functions like:
paren = #(x, varargin) x(varargin{:});
curly = #(x, varargin) x{varargin{:}};
where paren() can be used like
paren(magic(5), 3, 3);
would return
ans = 16
I would also surmise that this will be faster than gnovice's answer, but I haven't checked (Use the profiler!!!). That being said, you also have to include these function definitions somewhere. I personally have made them independent functions in my path, because they are super useful.
These functions and others are now available in the Functional Programming Constructs add-on which is available through the MATLAB Add-On Explorer or on the File Exchange.
How do you feel about using undocumented features:
>> builtin('_paren', magic(5), 3, 3) %# M(3,3)
ans =
13
or for cell arrays:
>> builtin('_brace', num2cell(magic(5)), 3, 3) %# C{3,3}
ans =
13
Just like magic :)
UPDATE:
Bad news, the above hack doesn't work anymore in R2015b! That's fine, it was undocumented functionality and we cannot rely on it as a supported feature :)
For those wondering where to find this type of thing, look in the folder fullfile(matlabroot,'bin','registry'). There's a bunch of XML files there that list all kinds of goodies. Be warned that calling some of these functions directly can easily crash your MATLAB session.
At least in MATLAB 2013a you can use getfield like:
a=rand(5);
getfield(a,{1,2}) % etc
to get the element at (1,2)
unfortunately syntax like magic(5)(3,3) is not supported by matlab. you need to use temporary intermediate variables. you can free up the memory after use, e.g.
tmp = magic(3);
myVar = tmp(3,3);
clear tmp
Note that if you compare running times with the standard way (asign the result and then access entries), they are exactly the same.
subs=#(M,i,j) M(i,j);
>> for nit=1:10;tic;subs(magic(100),1:10,1:10);tlap(nit)=toc;end;mean(tlap)
ans =
0.0103
>> for nit=1:10,tic;M=magic(100); M(1:10,1:10);tlap(nit)=toc;end;mean(tlap)
ans =
0.0101
To my opinion, the bottom line is : MATLAB does not have pointers, you have to live with it.
It could be more simple if you make a new function:
function [ element ] = getElem( matrix, index1, index2 )
element = matrix(index1, index2);
end
and then use it:
value = getElem(magic(5), 3, 3);
Your initial notation is the most concise way to do this:
M = magic(5); %create
value = M(3,3); % extract useful data
clear M; %free memory
If you are doing this in a loop you can just reassign M every time and ignore the clear statement as well.
To complement Amro's answer, you can use feval instead of builtin. There is no difference, really, unless you try to overload the operator function:
BUILTIN(...) is the same as FEVAL(...) except that it will call the
original built-in version of the function even if an overloaded one
exists (for this to work, you must never overload
BUILTIN).
>> feval('_paren', magic(5), 3, 3) % M(3,3)
ans =
13
>> feval('_brace', num2cell(magic(5)), 3, 3) % C{3,3}
ans =
13
What's interesting is that feval seems to be just a tiny bit quicker than builtin (by ~3.5%), at least in Matlab 2013b, which is weird given that feval needs to check if the function is overloaded, unlike builtin:
>> tic; for i=1:1e6, feval('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 49.904117 seconds.
>> tic; for i=1:1e6, builtin('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 51.485339 seconds.

Need suggestion on Code conversion to Matlab_extension 2

This is an extension of the previously asked question: link. In a short, I am trying to convert a C program into Matlab and looking for your suggestion to improve the code as the code is not giving the correct output. Did I convert xor the best way possible?
C Code:
void rc4(char *key, char *data){
://Other parts of the program
:
:
i = j = 0;
int k;
for (k=0;k<strlen(data);k++){
:
:
has[k] = data[k]^S[(S[i]+S[j]) %256];
}
int main()
{
char key[] = "Key";
char sdata[] = "Data";
rc4(key,sdata);
}
Matlab code:
function has = rc4(key, data)
://Other parts of the program
:
:
i=0; j=0;
for k=0:length(data)-1
:
:
out(k+1) = S(mod(S(i+1)+S(j+1), 256)+1);
v(k+1)=double(data(k+1))-48;
C = bitxor(v,out);
data_show =dec2hex(C);
has = data_show;
end
It looks like you're doing bitwise XOR on 64-bit doubles. [Edit: or not, seems I forgot bitxor() will do an implicit conversion to integer - still, an implicit conversion may not always do what you expect, so my point remains, plus it's far more efficient to store 8-bit integer data in the appropriate type rather than double]
To replicate the C code, if key, data, out and S are not already the correct type you can either convert them explicitly - with e.g. key = int8(key) - or if they're being read from a file even better to use the precision argument to fread() to create them as the correct type in the first place. If this is in fact already happening in the not-shown code then you simply need to remove the conversion to double and let v be int8 as well.
Second, k is being used incorrectly - Matlab arrays are 1-indexed so either k needs to loop over 1:length(data) or (if the zero-based value of k is used as i and j are) then you need to index data by k+1.
(side note: who is x and where did he come from?)
Third, you appear to be constructing v as an array the same size of data - if this is correct then you should take the bitxor() and following lines outside the loop. Since they work on entire arrays you're needlessly repeating this every iteration instead of doing it just once at the end when the arrays are full.
As a general aside, since converting C code to Matlab code can sometimes be tricky (and converting C code to efficient Matlab code very much more so), if it's purely a case of wanting to use some existing non-trivial C code from within Matlab then it's often far easier to just wrap it in a MEX function. Of course if it's more of a programming exercise or way to explore the algorithm, then the pain of converting it, trying to vectorise it well, etc. is worthwhile and, dare I say it, (eventually) fun.

Is there an type of array in c that allows strings to be used as indices?

I am looking for something like:
a["hello"] points to a list, a["h"] to another.
Basically, I'm looking for an associative array implementation.
No, not in C. You may want to look into hash table libraries to get what you want.
A bit of trivia: although strings cannot typically be used as indices, in certain narrow cases, they are valid.
Consider this line of code:
printf("%c", 1["hello"]);
The output is "e".
This exploits the property that a[b] == *(a+b) == *(b+a) == b[a].
As a result, 1["hello"] == "hello"[1], which clearly results in the second letter, "e"
Not directly, but there are a number of hash table implementations in C.
Here's one example. I haven't tried it, but it was near the top of a Google search. (Presumably it doesn't let you use the a["hello"] syntax.)
(And if using C++ rather than C is an option, something like a map might be a good solution.)
You cannot do this exactly as written ( like you can do in python or perl ) But, If you want to use a string as an index. It sounds very much like you want a perl hash or dictionary. I have a quite lightweight dictionary/ahash implementation for C that lets you use anything as a key (index) including strings.
xrhash - guthub
Here's a brief example of using a string as an indexer:
XRHash * dict = xr_init_hash( xr_hash__strhash, xr_hash__strcmp );
/* add things to the hash */
if ( xr_hash_contains( dict, "mary" ) != XRHASH_EXISTS_TRUE )
printf("does not contain mary\n");
xr_hash_add( dict, "fred", strdup("my name is fred") );
xr_hash_add( dict, "mary", strdup("my name is mary") );
xr_hash_add( dict, "sally", strdup("my name is sally") );
xr_hash_add( dict, "bob", strdup("my name is bob") );
/* test if things exist */
if ( xr_hash_contains( dict, "mary" ) == XRHASH_EXISTS_TRUE )
printf("does contain mary\n");
/* iterate the hash */
xrhash_fast_iterator * iter = xr_init_fasthashiterator( dict );
char * hashkey = NULL;
do {
hashkey = (char*) xr_hash_fastiteratekey( iter );
if ( hashkey != NULL ){
/* get values */
char * data;
xr_hash_get( dict, (void*)hashkey, (void**)&data );
printf("key = %s, value = %s\n", hashkey, data );
} else {
break;
}
} while ( 1 );
The full source for the above is here
EDIT:
There also turns out to be Hash Tables that do the same and more from GLib. My lib is quite fast though :)
All the answers so far have focused purely on syntax, not on solving your problem. If you really need an "associative array", you need to find or write some library routines to provide such a data structure. C does not have any high-level data structures as builtin types or part of the standard library. glib surely provides something like what you're looking for.
Note however: (!!) If you find yourself needing associative arrays outside of specialized applications where the key comes from the outside world (as opposed to within your program), I think you should really evaluate either (1) whether there's a better way to do what you're trying to achieve in C, or (2) whether you really want to be programming in C. Associative arrays are not a C idiom, and by using them when another data type would do, you're throwing out many of the advantages of C and just keeping all of the pain of C.
No, array are just pointers and the index operator ( [] ) is just a shorthand for :
a[i] == *(a + i * sizeof(*a))
It's called an std::map and you can use std::string as a key.
Note that this is only an option in C++, not C. However, I'm thinking it's probably what you were looking for, as many times novices will tag C questions as C++ and the other way around.

Resources