Add comma in a sprintf function - c++

I was looking at topic: How to format a number from 1123456789 to 1,123,456,789 in C?
So I mounted my code based on an existing one.
void printfcomma(char *buf, const char* text int n) {
if (n < 1000) {
sprintf(buf, "%s %d", text, n);
return;
}
printfcomma(buf, n / 1000);
sprintf(buf, "%s ,%03d", text, n %1000);
return;
}
sprintf is only returning the final 3 digits. Example: ,536
Does anyone have any idea why they are not showing the other numbers

You are overwriting.
You should do sprintf(s+ strlen(s),"abcde");
void printfcomma(char *buf,int n) {
if (n < 1000) {
sprintf(buf+strlen(buf), "%d", n);
return;
}
printfcomma(buf, n / 1000);
sprintf(buf+strlen(buf), ",%03d", n %1000);
return;
}
In calling function
memset(s,0,sizeof(s));// s is the char array.
printfcomma(s,100000536);
Output
100,000,536

As answered by #coderredoc, code is over-writing buf.
An alternative to calling strlen() is to take advantage of the return value of sprintf().
The sprintf function returns the number of characters written in the array, not counting the terminating null character, or a negative value if an encoding error occurred. C11dr §7.21.6.6 3
Further: code should handle negative numbers too.
const char* text use is unclear. Example code below does not use it.
int printfcomma(char *buf, int n) {
if (n > -1000 && n < 1000) { // avoid (abs(n) < 1000) here. abs(INT_MIN) is a problem
return sprintf(buf, "%d", n);
}
int len = printfcomma(buf, n / 1000);
if (len > 0) {
len += sprintf(buf + len, ",%03d", text, abs(n % 1000)); // do not print `-`
}
return len;
}
Usage
char s[sizeof(int)*CHAR_BIT]; // Somehow, insure buffer size is sufficient.
printfcomma(s, INT_MIN);
puts(s); --> -2,147,483,648

Related

print fibo big numbers in c++ or c language

I write this code for show fibonacci series using recursion.But It not show correctly for n>43 (ex: for n=100 show:-980107325).
#include<stdio.h>
#include<conio.h>
void fibonacciSeries(int);
void fibonacciSeries(int n)
{
static long d = 0, e = 1;
long c;
if (n>1)
{
c = d + e;
d = e;
e = c;
printf("%d \n", c);
fibonacciSeries(n - 1);
}
}
int main()
{
long a, n;
long long i = 0, j = 1, f;
printf("How many number you want to print in the fibonnaci series :\n");
scanf("%d", &n);
printf("\nFibonacci Series: ");
printf("%d", 0);
fibonacciSeries(n);
_getch();
return 0;
}
The value of fib(100) is so large that it will overflow even a 64 bit number. To operate on such large values, you need to do arbitrary-precision arithmetic. Arbitrary-precision arithmetic is not provided by C nor C++ standard libraries, so you'll need to either implement it yourself or use a library written by someone else.
For smaller values that do fit your long long, your problem is that you use the wrong printf format specifier. To print a long long, you need to use %lld.
Code overflows the range of the integer used long.
Could use long long, but even that may not handle Fib(100) which needs at least 69 bits.
Code could use long double if 1.0/LDBL_EPSILON > 3.6e20
Various libraries exist to handle very large integers.
For this task, all that is needed is a way to add two large integers. Consider using a string. An inefficient but simply string addition follows. No contingencies for buffer overflow.
#include <stdio.h>
#include <string.h>
#include <assert.h>
char *str_revese_inplace(char *s) {
char *left = s;
char *right = s + strlen(s);
while (right > left) {
right--;
char t = *right;
*right = *left;
*left = t;
left++;
}
return s;
}
char *str_add(char *ssum, const char *sa, const char *sb) {
const char *pa = sa + strlen(sa);
const char *pb = sb + strlen(sb);
char *psum = ssum;
int carry = 0;
while (pa > sa || pb > sb || carry) {
int sum = carry;
if (pa > sa) sum += *(--pa) - '0';
if (pb > sb) sum += *(--pb) - '0';
*psum++ = sum % 10 + '0';
carry = sum / 10;
}
*psum = '\0';
return str_revese_inplace(ssum);
}
int main(void) {
char fib[3][300];
strcpy(fib[0], "0");
strcpy(fib[1], "1");
int i;
for (i = 2; i <= 1000; i++) {
printf("Fib(%3d) %s.\n", i, str_add(fib[2], fib[1], fib[0]));
strcpy(fib[0], fib[1]);
strcpy(fib[1], fib[2]);
}
return 0;
}
Output
Fib( 2) 1.
Fib( 3) 2.
Fib( 4) 3.
Fib( 5) 5.
Fib( 6) 8.
...
Fib(100) 3542248xxxxxxxxxx5075. // Some xx left in for a bit of mystery.
Fib(1000) --> 43466...about 200 more digits...8875
You can print some large Fibonacci numbers using only char, int and <stdio.h> in C.
There is some headers :
#include <stdio.h>
#define B_SIZE 10000 // max number of digits
typedef int positive_number;
struct buffer {
size_t index;
char data[B_SIZE];
};
Also some functions :
void init_buffer(struct buffer *buffer, positive_number n) {
for (buffer->index = B_SIZE; n; buffer->data[--buffer->index] = (char) (n % 10), n /= 10);
}
void print_buffer(const struct buffer *buffer) {
for (size_t i = buffer->index; i < B_SIZE; ++i) putchar('0' + buffer->data[i]);
}
void fly_add_buffer(struct buffer *buffer, const struct buffer *client) {
positive_number a = 0;
size_t i = (B_SIZE - 1);
for (; i >= client->index; --i) {
buffer->data[i] = (char) (buffer->data[i] + client->data[i] + a);
buffer->data[i] = (char) (buffer->data[i] - (a = buffer->data[i] > 9) * 10);
}
for (; a; buffer->data[i] = (char) (buffer->data[i] + a), a = buffer->data[i] > 9, buffer->data[i] = (char) (buffer->data[i] - a * 10), --i);
if (++i < buffer->index) buffer->index = i;
}
Example usage :
int main() {
struct buffer number_1, number_2, number_3;
init_buffer(&number_1, 0);
init_buffer(&number_2, 1);
for (int i = 0; i < 2500; ++i) {
number_3 = number_1;
fly_add_buffer(&number_1, &number_2);
number_2 = number_3;
}
print_buffer(&number_1);
}
// print 131709051675194962952276308712 ... 935714056959634778700594751875
Best C type is still char ? The given code is printing f(2500), a 523 digits number.
Info : f(2e5) has 41,798 digits, see also Factorial(10000) and Fibonacci(1000000).
Well, you could want to try implementing BigInt in C++ or C.
Useful Material:
How to implement big int in C++
For this purporse you need implement BigInteger. There is no such build-in support in current c++. You can view few advises on stack overflow
Or you also can use some libs like GMP
Also here is some implementation:
E-maxx - on Russian language description.
Or find some open implementation on GitHub
Try to use a different format and printf, use unsigned to get wider range of digits.
If you use unsigned long long you should get until 18 446 744 073 709 551 615 so until the 93th number for fibonacci serie 12200160415121876738 but after this one you will get incorrect result because the 94th number 19740274219868223167 is too big for unsigned long long.
Keep in mind that the n-th fibonacci number is (approximately) ((1 + sqrt(5))/2)^n.
This allows you to get the value for n that allows the result to fit in 32 /64 unsigned integers. For signed remember that you lose one bit.

How to loop generate random 256bit hex in c or c++?

in python i do :
import random
while True:
x = random.randint(0xF,0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140)
print hex(x)[2:66].lower()
how to do that using C or C++ ?
Using GNU MP library, this can be done like this:
#include <stdio.h>
#include <ctype.h>
#include <gmp.h>
void randint(mpz_t rop, gmp_randstate_t state, mpz_t from, mpz_t to) {
mpz_t range;
mpz_init(range);
/* range = to - from + 1 */
mpz_sub(range, to, from);
mpz_add_ui(range, range, 1);
/* rop = random number in [0, range) */
mpz_urandomm(rop, state, range);
/* rop += from */
mpz_add(rop, rop, from);
mpz_clear(range);
}
int main(void) {
char str[1024]; /* allocate enough memory */
gmp_randstate_t state;
mpz_t low, high;
mpz_t ret;
gmp_randinit_default(state);
mpz_init(ret);
mpz_init_set_str(low, "F", 16);
mpz_init_set_str(high, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140", 16);
for(;;) {
randint(ret, state, low, high);
str[0]='0'; str[1]='x';
mpz_get_str(str + 2, 16, ret);
if (str[0] != '\0' && str[1] != '\0') {
int i;
for (i = 2; i < 66 && str[i] != '\0'; i++) putchar(tolower(str[i]));
}
putchar('\n');
}
/* the control won't come here */
#if 0
mpz_clear(low);
mpz_clear(high);
mpz_clear(ret);
gmp_randclear(state);
return 0;
#endif
}
A very simple solution:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define StringLength (256/4) // (Bits you want)/4 (Thanks, chux)
int main(void){
char cStrHex[(StringLength+1)] = {0};
// Seed random:
srand((unsigned int) time(0));
// Fill the char buffer
int i=0;
for(; i < StringLength; i++){
sprintf(cStrHex+i, "%x", rand() % 16);
}
// Print hex string:
printf("%s\n", cStrHex);
return 0;
}
Please note that rand() is not considered to be cryptographically secure, so replace calls to rand() with a CSPRNG if you want to use this for anything requiring completely unpredictable random number. Nonetheless, this is a short, simple, and efficient solution to your problem.
Here's an approach that uses random(). It attempts to use as many digits as possible. In case of POSIX random(), that's 31 bits, so 7 full digits. With, say, arc4random, you could use 8.
int max_usable_digits = 7;
uint64_t mask = (1 << (4 * max_usable_digits)) - 1;
const char *hex_digits = "0123456789abcdef";
std::string get_random_hex(int digits) {
char buffer[65] = {};
int offset = 0;
while (offset < sizeof(buffer)) {
long r = random() & mask;
offset += snprintf(buffer + offset, sizeof(buffer) - offset,
"%0*lx", max_usable_digits, r);
}
return std::string(buffer);
}
If you can use Boost library, generating_a_random_password example solves your problem with minor modifications.
UPDATE: This returns random strings between 64 zeros and 64 F's. The specific limits in OP's question (of 0xF and 0xFF..140) are a range of valid EDCSA keys. Nearly all 64-digit strings are valid. You can guarantee a number in the range with:
std::string min = "000000000000000000000000000000000000000000000000000000000000000F";
std::string max = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140";
std::string get_random_ecdsa_key() {
while (true) {
std::string s = get_random_hex(64);
if (s >= min && s < max) {
return s;
}
}
}

how to convert unsigned char* to integer fast,

In my project i wrote such function for conversion:
// len should be > 0
uint32_t stringToInt(unsigned char const* buffer, int len) {
uint32_t result = buffer[0] - '0';
for (int i = 1; i < len; i++) {
result *= 10;
result += buffer[i] - '0';
}
return result;
}
Are there any stl / boost methods that can do the same with the same speed? If not so then probaly you can further improve my version?
I can not use atoi because it doesn't allow to provide len. I also don't want to create temp buffer just for atoi call.
From atoi implementation in C, with minor modification to account for length.
int my_atoi(char *p,int len) {
int k = 0;
for (int i=0;i<len;i++) {
k = (k<<3)+(k<<1)+(*p)-'0';
p++;
}
return k;
}
If you want the fastest possible atoi implementation, one way to go would be to check gcc source for their implementation of atoi and modify it to match your additional requirement for length...
Saw this one years ago. Its probably slower but more fun:
int stringToInt(char *buffer, int len) {
if (len > 0) {
return myStoi(buffer + len - 1, len);
}
return 0;
}
int myStoi(char *curr, int len) {
if (--len) {
return myStoi(curr-1, len) * 10 + (*curr - '0');
}
return (*curr - '0');
}
This, like the original, assumes the buffer contents are valid digit characters. (i.e. no leading spaces or dashes or plus-signs, no internal dots or alpha chars)

Get the number of digits in an int

How do I detect the length of an integer? In case I had le: int test(234567545);
How do I know how long the int is? Like telling me there is 9 numbers inside it???
*I have tried:**
char buffer_length[100];
// assign directly to a string.
sprintf(buffer_length, "%d\n", 234567545);
string sf = buffer_length;
cout <<sf.length()-1 << endl;
But there must be a simpler way of doing it or more clean...
How about division:
int length = 1;
int x = 234567545;
while ( x /= 10 )
length++;
or use the log10 method from <math.h>.
Note that log10 returns a double, so you'll have to adjust the result.
Make a function :
int count_numbers ( int num) {
int count =0;
while (num !=0) {
count++;
num/=10;
}
return count;
}
Nobody seems to have mentioned converting it to a string, and then getting the length. Not the most performant, but it definitely does it in one line of code :)
int num = -123456;
int len = to_string(abs(num)).length();
cout << "LENGTH of " << num << " is " << len << endl;
// prints "LENGTH of 123456 is 6"
You can use stringstream for this as shown below
stringstream ss;
int i = 234567545;
ss << i;
cout << ss.str().size() << endl;
if "i" is the integer, then
int len ;
char buf[33] ;
itoa (i, buf, 10) ; // or maybe 16 if you want base-16 ?
len = strlen(buf) ;
if(i < 0)
len-- ; // maybe if you don't want to include "-" in length ?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int i=2384995;
char buf[100];
itoa(i, buf, 10); // 10 is the base decimal
printf("Lenght: %d\n", strlen(buf));
return 0;
}
Beware that itoa is not a standard function, even if it is supported by many compilers.
len=1+floor(log10(n));//c++ code lib (cmath)
looking across the internet it's common to make the mistake of initializing the counter variable to 0 and then entering a pre-condition loop testing for as long as the count does not equal 0. a do-while loop is perfect to avoid this.
unsigned udc(unsigned u) //unsigned digit count
{
unsigned c = 0;
do
++c;
while ((u /= 10) != 0);
return c;
}
it's probably cheaper to test whether u is less than 10 to avoid the uneccessary division, increment, and cmp instructions for cases where u < 10.
but while on that subject, optimization, you could simply test u against constant powers of ten.
unsigned udc(unsigned u) //unsigned digit count
{
if (u < 10) return 1;
if (u < 100) return 2;
if (u < 1000) return 3;
//...
return 0; //number was not supported
}
which saves you 3 instructions per digit, but is less adaptable for different radixes inaddition to being not as attractive, and tedious to write by hand, in which case you'd rather write a routine to write the routine before inserting it into your program. because C only supports very finite numbers, 64bit,32bit,16bit,8bit, you could simply limit yourself to the maximum when generating the routine to benefit all sizes.
to account for negative numbers, you'd simply negate u if u < 0 before counting the number of digits. of course first making the routine support signed numbers.
if you know that u < 1000,
it's probably easier to just write, instead of writing the routine.
if (u > 99) len = 3;
else
if (u > 9) len = 2;
else len = 1;
Here are a few different C++ implementations* of a function named digits() which takes a size_t as argument and returns its number of digits. If your number is negative, you are going to have to pass its absolute value to the function in order for it to work properly:
The While Loop
int digits(size_t i)
{
int count = 1;
while (i /= 10) {
count++;
}
return count;
}
The Exhaustive Optimization Technique
int digits(size_t i) {
if (i > 9999999999999999999ull) return 20;
if (i > 999999999999999999ull) return 19;
if (i > 99999999999999999ull) return 18;
if (i > 9999999999999999ull) return 17;
if (i > 999999999999999ull) return 16;
if (i > 99999999999999ull) return 15;
if (i > 9999999999999ull) return 14;
if (i > 999999999999ull) return 13;
if (i > 99999999999ull) return 12;
if (i > 9999999999ull) return 11;
if (i > 999999999ull) return 10;
if (i > 99999999ull) return 9;
if (i > 9999999ull) return 8;
if (i > 999999ull) return 7;
if (i > 99999ull) return 6;
if (i > 9999ull) return 5;
if (i > 999ull) return 4;
if (i > 99ull) return 3;
if (i > 9ull) return 2;
return 1;
}
The Recursive Way
int digits(size_t i) { return i < 10 ? 1 : 1 + digits(i / 10); }
Using snprintf() as a Character Counter
⚠ Requires #include <stdio.h> and may incur a significant performance penalty compared to other solutions. This method capitalizes on the fact that snprintf() counts the characters it discards when the buffer is full. Therefore, with the right arguments and format specifiers, we can force snprintf() to give us the number of digits of any size_t.
int digits(size_t i) { return snprintf (NULL, 0, "%llu", i); }
The Logarithmic Way
⚠ Requires #include <cmath> and is unreliable for unsigned integers with more than 14 digits.
// WARNING! There is a silent implicit conversion precision loss that happens
// when we pass a large int to log10() which expects a double as argument.
int digits(size_t i) { return !i? 1 : 1 + log10(i); }
Driver Program
You can use this program to test any function that takes a size_t as argument and returns its number of digits. Just replace the definition of the function digits() in the following code:
#include <iostream>
#include <stdio.h>
#include <cmath>
using std::cout;
// REPLACE this function definition with the one you want to test.
int digits(size_t i)
{
int count = 1;
while (i /= 10) {
count++;
}
return count;
}
// driver code
int main ()
{
const int max = digits(-1ull);
size_t i = 0;
int d;
do {
d = digits(i);
cout << i << " has " << d << " digits." << '\n';
i = d < max ? (!i ? 9 : 10 * i - 1) : -1;
cout << i << " has " << digits(i) << " digits." << '\n';
} while (++i);
}
* Everything was tested on a Windows 10 (64-bit) machine using GCC 12.2.0 in Visual Studio Code .
As long as you are mixing C stdio and C++ iostream, you can use the snprintf NULL 0 trick to get the number of digits in the integer representation of the number. Specifically, per man 3 printf If the string exceeds the size parameter provided and is truncated snprintf() will return
... the number of characters (excluding the terminating null byte)
which would have been written to the final string if enough space
had been available.
This allows snprintf() to be called with the str parameter NULL and the size parameter 0, e.g.
int ndigits = snprintf (NULL, 0, "%d", 234567545)
In your case where you simply wish to output the number of digits required for the representation, you can simply output the return, e.g.
#include <iostream>
#include <cstdio>
int main() {
std::cout << "234567545 is " << snprintf (NULL, 0, "%d", 234567545) <<
" characters\n";
}
Example Use/Output
$ ./bin/snprintf_trick
234567545 is 9 characters
note: the downside to using the snprintf() trick is that you must provide the conversion specifier which will limit the number of digits representable. E.g "%d" will limit to int values while "%lld" would allow space for long long values. The C++ approach using std::stringstream while still limited to numeric conversion using the << operator handles the different integer types without manually specifying the conversion. Something to consider.
second note: you shouldn't dangle the "\n" of the end of your sprintf() conversion. Add the new line as part of your output and you don't have to subtract 1 from the length...

Convert char array to single int?

Anyone know how to convert a char array to a single int?
char hello[5];
hello = "12345";
int myNumber = convert_char_to_int(hello);
Printf("My number is: %d", myNumber);
There are mulitple ways of converting a string to an int.
Solution 1: Using Legacy C functionality
int main()
{
//char hello[5];
//hello = "12345"; --->This wont compile
char hello[] = "12345";
Printf("My number is: %d", atoi(hello));
return 0;
}
Solution 2: Using lexical_cast(Most Appropriate & simplest)
int x = boost::lexical_cast<int>("12345");
Solution 3: Using C++ Streams
std::string hello("123");
std::stringstream str(hello);
int x;
str >> x;
if (!str)
{
// The conversion failed.
}
If you are using C++11, you should probably use stoi because it can distinguish between an error and parsing "0".
try {
int number = std::stoi("1234abc");
} catch (std::exception const &e) {
// This could not be parsed into a number so an exception is thrown.
// atoi() would return 0, which is less helpful if it could be a valid value.
}
It should be noted that "1234abc" is implicitly converted from a char[] to a std:string before being passed to stoi().
I use :
int convertToInt(char a[1000]){
int i = 0;
int num = 0;
while (a[i] != 0)
{
num = (a[i] - '0') + (num * 10);
i++;
}
return num;;
}
Use sscanf
/* sscanf example */
#include <stdio.h>
int main ()
{
char sentence []="Rudolph is 12 years old";
char str [20];
int i;
sscanf (sentence,"%s %*s %d",str,&i);
printf ("%s -> %d\n",str,i);
return 0;
}
I'll just leave this here for people interested in an implementation with no dependencies.
inline int
stringLength (char *String)
{
int Count = 0;
while (*String ++) ++ Count;
return Count;
}
inline int
stringToInt (char *String)
{
int Integer = 0;
int Length = stringLength(String);
for (int Caret = Length - 1, Digit = 1; Caret >= 0; -- Caret, Digit *= 10)
{
if (String[Caret] == '-') return Integer * -1;
Integer += (String[Caret] - '0') * Digit;
}
return Integer;
}
Works with negative values, but can't handle non-numeric characters mixed in between (should be easy to add though). Integers only.
For example, "mcc" is a char array and "mcc_int" is the integer you want to get.
char mcc[] = "1234";
int mcc_int;
sscanf(mcc, "%d", &mcc_int);
With cstring and cmath:
int charsToInt (char* chars) {
int res{ 0 };
int len = strlen(chars);
bool sig = *chars == '-';
if (sig) {
chars++;
len--;
}
for (int i{ 0 }; i < len; i++) {
int dig = *(chars + i) - '0';
res += dig * (pow(10, len - i - 1));
}
res *= sig ? -1 : 1;
return res;
}
Ascii string to integer conversion is done by the atoi() function.
Long story short you have to use atoi()
ed:
If you are interested in doing this the right way :
char szNos[] = "12345";
char *pNext;
long output;
output = strtol (szNos, &pNext, 10); // input, ptr to next char in szNos (null here), base