Reputation: 1
So I am writing a function to convert a decimal number to hexadecimal arithmetically. I'm writing a hexadecimal function that will do the conversion and I will call it in main(). I need my hexadecimal function to return a character array of the hex number. I have watched youtube videos and other questions on returning character arrays in different examples but I can't make it work in my code. The error I keep getting is "conflicting types for hexadecimal"
#include<stdio.h>
int main()
{
//receiving name from user
char name[50];
printf("Enter your name: ");
scanf("%s", name);
//recieving integer from user
char hex1[32];
int num;
printf("Enter an integer(1-1,000,000) or type x to exit: ");
scanf("%d", &num);
char hex[30];
printf("Hexadecimal: %s\n", hexadecimal(hex1));
}
char hexadecimal(char x[])
{
int quotient;
int temp, i;
i=1;
quotient = x;
char hex2[32];
memcpy(hex2, x, sizeof(hex2));
while (quotient != 0)
{
temp = quotient%16;
if(temp<10)
temp += 48;
else
temp += 55;
hex2[i++] = temp;
quotient = quotient/16;
}
return hex2;
}
Upvotes: 0
Views: 437
Reputation: 400
Most of the inconsistencies in the code and appropriate measures to rectify them have been pointed out in Eric's response. Hope you read and give heed.
Some specifics of the issue.
num
but call the function
with an uninitialized character array hexadecimal(hex1)
???char hex[30];
quotient = x;
Here's the proposed fix....
#include <stdio.h>
#include <string.h>
char * hexadecimal(int num)
{
int x;
int quotient;
int temp, i;
i=0;
quotient = num;
static char hex2[32];//declaring hex2 as static char array
while (quotient != 0)
{
temp = quotient%16;
/* You can either use this block of code or the single ternary statement listed below
if(temp<10)
temp += '0';
else
temp += 'A' - 10;
hex2[i++] = temp;
*/
hex2[i++] = (temp < 10) ? temp + '0' : temp + 'A' - 10;//you could use this
quotient = quotient/16; //ternary statement or the block above
}
hex2[i] = '\0';//terminate the array with NULL character
//Since the result would be in reverse
//the following will reverse the string hex2 in place
for(i = 0,x = strlen(hex2)-1;i < x;i++,x--){
temp = hex2[i];
hex2[i] = hex2[x];
hex2[x] = temp;
}
return hex2;
}
int main()
{
char name[50];
printf("Enter your name: ");
scanf("%s", name);
int num;
printf("Enter an integer(1-1,000,000) or type x to exit: ");
scanf("%d", &num);
printf("Hexadecimal: %s\n", hexadecimal(num));
}
Upvotes: 0
Reputation: 222302
The code in the question calls the hexadecimal
function in main
but has not declared it yet. This results in the compiler using a default declaration in which hexadecimal
returns int
.
The later definition of hexadecimal
to return a char
conflicts with this.
To remedy this, either move the entire definition of hexadecimal
before main
or put a declaration of hexadecimal
before main. A function can be declared using the same line that starts its definition, except that line is ended with a ;
for a declaration instead of a list of statements in braces { ... }
for a definition.
For two decades, standard C has required functions to be declared. Refer to your compiler documentation to find out how to tell the compiler to use a modern C standard. If you are using GCC or Clang, you can use the command-line switch -std=c17
to request the 2017/2018 C standard.
If you are using GCC or Clang, use the command-line switch -Wmost
or -Wall
to enable many warning messages, and use -Werror
to make warnings into errors. If you are using another compiler, refer to its documentation.
When the compiler prints a warning message, figure out what it means and fix it before proceeding.
A function declared with char hexadecimal(char x[])
returns only a single char
. You want to return a string of characters. A string of characters is a sequence of characters terminated by a null character.
Strings are referred to by pointers to their first character. So the base type used for referring to a string is char *
. Your function should be declared as char *hexadecimal(char x[])
. (It can also be declared as char *hexadecimal(char *x)
, because an array parameter is automatically adjusted to be a pointer.)
Your function defines an array with char hex2[32];
and attempts to return it with return hex2;
. An object defined this way inside a function has automatic storage duration, which means the C implementation provides memory for it within the function call and releases that memory when the function returns. The address of an automatic object should never be returned from its function, because its memory is no longer reserved for use (and because the pointer technically becomes invalid).
Remove char hex2[32];
and instead use:
char *hex2 = malloc(32 * sizeof *hex2);
if (!hex2)
{
fprintf(stderr, "Error, malloc failed.\n");
exit(EXIT_FAILURE);
}
This will attempt to allocate memory with malloc
. If the allocation fails, it will print a message and terminate the program. Since this uses new routines from the standard library, you should insert this at the beginning of your program:
#include <stdlib.h>
This allocates memory but does not release it. In larger programs where managing memory is a concern, the memory should be released. In this case, the caller, when they are done with the memory, should release it, as with free(x);
, where x
is a char *
that contains the pointer value returned from the function.
The end of a string is marked with a null character. After the hexadecimal
function has put the characters it wants in the string, it should put a null character at the end, with:
hex2[i] = '\0';
It is important to ensure there is space for this character in the allocated space—always include it in the counts of how much space is needed.
Do not use 48
for the character “0” or 55
for the difference between A
and ten. This is not strictly conforming C, and needlessly so, because C makes it easy to make this code portable. Additionally, hardcoded constants do not convey the intent, whereas using character values do. Change this code:
if(temp<10)
temp += 48;
else
temp += 55;
to:
if (temp < 10)
temp += '0';
else
temp += 'A' - 10;
This makes it much more apparent to a reader what the intent is. It is still not fully portable, because the C standard (5.2.1/3 in the C17 draft) does not guarantee the characters “A” through “F” have consecutive values in the character encoding (it does for the digits “0” through “9”), but it is an improvement.
Upvotes: 5
Reputation:
You would have to pass in an array as an argument initially or create an array with a malloc call because the array would otherwise be local storage to the block and that space, while it may exist for a bit, if at all after returning from the function, the memory address in the stack would be made available to future calls to overwrite thus corrupting the structure you had intended.
Upvotes: 1