Reputation: 1632
I have a problem to convert from unsigned char into long.
The mission: I have 25
in (unsigned char) ptr->studentArr[i].subjectStatus
when i = 0
, I go into the function unsigned char fromDecToBinary(unsigned char tmpSubjectStatus)
, and I want in that function to get unsigned long 11001
into variable ret
and then fprintf
it into output.txt
file.
Expectation: to fprintf into the file 11001
when i = 0
, problem: it prints 25
instead(if I use fromDecToBinary
function, it prints 0
).
Please, just look at the 2 functions: outPutStudents
and fromDecToBinary
, other functions work properly, and those other functions just get the information and store the info. into structures which are then used to print the details into output.txt
, most of them work, except the binary thingy.
input.txt file:
Nir 32251 99.80 11001
Ely 12347 77.89 01111
Moshe 45321 50.34 11111
Avi 31456 49.78 00011
*NOTE: this is the output without using the function fromDecToBinary
output.txt file:
Student 1: Nir 32251 99.80 25
Student 2: Ely 12347 77.89 15
Student 3: Moshe 45321 50.34 31
Student 4: Avi 31456 49.78 3
Code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
typedef struct Student{
char* studentName; //Dyn. alloc. of stud. name
long id; // ID Number
float mark; // mark
unsigned char subjectStatus;
}Student;
typedef struct University{
Student* studentArr; // Dync. Alloc(Realloc) of students
int numOfStudents; //num of students
}University;
void getStudents(University *ptr);
unsigned char stringToBinary(unsigned char tmpSubjectStatus[]);
void outPutStudents(University *ptr);
unsigned char fromDecToBinary(University *ptr);
void main()
{
printf("Please enter details of student: (a)");
University uni;
getStudents(&uni); //Send address of structure University, because we want to change it not make a local copy of it
outPutStudents(&uni);
getch();
}
void getStudents(University *ptr)
{
FILE *op;
char tmpStudentName[20];
long tmpId;
float tmpMark;
char tmpSubjectStatus[6];
ptr->numOfStudents = 0;
if ((op = fopen("input.txt", "r")) == NULL)
{
printf("Failed to open file.");
}
ptr->studentArr = (Student*)malloc(sizeof(Student));
if (ptr->studentArr == NULL){
printf("Error: memory was not allocated.");
exit(1);
}
while (fscanf(op, "%s %ld %f %s", tmpStudentName, &tmpId, &tmpMark, tmpSubjectStatus) == 4)
{
ptr->numOfStudents++;
ptr->studentArr = (Student*)realloc(ptr->studentArr, sizeof(Student) * ptr->numOfStudents); /*Additional code for Realloc fails - we didn't study!*/
ptr->studentArr[ptr->numOfStudents - 1].studentName = (char*)malloc(sizeof(char)* strlen(tmpStudentName));
if (!(ptr->studentArr[ptr->numOfStudents - 1].studentName)) //if we failed to allocate memory for studentName
{
while (ptr->numOfStudents > 0)
{
free(ptr->studentArr[ptr->numOfStudents - 1].studentName); //free student name
ptr->numOfStudents--; // decrease numOfStudents by one
}
free(ptr->studentArr); //if all student names are free, we need to free the array
printf("Student name was not allocated.");
exit(1);
}
strcpy(ptr->studentArr[ptr->numOfStudents - 1].studentName, tmpStudentName);
ptr->studentArr[ptr->numOfStudents - 1].id = tmpId;
ptr->studentArr[ptr->numOfStudents - 1].mark = tmpMark;
ptr->studentArr[ptr->numOfStudents - 1].subjectStatus = stringToBinary(tmpSubjectStatus); //atoi: from "11001"(string) to 11001(int),then casting to unsigned char
}
fclose(op);
}
void outPutStudents(University *ptr)
{
int i;
FILE *fp;
unsigned char tmpSubjectStatus;
long val;
if ((fp = fopen("output.txt", "w")) == NULL)
{
printf("Couldn't open output file.");
exit(1);
}
for (i = 0; ptr->numOfStudents != i; i++){
tmpSubjectStatus = ptr->studentArr[i].subjectStatus;
val = fromDecToBinary(tmpSubjectStatus);
fprintf(fp, "Student %d: %s %ld %.2f %ld \n", i + 1, ptr->studentArr[i].studentName, ptr->studentArr[i].id, ptr->studentArr[i].mark, tmpSubjectStatus);
}
fclose(fp);
}
unsigned char stringToBinary(char tmpSubjectStatus[])
{
unsigned char tmpBinaryCh = 0;
int i;
for (i = 0; i < 5; i++){
if (tmpSubjectStatus[i] == '1') tmpBinaryCh += 1 << (4 - i);
}
return tmpBinaryCh;
}
unsigned char fromDecToBinary(unsigned char tmpSubjectStatus)
{
int i;
long ret;
char arrBinary[6];
for (i = 0; i < 5; i++){
arrBinary[4 - i] = tmpSubjectStatus % 2;
tmpSubjectStatus /= 2;
}
arrBinary[5] = '/0';
ret = strtol(arrBinary, NULL, 10);
return ret;
}
Upvotes: 0
Views: 1250
Reputation: 2132
#include <stdio.h>
int main()
{
unsigned char tmpSubjectStatus=25;
long quotient = tmpSubjectStatus;
long remainder;
long binary=0;
long multiplier=1;
while(quotient!=0){
remainder=quotient % 2;
binary=binary+(remainder*multiplier);
multiplier=multiplier*10;
quotient = quotient / 2;
}
printf("%ld",binary);
return 0;
}
Try this. In the function it will be like this
long fromDecToBinary(unsigned char tmpSubjectStatus)
{
long quotient = tmpSubjectStatus;
long remainder;
long binary=0;
long multiplier=1;
while(quotient!=0){
remainder=quotient % 2;
binary=binary+(remainder*multiplier);
multiplier=multiplier*10;
quotient = quotient / 2;
}
return binary;
}
In here return type is changed to long.
Upvotes: 0
Reputation: 41635
You have several errors in the fromDecToBinary
function:
'/0'
with '\0'
.'0' + tmpSubjectStatus % 2
in the array.strtol
call.long
.Upvotes: 1
Reputation: 11648
If you want to print some binary using numbers use this.
#include <stdio.h>
#include <stdlib.h>
void print_bin(uint64_t num, size_t bytes) {
int i = 0;
for(i = bytes * 8; i > 0; i--) {
(i % 8 == 0) ? printf("|") : 1;
(num & 1) ? printf("1") : printf("0");
num >>= 1;
}
printf("\n");
}
int main(void) {
int arg = atoi("25");
print_bin(arg, 1);
return 0;
}
It also prints a vertical bar every 8 bits to make the bytes easier to read but you can just remove that.
If you want to specify how many bytes you want use this
#include <stdio.h>
#include <stdlib.h>
void print_bin(uint64_t num, size_t bytes) {
int i = 0;
for(i = bytes * 8; i > 0; i--) {
(i % 8 == 0) ? printf("|") : 1;
(num & 1) ? printf("1") : printf("0");
num >>= 1;
}
printf("\n");
}
int main(void) {
print_bin(16000, 3);
return 0;
}
Upvotes: 0