Ilan Aizelman WS
Ilan Aizelman WS

Reputation: 1632

How do I convert from unsigned char to long

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

Answers (3)

Xcross
Xcross

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

Roland Illig
Roland Illig

Reputation: 41635

You have several errors in the fromDecToBinary function:

  • Replace the '/0' with '\0'.
  • Store '0' + tmpSubjectStatus % 2 in the array.
  • Add proper error handling to the strtol call.
  • Change the return type to long.

Upvotes: 1

Harry
Harry

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

Related Questions