Splitting an array into two in C - c

I am trying to convert some binary code into assembly, but as part of the task, I'm not sure how to get the last 5 elements(of 8) in the array into a new array. As you can see I've managed to created an array for the opCode(the first 3 elements), but am not sure how to get the operand into a new array or edit the initial one.
All help is appreciated.
void convert_to_assembly(char bin[])
{
int i;
printf("The binary code before spiliting is: ");
char binary[9] = {'1','0','1','1','1','1','1','0'};
for(i=0;i<=7;i++)
{
printf("%c",binary[i]);
}
printf("\n");
char opCode[4];
strncpy(opCode,binary,3);
printf("opcode: ");
for(i=0;i<3;i++)
{
printf("%c",opCode[i]);
}
printf("\n");
}
Output
The binary code before splitting is: 10111110
opcode : 101
operand: ???????

This worked for me if I understood you correctly (based on #WhozCraig):
void convert_to_assembly(char bin[])
{
int i;
printf("The binary code before spiliting is: ");
char binary[9] = "10111110\0";
printf("%s\n",binary);
char opcode[4];
char operand[6];
strncpy(opcode,binary,3);
opcode[3]='\0';
strncpy(operand,binary+3,6);
printf("opcode: %s\n",opcode);
printf("operand: %s\n",operand);
}
strncpy will copy 6 chars starting at binary+3 to operand, which will copy the next six elements starting from the fourth one.

Since the binary string contains all the information, we can treat the opcode and operand as an overlay view using union without creating new arrays nor writing code to tear apart the data:
#include <stdio.h>
#include <string.h>
union word {
char binary[8];
struct operation {
char opcode[3];
char operand[5];
} opvar;
};
void convert_to_assembly(char *bin) {
union word op;
(void) strncpy(op.binary, bin, sizeof(op.binary));
printf("before splitting: %.8s\n", op.binary);
printf("opcode: %.3s\n", op.opvar.opcode);
printf("operand: %.5s\n", op.opvar.operand);
}
int main() {
convert_to_assembly("10111110");
return 0;
}
OUTPUT
> ./a.out
before splitting: 10111110
opcode: 101
operand: 11110
>

Related

how to assign/initialize the array of function pointers only when i call a function to do so

#include <stdio.h>
#include <stdlib.h>
int (*(*ptr[2])[2])(); //arr of pointers to the array of func pointer
int (*arr_1[2])(int ,int);//arr of function pointers
(*arr_1[])()={add1, sub1};//add1 ,sub1 are simple functions returning int
int (*arr_2[2])(int ,int);
int a,b, user_func_choice;
(*arr_2[])()={add2, sub2};
int lib_choice,user_lib_choice;
int main(int argc , char* argv[]) {
printf("enter the lib number\t 1:Lib1 , 2:Lib2 \n");
scanf("%d", &user_lib_choice);
lib_choice=user_lib_choice-1;
if(lib_choice==0){
printf("Welcome to lib1\n");
printf("enter func choice==> 1: Add , 2: subtract\n");
scanf("%d", &user_func_choice);
printf("enter the numbers.\n");
scanf("%d%d",&a,&b);
int func_choice= user_func_choice-1;
ptr[0]= arr_1;
if(func_choice==0)
{
int sum1=(*(*ptr[lib_choice])[func_choice])(a,b);
printf("sum1=%1d\n\n", sum1);
}
else if(func_choice==1)
{
int subtract1=(*(*ptr[lib_choice])[func_choice])(a,b);
printf("sub1=%1d\n\n", subtract1);
}
else{printf("InValid Function/operator choice\n");}
return;
}
if(lib_choice=1){
int a, b, user_func_choice;
printf("welcome to lib2\n");
printf("enter func choice: 1: Add , 2: subtract\n");
scanf("%d", &user_func_choice);
printf("enter the numbers.\n");
scanf("%d%d",&a,&b);
ptr[1] = arr_2;
int func_choice= user_func_choice-1;
if(func_choice==0)
{
int sum2=(*(*ptr[lib_choice])[func_choice])(a,b);
printf("sum2=%1d\n\n", sum2);
}
else if(func_choice==1)
{
int subtract2=(*(*ptr[lib_choice])[func_choice])(a,b);
printf("sub2=%1d\n\n", subtract2);
}
return;
}
else{printf("InValid library choice\n");
}
return 0;
}
Every thing works fine here
But what i want is instead of hardcoding the initialization of library(lib1 or lib2) let user specify the number of libraries he want to intialize. Something like this
int main(int argc , char* argv[]){
printf("enter the lib number\t 1:Lib1 , 2:Lib2 \n");
scanf("%d", &user_lib_choice);
if(argc!=2){printf("please specify the library number as sencond argument\n");return 0;}
int lib_choice_cmd=atoi(argv[1]);
if(lib_choice==1)
{
lib1_init();
}
else if(lib_choice==2)
{
lib1_init();
lib2_init();
}
lib_init() is the function that will do the initialization process.If user specify lib num as 1 i will initialize only lib1. I did this for lib1, but this gives me an error
lib1_init(){
(*arr_1[2])(int ,int)={add1 , sub1};
}
And when i did
lib1_init(){
arr_1[0]=add1;
arr_1[1]=sub1;
}
This gives me a segmentation fault.Pleae tell me what is wrong
You can only do initialization when initializing, not later. Even given that, your syntax looks odd.
You can of course use plain assignment to each element:
void array_init(void)
{
arr_1[0] = add1;
arr_1[1] = sub1;
}
(*arr[2])()={add1 ,sub1};
Unless that line appears on the same line as the function pointer array initialization, it is complete nonsense code.
You can initialize the array upon declaration like this:
int(*arr[2])(int ,int) = {add1 ,sub1};
Or you can assign an individual item, just as for any array:
arr[0] = add1;
In C, you cannot assign arrays to arrays, nor can you assign several array items on a single line. That is, you can't do int arr[2]; arr = {1,2};Function pointer arrays are no different than other arrays.
If you want to initialize the array in run-time, you have to either set each item one by one in a loop, or use memcpy.
I did not right understood the problem, but there is a syntax mistake:
if you declare a pointer to function array like this:
int(*arr[2])(int ,int)
you have to call the function like this:
(*arr[0])(some_int_stuff, some_other_int_stuff);
the mistakes are that the index must be smaller than 2, and you don't pass any parameter

Filling an array with a string on a side function. Why does it prints gibberish?

I can't find help about this. Most issues i found are related to not closing the array with a '\0' , but this is not the case.
void main() {
char text[1000];
int index=0;
loadText(text,&index);
printf("\nThe text is:\n %s",text);
getch();
}
void loadText(char* text,int* index){
printf("Insert the text: \n");
while((*index<1000) && (text[*index]=getchar())!=EOF) {
*index++;
}
text[*index]='\0';
}
When i print the array it shows random chars.
On a side note, this is a test and we are forced to write the function as:
void loadText(char*, int*)
In
*index++;
doesn't increment the the value in the pointer. Instead it gets the value ie (*index) and then increment the pointer itself (index=index+1).
Do
(*index)++;

Compare struct char elements (not sure how to say it)

I need to compare the contents of an element of a struct to another.
struct total_owners
{
int ADT2; //id number
char arkyk[7]; //license plate number
};
typedef struct total_owners owners;
struct total_offenses
{
char arkyk2[7];
int serious; //seriousness of offense (0 or 1)
};
typedef struct total_offenses offenses;
struct total_drivers
{
int ADT;
int ADO; //license number
};
typedef struct total_drivers drivers;
what I want to compare is arkyk2 in total_offenses with arkyk in total_owners. they are both of the format XXX1234 ( three letters and 4 numbers)
this is the function I am working on
void sumpoints(offenses* b,owners* a, drivers* c, int amountowners , int amountoffenses ,int amountdrivers)
{
int totals[amountdrivers][3],i,j,h;
for (i=0;i<amountdrivers;i++)
{
totals[i][0] = c[i].ADT;
totals[i][1] = c[i].ADO;
totals[i][2] = 0;
}
for (h=0;h<amountdrivers;h++)
{
for (i=0;i<amountowners;i++)
{
for(j=0;j<amountoffenses;j++)
{
if (a[i].arkyk == b[j].arkyk2) // this is wrong (definitely)
{
if (c[h].ADT == a[i].ADT2)
{
totals[h][2] = totals[h][2]+1;
}
}
}
}
}
for (i=0;i<amountdrivers;i++)
{
printf("Total offenses per driver:\n");
printf(" ADT %d \t ADO %d \t total %d\n", totals[i][0] , totals[i][1] , totals[i][2]);
}
}
the end result should be a totals array with the id number in the first column , the license number in the second and the amount of offenses in the last.
To do string comparison, you would change
if ( a[i].arkyk == b[j].arkyk2 )
to
if( strncmp( a[i].arkyk, b[j].arkyk2, 7 ) == 0)
As was pointed out by #notlikethat, using plain strcmp may run into trouble since you have a 7 element array to store 7 characters, so there is no space for a terminating '\0'. By specifying that the comparison should stop after 7 characters, you avoid this issue.
In C: Create a function called compare that takes the two different structures as parameters and returns a bool. Inside the function just do a string comparison with strcmp or strncmp
In C++:
Go nuts with operator overloading, it might look better, and will give you the same performance.

Switch statement using string on an array

#include<stdio.h>
int main(){
char name[20];
printf("enter a name ");
scanf("%s",name);
switch(name[20]){
case "kevin" :
printf("hello");
break;
}
printf("%s",name);
getch();
}
It seems it will not work. Is this possible? I mean is there any way we can make a switch statement of a string. How to solve the problem, actually?
Switch statements in C aren't smart like one's found in other languages (such as Java 7 or Go) you cannot switch on a string (Nor can you compare strings with ==). Switch can only operate on integral types (int, char, etc).
In your code you call switch with: switch(name[20]). That means switch(*(name + 20)). In other words switch on the 21st char in name (because name[0] is the first). As name only has 20 chars you are accessing whatever memory is after name. (which could do unpredictable things)
Also the string "kevin" is compiled to a char[N] (where N is strlen("kevin") + 1) which contains the string. When you do case "kevin". It will only work if name is in the exact same piece of memory storing the string. So even if I copied kevin into name. It still would not match as it is stored in a different piece of memory.
To do what you seem to be trying you would do this:
#include <string.h>
...
if (strcmp(name, "kevin") == 0) {
...
}
String compare (strcmp) returns different values based on the difference in the strings. Eg:
int ord = strcmp(str1, str2);
if (ord < 0)
printf("str1 is before str2 alphabetically\n");
else if (ord == 0)
printf("str1 is the same as str2\n");
else if (ord > 0)
printf("str1 is after str2 alphabetically\n");
Side note: Dont use scanf("%s", name) in that form. It creates a common security problem use fgets like this: (there is a safe way to use scanf too)
#define MAX_LEN 20
int main() {
char name[MAX_LEN];
fgets(name, MAX_LEN, stdin);
...
Switch statements work on int values (or enum), but not on char arrays.
You could do
if (strcmp(name, "kevin")==0) {
printf("hello");
}
else if (strcmp(name, "Laura")==0) {
printf("Allo");
}
else if (strcmp(name, "Mike")==0) {
printf("Good day");
}
else {
printf("Help!");
}
There are plenty of ways to go about this! For example, use a...
3-letter hash
#include <stdio.h>
int main(){
char name[20];
printf("enter a name ");
scanf("%s",name);
switch((int)*name * (int)*(name+1) * (int)*(name+2)){
case (1275226) : // "kevin"
printf("hello %s.\n", name);
break;
case (1293980) : // "astro"
printf("welcome %s.\n", name);
break;
}
printf("%d",(int)*name * (int)*(name+1) * (int)*(name+2));
}
No, you cannot use the switch statement in C with the value of a string or character array. The closest alternative is to use some sort of data structure mapping strings to function pointers. The function pointer could be called after a string is used to look it up.
since the name is declared as a char type ,it would be better if you use "%c" instead of using "%s" inside the scanf() method.
You can use "hash-string.h" library that converts strings into hash code integer.
Create a header file and paste this code:
http://www.opensource.apple.com/source/gcc/gcc-5484/intl/hash-string.h
#include <stdio.h>
#include <stdlib.h>
#include "hash-string.h"
int main(){
char name[20];
printf("Enter a name: ");
scanf("%s",name);
unsigned long nameInt = hash_string(name);
switch(nameInt){
case 7458046 /* "kevin" */: { printf("Hello %s", name); break; }
default: { printf("You are not kevin"); }
}
printf("\n");
return 0;
}
Remember the rules while using switch statements.
Switch constraints
1. The controlling expression of a switch statement must have "integer type".
2. The expression of each case label shall be an integer constant expression and no two of
the case constant expressions in the same switch statement shall have the same value
after conversion. There may be at most one default label in a switch statement.
3. Any enclosed switch statement may have a default label or case constant expressions with values that duplicate case constant expressions in the enclosing switch statement.
If you are after performing specific actions for specific strings this implies you know the strings in advance. This in turn implies their number is limited, is countable, like for example a set of N commands:
const char * commands[] = {
"command-1",
"command-2",
...
"command-N"
}
To address those commands inside the array above from your code using a swtich you need to know their index, which is error prone. So number them, give them an ID:
enum Command_id {
NO_COMMAND,
COMMAND_1,
COMMAND_2,
//...
COMMAND_N,
};
Now put the two above together using a struct:
struct Command_info {
const char * command;
enum Command_id id;
} command_infos[] = {
{"", NO_COMMAND},
{"command-1", COMMAND_1},
{"command-2", COMMAND_2},
// ...
{"command-N", COMMAND_N},
};
Now you have nice mapping of strings and their related IDs. To be able to map from string to ID during runtime the mapping above needs to be searched. To do this in a efficient manner you want to us binary search. The C library proveids bsearch() for this. The only prerequsite is that the array to be searched need to sorted.
To sort use qsort() also proveid by the C library. For qsort() to work we you need a comparsion function:
int cmp_command_infos(const void * pvCI1, const void* pvCI2)
{
const struct Command_info * pCI1 = pvCI1;
const struct Command_info * pCI2 = pvCI2;
return strcmp(pCI1->command, pCI2->command);
}
Call qsort() like this
qsort(command_infos, sizeof command_infos / sizeof *command_infos, sizeof *command_infos, cmp_command_infos);
Now as the array is sorted one can look it up using bsearch(). For "COMMAND-2" this would look like this:
... = bsearch(&(struct Command_info){"COMMAND-2", NO_COMMAND}, command_infos, sizeof command_infos / sizeof *command_infos, sizeof *command_infos, cmp_command_infos);
Putting all this together could result in:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
enum Command_id {
NO_COMMAND,
COMMAND_1,
COMMAND_2,
//...
COMMAND_N,
};
struct Command_info {
const char * command;
enum Command_id id;
} command_infos[] = {
{"", NO_COMMAND},
{"command-1", COMMAND_1},
{"command-2", COMMAND_2},
// ...
{"command-N", COMMAND_N},
};
int cmp_command_infos(const void * pvCI1, const void* pvCI2)
{
const struct Command_info * pCI1 = pvCI1;
const struct Command_info * pCI2 = pvCI2;
return strcmp(pCI1->command, pCI2->command);
}
int main(int argc, char ** argv)
{
qsort(command_infos, sizeof command_infos / sizeof *command_infos, sizeof *command_infos, cmp_command_infos);
{
enum Command_id command_id = NO_COMMAND;
struct Command_info * pCI = bsearch(&(struct Command_info){argv[1], NO_COMMAND}, command_infos, sizeof command_infos / sizeof *command_infos, sizeof *command_infos, cmp_command_infos);
if (NULL == pCI)
{
printf("Command = '%s' is unknown\n", argv[1]);
}
else
{
printf("Command = '%s' --> ID = %d\n", pCI->command, pCI->id);
switch(command_id)
{
case COMMAND_1:
/* perform action on COMMAND 1 here */
break;
case COMMAND_2:
/* perform action on COMMAND 1 here */
break;
default:
/* unknow command, do nothing */
break;
}
}
}
}
Call it like:
./a.out command-1
giving:
Command = 'command-1' --> ID = 1
or:
./a.out command-bla
giving:
Command = 'command-bla' is unknown
or even
./a.out ""
giving:
Command = '' --> ID = 0

how to best achieve string to number mapping in a c program

I have a definite set of strings and its corresponding numbers:
kill -> 1
live -> 2
half_kill -> 3
dont_live -> 4
List is of 30 such strings and their number mapping.
If user enters "kill", I need to return 1 and if he enters "dont_live" I need to return 4.
How should I achieve this in c program? I am looking for an efficient solution because this operation needs to be done 100s of times.
should I put them in #define in my .h file?
Thanks in advance.
Sort your table, and use the standard library function bsearch to perform a binary search.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct entry {
char *str;
int n;
};
/* sorted according to str */
struct entry dict[] = {
"dont_live", 4,
"half_kill", 3,
"kill", 1,
"live", 2,
};
int compare(const void *s1, const void *s2)
{
const struct entry *e1 = s1;
const struct entry *e2 = s2;
return strcmp(e1->str, e2->str);
}
int
main (int argc, char *argv[])
{
struct entry *result, key = {argv[1]};
result = bsearch(&key, dict, sizeof(dict)/sizeof(dict[0]),
sizeof dict[0], compare);
if (result)
printf("%d\n", result->n);
return 0;
}
Here's what you get when you run the program.
$ ./a.out kill
1
$ ./a.out half_kill
3
$ ./a.out foo
<no output>
PS: I reused portions of sidyll's program. My answer should now be CC BY-SA compliant :p
A possible solution:
#include <stdio.h>
#include <string.h>
struct entry {
char *str;
int n;
};
struct entry dict[] = {
"kill", 1,
"live", 2,
"half_kill", 3,
"dont_live", 4,
0,0
};
int
number_for_key(char *key)
{
int i = 0;
char *name = dict[i].str;
while (name) {
if (strcmp(name, key) == 0)
return dict[i].n;
name = dict[++i].str;
}
return 0;
}
int
main (int argc, char *argv[])
{
printf("enter your keyword: ");
char s[100]; scanf("%s", s);
printf("the number is: %d\n", number_for_key(s));
return 0;
}
Here's one approach:
int get_index(char *s)
{
static const char mapping[] = "\1.kill\2.live\3.half_kill\4.dont_live";
char buf[sizeof mapping];
const char *p;
snprintf(buf, sizeof buf, ".%s", s);
p = strstr(mapping, buf);
return p ? p[-1] : 0;
}
The . mess is to work around kill being a substring of half_kill. Without that issue you could simply search for the string directly.
If it is a very short list of strings then a simple block of ifs will be more than sufficient
if (0 == strcmp(value, "kill")) {
return 1;
}
if (0 == strcmp(value, "live")) {
return 2;
}
...
If the number approach 10 I would begin to profile my application though and consider a map style structure.
if you have a fixed set of strimgs, you have two options: generate a perfect hashing function (check gperf or cmph) or create a trie so that you never have to check charcters more than once.
Compilers usually use perfect hashes to recognize a language keyword, in your case I would probably go with the trie, it should be the fastest way (but nothing beats direct measurement!)
Is it really a bottleneck? You should worry about efficiency only if the simple solution proves to be too slow.
Having said that, possible speed improvements are checking the lengths first:
If it's 4 characters then it could be "kill" or "live"
If it's 9 characters then it could be "half_kill" or "dont_live"
or checking the first character in a switch statement:
switch (string[0]) {
case 'k':
if (strcmp(string, "kill") == 0)
return 1;
return 0;
case 'l':
...
default:
return 0;
}
Use hashmap/ hashtable i think this would be the best solution.
Can you use an Enumunerator?
int main(void) {
enum outcome { kill=1, live, half_kill, dont_live };
printf("%i\n", kill); //1
printf("%i\n", dont_live); //4
printf("%i\n", half_kill); //3
printf("%i\n", live); //2
return 0;
}
Create a list of const values:
const int kill = 1;
const int live = 2;
const int half_kill = 3;
etc

Resources