This code need to get an int number and convert it to array of char that present the number:
for example :
The number 324
convert to this:
like:
char newstr [6] = {'3','2','4','\0','\0','\0'};
I think that '\0' is null, right?
What is wrong with my code ?
also how can I change this to a function that get an int number and return array of char that present it?
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
void main ()
{
int value = 324;
char str [6];
char newstr [6];
int pointer, i = 0;
for(i=0; value>0; i++)
{
str[i] = value%10 + '0';
value /=10;
}
str[i] = '\0';
for(i=5; i>-1; i--)
{
if(str[i]!='\0')
{
newstr[pointer] = str[i];
pointer++;
}
}
for (i = 0; i < 6; i++)
{
printf("%d %c\n", i, newstr[i] );
}
printf ("shalom");
}
An easy way should be calling sprintf().
char newstr[6] = {0};
sprintf(newstr, "%d", value);
In your existing code, str looks lile {'4', '2', '3', '\0', SomethingRandom, SomethingRandom}. Reversing it and assign to newstr makes it {SomethingRandom, SomethingRandom, '\0', '3', '2', '4'}, which is definitely not what you want. And indeed you don't assign newstr when str[i] == '\0', which means newstr[2] == SomethingRandom.
Try the following
#include <stdio.h>
#include <stdlib.h>
char * itoa( int x )
{
const unsigned int BASE = 10;
unsigned int u = abs( x );
size_t n = 0;
unsigned int tmp = u;
char *s;
do { ++n; } while ( tmp /= BASE );
n += x < 0;
s = malloc( ( n + 1 ) * sizeof( char ) );
s[n] = '\0';
do
{
s[--n] = u % BASE + '0';
} while ( u /= BASE );
if ( x < 0 ) s[--n] = '-';
return s;
}
int main(void)
{
char *s = itoa( -1234567890 );
printf( "%s\n", s );
free( s );
return 0;
}
The output is
-1234567890
As for your question what is wrong with your code then it is entirely wrong.:)
For example the code ignores numbers that are equal to zero. Variable pointer was not initialized
int pointer, i = 0;
each loop deals with some garbage and so on.
It will be more helpful for you if you will investigate my code.
OP's code looks very close to being correct for limited usage.
Do not start with value>0 test, otherwise when value == 0, the result will be "". Be sure to limit the number of iterations to not exceed the array size.
do {
str[i] = value%10 + '0';
value /=10;
i++;
} while (value>0 && i < (6-1));
Set '\0' in a loop. #timra points out random unset elements.
do {
str[i] = '\0';
i++;
} while (i < (6-1));
OP still has 2 remaining issues which OP has yet to specify what to do:
Values greater than 99999
Values < 0
BTW: "I think that '\0' is null, right?" '\0' is the "null character". This differs from NULL, the "null pointer".
"how can I change this to a function that get an int number and return array of char that present it"
OP's code has a number of corner problems. Suggest a new approach.
Perform conversion into local array and then return a copy of it.
Calling code should eventually free() it.
#include <limits.h>
// max size needed for int. Note 10/33 just greater than log(2)
#define INTSIZE_MAX (sizeof int * CHAR_BIT * 10 / 33 + 3)
char *intoa_alloc(int x) {
char buf[INTSIZE_MAX];
char *p = &buf[sizeof buf - 1];
// Work with negative absolute value to cope with INT_MIN
// This avoids portability problems with abs(x) approach.
int x_negative = x < 0 ? x : -x;
// Form string
*p = '\0';
do {
*--p = '0' - x_negative % 10;
x_negative /= 10;
} while (x_negative);
if (x < 0) {
*--p = '-';
}
char *dest = malloc(strlen(p) + 1);
if (dest) {
strcpy(dest, p);
}
return dest;
}
In this simple way you can do that.
int main()
{
char str [6] = "324";
printf ("%c",str[1]);
return 0;
}
Related
i need to write a function that randomize length of string, allocate dynamic memory for it and than randomize small letters inside it.
the main program should print 15 words from the function.
the function by itself works for me, i just can't pass it from the main program.
my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 15
char randWord() {
int len;
srand(time(NULL));
len = (rand() % 10) + 1;
char * word = malloc(len);
for (int i = 0; i < len; i++) {
word[i] = ((rand() % 26) + 97);
}
return word;
}
int main() {
char* s;
int i;
for (i = 0; i < N; i++) {
randWord(s);
printf("%s\n", s);
free(s);
}
return 0;
}
You need to modify your function to accept parameters, and potentially return a char pointer.
char* randWord(char* s)
I think you might have a misunderstanding of functions in general. They can optionally take in parameters, and optionally return something.
A really simple example would be something like this:
int addOne(int x) {
return x + 1;
}
It may help to think of programming functions in terms of math functions. the above is equivalent to f(x)=x+1. So f(1) "returns" 2, f(2) is 3 and so on.
The function is declared without parameters
char randWord() {
but you are passing a pointer of the type char *.
randWord(s)
The function returns a pointer of the type char * but its return type is char.
char randWord() {
int len;
srand(time(NULL));
len = (rand() % 10) + 1;
char * word = malloc(len);
for (int i = 0; i < len; i++) {
word[i] = ((rand() % 26) + 97);
}
return word;
}
Also the function does not build a string because the dynamically allocated character array does not contain the terminating zero character '\0'.
And it is a bad style of programming to use magic numbers like 97.
Redefine the function at least like
char * randWord( void ) {
size_t len = (rand() % 10) + 1;
char * word = malloc(len);
if ( word != NULL )
{
size_t i = 0;
for (; i < len - 1; i++) {
word[i] = ((rand() % 26) + 'a');
}
word[i] = '\0';
}
return word;
}
and in main write
s = randWord();
if ( s != NULL ) puts( s );
free( s );
This statement
srand(time(NULL));
should be moved from the function to main before its for loop.
Here is your code annotated and altered to function correctly.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 15
char *randWord() { // Return ptr to word buffer (the string)
int len = rand() % 10 + 1; // knowing operator precedence avoids overuse of ( )
char *word = malloc( len + 1 ); // allow room for '\0'
if( word == NULL )
exit( EXIT_FAILURE ); // do not presume success
// Here "len" is the # of chars to generate (at least one)
for( int i = 0; i < len; i++ ) {
word[i] = rand() % 26 + 'a'; // use ASCII value, not magic number
}
word[i] = '\0'; // TERMINATE the string
return word;
}
int main() { // be consistent with braces
srand( time( NULL ) ); // Seed the random number generator only once
for( int i = 0; i < N; i++ ) { // Be consistent
char *s = randWord(); // declare variables proximate to use. Strive for clarity
puts( s ); // Simpler function than printf
free( s );
}
return 0;
}
It is a subtlety of your code that the returned string will always be at least one character long.
I was trying to solve a coding problem to covert an integer to a string using C. e.g. if there is an integer 321, then the function should return a string "321". My character assignment seems to be successful based on the output during the assignment. However, once the assignment is complete, my string is completely empty. Not sure why this would be happening. I am guessing it has something to do with the null terminating character?
char * solution(int X) {
printf("x is %d\n", X);
int len = len_num (X); //Returns correct length as tested.
printf("Length is %d\n", len);
char * str = (char*)malloc( (++len * sizeof(char)) ); //one extra space for '\0'
str[len] = '\0'; //Assigning the last character as null terminating character '\0'
int i = len - 1 ;
do
{
int n = X%10;
str[i] = '0' + n;
printf("str[%i]:%c, n:%d.\n", i, str[i], n);
X = X / 10;
i--;
}while (i > 0);
printf("\nstr:%s.\n", str);
return str;
}
Output:
x is 942
Length is 3
str[1]:2, n:2. <---- All assignments are successful
str[2]:4, n:4.
str[3]:9, n:9.
str:. <----This shouldn't be empty!
You have some off-by-one errors.
The first is here:
char * str = (char*)malloc( (++len * sizeof(char)) ); //one extra space for '\0'
str[len] = '\0'; //Assigning the last character as null terminating character '\0'
You allocate enough space, but because len was incremented str[len] is off the end of allocated memory, and writing to caused undefined behavior. You instead want:
char * str = malloc( len + 1 );
Noting that you shouldn't cast the return value of malloc and that sizeof(char) is defined to be 1.
Related to this, at the bottom of the loop you decrement i and then check if it is greater than 0. This means you never write to element 0 of the array. You want:
do
{
...
}while (i >= 0);
For starters this statement
str[len] = '\0';
writes beyond the allocated character array that was allocated in this declaration using the sub-expression ++len.
char * str = (char*)malloc( (++len * sizeof(char)) );
So already the program has undefined behavior.
Also due to the condition of the while loop
while (i > 0);
you never set the element of the array str[0].
As the function parameter has the signed integer type int then the user can pass a negative number. You should process such a situation correctly.
The function can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
#include <stdlib.h>
size_t len_num( int x )
{
const int Base = 10;
size_t n = 0;
do
{
++n;
} while ( x /= Base );
return n;
}
char * solution( int x )
{
const int Base = 10;
size_t len = len_num( x );
int sign = x < 0;
if ( sign ) ++len;
char *s = (char * )malloc( len + 1 );
if ( s )
{
s[len] = '\0';
do
{
s[--len] = ( sign ? -( x % Base ) : ( x % Base ) ) + '0';
} while ( x /= Base );
if ( sign ) s[--len] = '-';
}
return s;
}
int main(void)
{
int x = 12345;
char *s = solution( x );
if ( s ) puts( s );
free( s );
x = -12345;
s = solution( x );
if ( s ) puts( s );
free( s );
return 0;
}
The program output is
12345
-12345
I'm trying to split a string into chunks of 6 using C and I'm having a rough time of it. If you input a 12 character long string it just prints two unusual characters.
#include <stdio.h>
#include <string.h>
void stringSplit(char string[50])
{
int counter = 0;
char chunk[7];
for (unsigned int i = 0; i < strlen(string); i++)
{
if (string[i] == ' ')
{
continue;
}
int lastElement = strlen(chunk) - 1;
chunk[lastElement] = string[i];
counter++;
if (counter == 6)
{
printf(chunk);
memset(chunk, '\0', sizeof chunk);
counter = 0;
}
}
if (chunk != NULL)
{
printf(chunk);
}
}
int main()
{
char string[50];
printf("Input string. \n");
fgets(string, 50, stdin);
stringSplit(string);
return(0);
}
I appreciate any help.
Your problem is at
int lastElement = strlen(chunk) - 1;
Firstly, strlen counts the number of characters up to the NUL character. Your array is initially uninitialized, so this might cause problems.
Assuming your array is filled with NULs, and you have, let's say, 2 characters at the beginning and you are looking to place the third one. Remember that your 2 characters are at positions 0 and 1, respectively. So, strlen will return 2 (your string has 2 characters), you subtract one, so the lastElement variable has the value 1 now. And you place the third character at index 1, thus overwriting the second character you already had.
Also, this is extremely inefficient, since you compute the number of characters each time. But wait, you already know how many characters you have (you count them in counter, don't you?). So why not use counter to compute the index where the new character should be placed? (be careful not to do the same mistake and overwrite something else).
The function is wrong.
This statement
int lastElement = strlen(chunk) - 1;
can result in undefined behavior of the function because firstly the array chunk is not initially initialized
char chunk[7];
and secondly after this statement
memset(chunk, '\0', sizeof chunk);
the value of the variable lastElement will be equal to -1.
This if statement
if (chunk != NULL)
{
printf(chunk);
}
does not make sense because the address of the first character of the array chunk is always unequal to NULL.
It seems that what you mean is the following.
#include <stdio.h>
#include <ctype.h>
void stringSplit( const char s[] )
{
const size_t N = 6;
char chunk[N + 1];
size_t i = 0;
for ( ; *s; ++s )
{
if ( !isspace( ( unsigned char )*s ) )
{
chunk[i++] = *s;
if ( i == N )
{
chunk[i] = '\0';
i = 0;
puts( chunk );
}
}
}
if ( i != 0 )
{
chunk[i] = '\0';
puts( chunk );
}
}
int main(void)
{
char s[] = " You and I are beginners in C ";
stringSplit( s );
}
The program output is
Youand
Iarebe
ginner
sinC
You can modify the function such a way that the length of the chunk was specified as a function parameter.
For example
#include <stdio.h>
#include <ctype.h>
void stringSplit( const char s[], size_t n )
{
if ( n )
{
char chunk[n + 1];
size_t i = 0;
for ( ; *s; ++s )
{
if ( !isspace( ( unsigned char )*s ) )
{
chunk[i++] = *s;
if ( i == n )
{
chunk[i] = '\0';
i = 0;
puts( chunk );
}
}
}
if ( i != 0 )
{
chunk[i] = '\0';
puts( chunk );
}
}
}
int main(void)
{
char s[] = " You and I are beginners in C ";
for ( size_t i = 3; i < 10; i++ )
{
stringSplit( s, i );
puts( "" );
}
}
The program output will be
You
and
Iar
ebe
gin
ner
sin
C
Youa
ndIa
rebe
ginn
ersi
nC
Youan
dIare
begin
nersi
nC
Youand
Iarebe
ginner
sinC
YouandI
arebegi
nnersin
C
YouandIa
rebeginn
ersinC
YouandIar
ebeginner
sinC
How can I trim a string into pieces of N numbers of characters and then pass them as an array of strings into a function?
This in a part of my program that converts binary<->hex.
I tried doing the same thing with strings but it did not work.
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <String.h>
#define MAXDIGITS 8 // 8bits
int main()
{
int y;
printf("Binary-Hex convertor\n");
printf("Enter the Binary value : ");
scanf("%d", &y);
int i = MAXDIGITS - 1;
int array[MAXDIGITS];
while(y > 0)
{
array[i--] = y % 10;
y /= 10;
}
printf("%s", "-----------------\n");
printf("%s", "HEX:");
int x = array[0];
int x1 = array[1];
int x2 = array[2];
int x3 = array[3];
int x4 = array[4];
int x5 = array[5];
int x6 = array[6];
int x7 = array[7];
char buffer[50];
char buffer2[50];
char buffer3[50];
}
If its just binary to hex from a string then this is much easier....
char *input_string = "1001010101001010";
int count = 0;
int value = 0;
while ( *input_string != '\0' )
{
// Might be worth checking for only 0 and 1 in input string
value <<= 1;
value |= (int)((*input_string--) - '0');
if ( ++count == 8 || *input_string == '\0' )
{
// USE value to print etc, if you want to display use
// the following else you could store this in an array etc.
printf("%x ", value);
count = 0;
value = 0;
}
}
Do you have to null terminate the strings, do you have a limit on this memory used. Do you need to allocate the memory correctly etc? A bit more info would be useful
const char *input_string = "HELLO THIS IS SOME INPUT STRING";
int N = 4; // The number to split on
// Work out how many strings we will end up in
int number_of_strings = (strlen(input_string) + (N - 1)) / N;
// ALlow for an extra string if you want to null terminate the list
int memory_needed = ((number_of_strings + 1) * sizeof(char *)) + (number_of_strings * (N + 1));
char *buffer = malloc(memory_needed);
char **pointers = (char **)buffer;
char *string_start = (buffer + ((number_of_strings + 1) * sizeof(char *));
int count = 0;
while ( *input_string != '\0' )
{
// Fresh string
if ( count == 0 )
{
*pointers++ = string_start;
*pointers = NULL; // Lazy null terminate
}
// Copy a character
*string_start++ = *input_string++;
*string_start = '\0'; // Again lazy terminat
count++;
if ( count == N )
{
count = 0;
string_start++; // Move past the null terminated string
}
}
You can then pass (char **)buffer; to a routine. I havent actually tried this, ive been lazy in the terminating of the strings. You could just terminate at the end of a count run and the end of the while loop. This isnt exactly pretty code, but it should do the job. Bit more info on the other requirements might be good.
I am writing this code to convert a hex entry into its integer equivalent. So A would be 10 and B would be 11 etc. This code acts weirdly, in that it seg. faults at random locations and including an extra newline character at times will get it to work. I am trying to debug it, just so I can understand what I am doing wrong here. Can anyone take a look and help me here ? Thanks a lot for your time.
/* Fixed working code for anyone interested */
#include <stdio.h>
#include <stdlib.h>
unsigned int hextoint(const char temp[])
{
int i;
int answer = 0;
int dec;
char hexchar[] = "aAbBcCdDeEfF" ;
for ( i=0; temp[i] != '\0'; i++ )
{
if ( temp[i] == '\0')
{
return ;
}
if (temp[i] == '0' || temp[i] == 'x' || temp[i] == 'X' )
{
printf("0");
answer = temp[i];
}
// compare each temp[i] with all contents in hexchar[]
int j;
int a = temp[i];
for ( j=0; hexchar[j] != '\0'; j++)
{
if ( temp[i] == hexchar[j] )
{
answer *= 16;
answer = answer + 10 + (j/2);
// printf("%d\n",answer );
break;
}
}
}
return answer;
}
main()
{
char *test[] =
{ "bad",
"aabbdd"
"0100",
"0x1",
"0XA",
"0X0C0BE",
"abcdef",
"123456",
"0x123456",
"deadbeef",
"zog_c"
};
int answer=0;
// Calculate the number of char's.
int numberOfChars;
numberOfChars = sizeof test /sizeof test[0];
printf("main():Number of chars = %d\n",numberOfChars);
int i;
// Go through each character and convert Hex to Integers.
for ( i = 0; i<numberOfChars;i++)
{
// Need to take the first char and then go through it and convert
it.
answer = hextoint(test[i]);
printf("%d\n",answer );
}
}
Let's take a look.
unsigned int hextoint(const char temp[])
{
int i;
int answer = 0;
char hexchar[] = "aAbBcCdDeEfF" ;
for ( i=0; temp[i] != '\0'; i++ )
{
printf("In here");
printf("%c\t",temp[i] );
}
return answer;
}
This doesn't seem to even try to do any conversion. It should always return 0, since answer is never assigned any other value. Normally, you'd do something like:
for (i=0; input[i] != '\0'; i++) {
answer *= 16;
answer += digit_value(input[i]);
}
return answer;
Where digit_value (obviously enough) returns the value of an individual digit. One way to do this is:
int digit_value(char input) {
input = tolower(input);
if (input >= '0' && input <= '9')
return input - '0';
if (input >= 'a' && input <= 'f')
return input - 'a' + 10;
return -1; // signal error.
}
Then, looking at main:
main()
{
Depending on the "implicit int" rule is generally poor practice, at least IMO. It's much better to specify the return type.
// Calculate the number of char's.
int numberOfChars;
numberOfChars = sizeof test /sizeof test[0];
This actually calculates the number of strings, not the number of chars.
for ( i = 0; i<=numberOfChars;i++)
Valid subscripts run from 0 through the number of items - 1, so this attempts to read past the end of the array (giving undefined behavior).
This'll work for any number within the unsigned int range, the nice thing is it does not use any other library functions so it is great for micro-controllers where space is tight.
unsigned int hexToInt(const char *hex)
{
unsigned int result = 0;
while (*hex)
{
if (*hex > 47 && *hex < 58)
result += (*hex - 48);
else if (*hex > 64 && *hex < 71)
result += (*hex - 55);
else if (*hex > 96 && *hex < 103)
result += (*hex - 87);
if (*++hex)
result <<= 4;
}
return result;
}
The problem is with calculating numberOfChars part. sizeof test is actually the size of the pointer, not the total length of all characters in your array, so the number returned in your code would be 1, which makes the for loop go to the second index of test (test[1]) which does not have a \0 at the end. Try using strlen for calculating numberOfChars.
This may not me the most optimal method, but it should work without problem.
unsigned int hex_to_int(const char* hex) {
unsigned int result = 0;
size_t len = strlen(hex);
for (size_t i = 0; i < len; ++i) {
char cur_char = tolower(hex[len - i - 1]);
// direct return if encounter any non-hex character.
if (!(isdigit(cur_char) && (cur_char >= 'a' && cur_char <= 'f'));)
return result;
unsigned int char_val = (isdigit(cur_char) ? cur_char - '0' : 10 + cur_char - 'a');
result += round(pow(16, i)) * char_val;
}
return result;
}