Been racking my brain for the past few hours but i need help. Pretty much trying to write a C model for a blocking cache to be used in a RTL design. I've defined the cache line in C as an array of 'char' types to make it byte-addressable. Only difficulty is I can't for the life of me figure how to concatenate four bytes (chars) into a 32bit 'int' type to be returned. I've tried everything I could think of using strcat, strncat, strcpy, etc but no luck. strcat returns the proper value when I the char array is populated with actual characters, but it doesn't behave as desired when numbers are use (strcat only returns the first element instead of the entire char array). Example code:
unsigned char aa[4] = {0};
char testet[2] = {1,0};
printf(" aa[0] = %d \n", aa[0]);
printf(" aa[1] = %d \n", aa[1]);
printf(" aa[2] = %d \n", aa[2]);
printf(" aa[3] = %d \n", aa[3]);
printf(" aaconcat as a 32b word is %u \n", *strncat(aa, testet,2));
printf(" aaconcat as a 32b word is %u \n", *strncat(aa, testet,1));
printf(" aa[0] = %d \n", aa[0]);
printf(" aa[1] = %d \n", aa[1]);
printf(" aa[2] = %d \n", aa[2]);
printf(" aa[3] = %d \n", aa[3]);
Returns:
aaconcat as a 32b word is 1
aaconcat as a 32b word is 1
aa[0] = 1
aa[1] = 2
aa[2] = 1
aa[3] = 0
Though I'm expecting {testet[0],testet[1],testet[0]} = 131330.
if you are trying to concatenate the actual bits, which I suspect you may be trying to do given your expected result from {testet[0],testet[1],testet[0]} = 131330, then try something like this to concatenate the chars:
This assumes the chars you want to concatenate are stored in unsigned char chararr[4].
long int chars_in_int = 0;
for (int i = 0; i < 4; i++ ) {
chars_in_int << 8; /* redundant on first loop */
chars_in_int += chararr[i];
}
This will place the chars with the lowest index in chararr in the most significant bits of chars_in_int.
Related
I am trying to assign an array and integer, this is the code i have. Say eg1 is 5, when i print arr[1][1], i want it to display 5
fscanf(f, "%d %d %d %d", &eg1, &eg2, &eg3, &eg4);
Arr[1][1] = eg1;
printf(" %c", Arr[1][1])
If I understand your question correctly you want an array of pointers to the variables eg1 to eg4 to be able to display any changes to those variables via the array. You need a 1D array of int* for this. Not a 2D array.
Example:
int eg1, eg2, eg3, eg4;
int *Arr[] = {&eg1, &eg2, &eg3, &eg4}; // fill Arr with pointers to the variables
if (fscanf(f, "%d %d %d %d", &eg1, &eg2, &eg3, &eg4) == 4) {
for(int i = 0; i < 4; ++i) {
printf("eg%d = %d\n", i+1, *Arr[i]); // derefrence pointer to get the value
}
}
Note that you fscanf for int:s with %d but you printf a char with %c. I assume you meant %d in your printf too.
I'm running user input through a series of functions provided by the ctype.h library, but scanf doesn't work for white space.
Since I can't use scanf for whitespace I believe fgets() should be what I'm looking for, but am unsure about the last parameter I would use for it. Any advice would be appreciated!
#include <stdio.h>
#include <ctype.h>
int main(void) {
char a;
puts("Enter a character:");
//scanf("%s", &a);
fgets(a, 1, ??);
printf("isblank('%c') = %d \n", a ,isblank(a));
printf("isdigit('%c') = %d \n", a ,isdigit(a));
printf("isalpha('%c') = %d \n", a ,isalpha(a));
printf("isalnum('%c') = %d \n", a ,isalnum(a));
printf("isxdigit('%c') = %d \n", a ,isxdigit(a));
printf("islower('%c') = %d \n", a ,islower(a));
printf("isupper('%c') = %d \n", a ,isupper(a));
printf("tolower('%c') = %d \n", a ,tolower(a));
printf("toupper('%c') = %d \n", a ,toupper(a));
printf("isspace('%c') = %d \n", a ,isspace(a));
printf("iscntrl('%c') = %d \n", a ,iscntrl(a));
printf("ispunct('%c') = %d \n", a ,ispunct(a));
printf("isprint('%c') = %d \n", a ,isprint(a));
printf("isgraph('%c') = %d \n", a ,isgraph(a));
return 0;
}
Output should look like this
Enter a character:
C
isblank('C') = 0
isdigit('C') = 0
isalpha('C') = 1024
isalnum('C') = 8
isxdigit('C') = 4096
islower('C') = 0
isupper('C') = 256
tolower('C') = 99
toupper('C') = 67
isspace('C') = 0
iscntrl('C') = 0
ispunct('C') = 0
isprint('C') = 16384
isgraph('C') = 32768
Program should intake a single character and convert it to integer through a series of functions.
The first argument to fgets() needs to be a buffer that can hold the entire line of input.
int main(void) {
char a;
char line[100];
puts("Enter a character:");
fgets(line, sizeof line, stdin);
a = line[0];
I'm working with four differest structs, two of which are quite large. I have a function to write each value of each struct to a .txt file, but the code is very long and robust. I'm looking for a way of printing out each value without having to hard code each in, but everything I've found so far in my research indicates that hardcoding is the only way, but I figured I'd check on here before I give up completely. As it stands right now, my code looks like this:
char text[416];
snprintf(text, 416,
"%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
epsy.VBUS_voltage_mV,
epsy.temp_internal_degC,
epsy.status,
batty.Z_pos_Camera_Temperature,
batty.Z_neg_Camera_Temperature,
batty.Y_pos_Camera_Temperature,
batty.Y_neg_Camera_Temperature,
batty.X_pos_Camera_Temperature,
batty.FPGA_Temp_1,
batty.FPGA_Temp_2,
batty.Rx_Hinge_Temperature,
batty.Bat_1_Vbat,
batty.Bat_1_Ichg,
batty.Bat_1_Idch,
batty.Bat_1_MCU_Temp,
batty.Bat_1_Temp_Therm,
batty.Bat_1_Status,
batty.Bat_2_Vbat,
batty.Bat_2_Ichg,
batty.Bat_2_Idch,
batty.Bat_2_MCU_Temp,
... and it goes on for a while. (80 values)
Is there a simpler way of doing this? If so, how do I do it?
The following solution defines a union that combines the actual struct with it's integral members with an array of integral values in order to "view" the struct members as array elements accessible through subscription.
To make this save, we need to control the alignment, since the compiler might add padding between the data members. This would then let the "array-view" point to invalid memory and introduce undefined behaviour.
I suggest to use #pragma pack(n) to control the alignment. Note that the code may also work without this alignment thing, yet it might get a problem if data members of other type are introduced before or after the "integral block" (This would also require to offset the "array-view", but that's not shown here).
The surrounding union is required to guarantee that the array and the struct are actually aligned correctly; otherwise, a cast from a struct to an array might introduce undefined behaviour.
I'm aware that #pragma pack is not portable and that it affects the memory layout and probably speed. Yet it is supposed to work on most compilers, and I think it is needed for controlling alignment in order to avoid UB:
#pragma pack(4) /* set alignment to 4 byte boundary */
#define nrOfMyPackedDataElements 3
union MyPackedData {
struct {
int32_t firstInt;
int32_t secondInt;
int32_t thirdInt;
} data;
int32_t array[nrOfMyPackedDataElements];
};
#pragma pack() /* reset alignment to compiler default */
int main() {
union MyPackedData data;
data.data.firstInt = 10;
data.data.secondInt = 20;
data.data.thirdInt = 30;
for (int i=0; i < nrOfMyPackedDataElements; i++) {
printf("%d ",data.array[i]);
}
return 0;
}
In C11 you could rewrite your structs using unnamed structures and union fields.
Something like this:
#include <stdio.h>
struct dir_t
{
int pos;
int neg;
};
struct cam_temp_t
{
dir_t x;
dir_t y;
dir_t z;
};
// it seems that you have only ints in your structure...
#define TOTAL_N_INTS 8
struct batty_t
{
union
{
int data_[TOTAL_N_INTS];
struct
{
struct cam_temp_t camera_temperature;
int fpga; // you get it...
int bat;
}
};
};
int main(void)
{
struct batty_t example = {
.camera_temperature = {
.x = {3, 4},
.y = {5, 6},
.z = {7, 8}
},
.fpga = 1,
.bat = 2
};
for (int i = 0; i < TOTAL_N_INTS; ++i )
{
printf("%4d", example.data_[i]);
}
return 0;
}
Of course if you have different types, you should use different arrays.
Accessing an int array via a struct and visa-versa like this answer might be valid, might not. Yet I am now not so confident for its use with general types. Leaving this as wiki for anyone to add/amend/delete.
OP later commented that the struct members are not all int. Oh well.
If all members are and forever will be int ...
Access each member, one at a time by int offset.
Some untested code to illustrate the idea:
int print_int_struct(char *dest, size_t d_size, const void *st, size_t s_size) {
if (s_size % sizeof(int) != 0) {
return -1; // bad struct size
}
size_t n = s_size / sizeof(int);
const char *delimiter = "";
for (size_t i = 0; i < n; i++) {
int d;
memcpy(&d, st, sizeof d);
st = (char*) st + sizeof(int);
int len = snprintf(dest, d_size, "%s%d", delimiter, d);
if (len < 0 || (size_t) len >= d_size) {
return -1; // out of room
}
dest += len;
d_size -= len;
delimiter = " ";
}
return 0;
}
struct s1 {
int VBUS_voltage_mV;
int temp_internal_degC;
int status;
...
};
struct s1 st = ...;
char buf[1024];
print_int_struct(buf, sizeof buf, &st, sizeof st);
puts(buf);
I want to read a file containing numbers in two columns.
1 2
3 4
5 6
7 8
I want to place the numbers in the first column into one array, and the ones in the second column into another array. Both of these arrays will always have the same amount of elements. The maximum number of elements permitted in this program is 100.
Here's what I have so far. This just reads in the elements as regular int and prints them out.
while (!feof (filereader))
{
printf ("%d %d\n",col_one,col_two);
fscanf (filereader, "%d %d", &col_one, &col_two);
}
So how do I place the numbers in the first column from the file into one array and the numbers in the second column into an array?
int array1[100];
int array2[100];
int i, size = 0;
while (size<100 && fscanf (filereader, " %d %d", &array1[size], &array2[size])==2)
{
size++;
}
for (i=0; i<size; i++) {
printf("array1[%d] = %d, array2[%d] = %d\n",
i, array1[i], i, array2[i]);
}
add space at the beginning of the format specifier of scanf " %d %d" this will avoid the problem of newlines in your file
Since you've got a maximum size, it's pretty easy. Just define the arrays like so:
int firstArray[100];
int secondArray[100];
int size = 0;
Then do your loop, incrementing the index for each line:
while (!feof (filereader))
{
fscanf (filereader, "%d %d", &col_one, &col_two);
firstArray[size] = col_one;
secondArray[size] = col_two;
size++;
}
Maybe also think about making sure size < 100 in case the file is too long.
I'm writing a method that turns a decimal number into any radix (2-36) and prints the appropriate chars to the screen. The decimalToSymbol() method works correctly. The problem I'm having is in the while loop I assign ans[i] to a char and when I try to print it immediately after it is 0. I have looked online and found this is an OK way to assign the char but am not sure what is going wrong.
void writeRadixB(int decimalNumber, int radixB)
{
char ans[80] = "";
int i = 0;
while(decimalNumber!= 0){
printf("decNum: %d div by rB: %d equals %d\n", decimalNumber, radixB, decimalN
printf("decNum: %d mod by rB: %d equals %d or char %c\n", decimalNumber, radix
printf("i: %d\n", i);
decimalNumber = decimalNumber/radixB;
ans[i] = decimalToSymbol(decimalNumber%radixB);
printf("ans[%d] is %c\n", i, ans[i]);
i++;
}
printf("(%s) radix %d", ans, radixB);
}
You shouldn't change decimalNumber until AFTER you've extracted your digit. That, and your result is backwards.
You should put the line ans[i] = decimalToSymbol(decimalNumber%radixB); before the line decimalNumber = decimalNumber/radixB;, (to not lose a digit). also, you probably want to reverse the string before printing it.