Convert numbers with toString in Ansi C - c

Is it possible to use toString operator, or how to convert numbers to char arrays.

int myNumber = 27; /* or what have you */
char myBuffer[100];
snprintf(myBuffer, 100, "%d", myNumber);
There are several considerations for you to think about here. Who provides the memory to hold the string? How long do you need it for, etc? (Above it's a stack buffer of 100 bytes, which is way bigger than necessary for any integer value being printed.)
Best answer: start using Java. Or Javascript, or C#, or for the love of God almost anything but C. Only tigers lie this way.

Use the sprintf() function.

sprintf() is considered unsafe because it can lead to a buffer overflow. If it's available (and on many platforms it is), you should use snprintf() instead.
Consider the following code:
#include <stdio.h>
int main()
{
int i = 12345;
char buf[4];
sprintf(buf, "%d", i);
}
This leads to a buffer overflow. So, you have to over-allocate a buffer to the maximum size (as a string) of an int, even if you require fewer characters, since you have the possibility of an overflow. Instead, if you used snprintf(), you could specify the number of characters to write, and any more than that number would simply be truncated.
#include <stdio.h>
int main()
{
int i = 12345;
char buf[4];
snprintf(buf, 4, "%d", i);
//truncates the string to 123
}
Note that in either case, you should take care to allocate enough buffer space for any valid output. It's just that snprintf() provides you with a safety net in case you haven't considered that one edge case where your buffer would otherwise overflow.

Related

How to get size_t from string?

I need to get an array size from user input. It seemed natural to me to store the input as size_t, however looking for an appropriate strto...() function I couldn't find any. I just used strtoull(), since unsigned long long is guaranteed to be at least 64 bits and I'm using C99 anyway. But I was wondering what would be the best way to get size_t from a string - say, in ANSI C.
Edit:
To clarify, I don't want the string length! The user will input the size of a large buffer in the form of a string, for instance "109302393029". I need to get that number and store as size_t. Of course I could use strtol() or even atoi(), but it seems like a clumsy hack (size_t may hold larger values than int, for instance, and I want the user to be able to input any value in the addressable space).
In case you have a string input containing the value for a size_t and you want to get the value, you can use sscanf() with %zu format specifier to read the value and store it into corresponding size_t variable.
Note: do not forget to check the success of sscanf() and family.
Pseudo-code:
size_t len = 0;
if (1 == sscanf(input, "%zu", &len))
printf("len is %zu\n", len);
However, FWIW, this won't handle the overflow case. In case of the input length being arbitaryly large which your program should be able to handle, you may want to make use of strtoumax() and check for overflow, finally casting the returned value to size_t. Please see Mr. Blue Moon's answer related to this.
However, if you don't mind another approach, instead of taking the input as sting and converting it to size_t, you can directly take the input as size_t, like
size_t arr_size = 0;
scanf("%zu", &arr_size);
You can use strtoumax() to perform the conversion:
#include <inttypes.h>
intmax_t strtoimax(const char *nptr, char **endptr, int base);
uintmax_t strtoumax(const char *nptr, char **endptr, int base);
and cast the result to size_t. This is a better approach since it helps detect overflow when arbitrarily large input is given.
The scanf() family functions can't detect integer overflow, which results in undefined behaviour.
Just get the input as unsigned int and cast it to size_t, or just:
size_t length;
scanf("%zu", &length);

How to XOR two byte streams in C?

I've been reading through SO for the past couple of days trying to figure this out, I am stumped. I want to read in two 32 bit byte arrays (from stdin, input will be hex) and xor them, then print the result.
So far I've tried using scanf, fgets, and gets. My thought was to read the large hex numbers into a char buffer and perform the xor in a for loop until I hit an EOL (with fgets) or a null terminator. So far my output is not even close. I tried lots of variations, but I will only post my latest fail below. The challenge I've been trying to complete is: http://cryptopals.com/sets/1/challenges/2/
I am trying it in C because I'm really trying to learn C, but I'm really getting frustrated with none of these attempts working.
#include <stdio.h>
#include <math.h>
int main()
{
char buff1[100];
char buff2[100];
char buff3[100];
int size = sizeof(buff1);
puts("Enter value\n");
fgets(buff1, size, stdin);
puts(buff1);
puts("Enter value\n");
fgets(buff2, size, stdin);
puts(buff2);
for (int i = 0; i != '\n'; i++) {
buff3[i] = buff2[i] ^ buff1[i];
printf("%x", buff3[i]);
}
return 0;
}
When using sizeof() it should be used with types, not data. For instance if you want space for 100 chars, you need to find the sizeof(char) and then multiply by 100 to find out how many bytes you need and that goes into the buffer. A char is usually a byte so expect 100 bytes. fgets() will work but I prefer to use this
int getchar()
Just stop when the the user
enters a newline/terminator character. Since you don't know how many characters will come in from stdin, you
need to dynamically increase the size of your buffer or it will overflow. For the purposes of this question you can just make it a very big array, check to see if its about to overflow and then terminate the program. So to recap the steps.
1.) Create a big array
2.) While loop over getchar() and stop when the output is the terminator, take note of
how many chars you read.
3.) Since both buffers are guaranteed to have equal chars make your
final array equal to that many chars in size.
4.) For loop over getchar() and as the chars come out, xor them with the first array
and put the result into the final array. You should try doing this with 1 array
afterwards to get some more C practice.
Good luck!
EDIT:
fgets() can be used but depending on the implementation it is useful to know how many chars have been read in.
#include <string.h>
#include <ctype.h>
static inline unsigned char hc2uc(char d){
const char *table = "0123456789abcdef";
return strchr(table, tolower(d)) - table;
}
...
for(int i=0;buff1[i]!='\n';i++){
buff3[i]=hc2uc(buff2[i])^hc2uc(buff1[i]);
printf("%x",buff3[i]);
}

Create char array of integer using digits as size

I am trying to create a char array in C, to fill it with the digits of an int, but the int can be of any number of digits.
I'm using a created function called getDigits(int num), that returns a number of digits the int has.
char buffer[getDigits(number)] = "";
snprintf(buffer, sizeof(buffer),"%d",number);
but when I compile using gcc, it returns:
error: variable-sized object may not be initialized
I've tried everything. When I declare it as char fileSizeStr[5] = "";, it works. I can see the problem is rising when I try to declare the buffer size dynamically, but I would really like to know if is a way of achieving this.
The problem is exactly as your compiler is telling you; you're not allowed to initialise VLAs. Zack gave an obvious solution in the comments: Remove the initialisation. You'll find working examples in this answer, some of which do permit an initialisation, and others which don't. You'll find more information about that in comments. The following examples are ordered from most sensible (IMHO) to least sensible (which involve using malloc) for allocating storage for decimal digit sequences representing numbers.
I suggest using the same trick to determine how many bytes are necessary to store an int value as decimal digits as you'd use for octal: Divide the total number of bits in an int by 3 and add for any sign and NUL termination. digit_count could be written as a preprocessor macro like so:
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#define digit_count(num) (1 /* sign */ \
+ sizeof (num) * CHAR_BIT / 3 /* digits */ \
+ (sizeof (num) * CHAR_BIT % 3 > 0)/* remaining digit */ \
+ 1) /* NUL terminator */
int main(void) {
short short_number = -32767;
int int_number = 32767;
char short_buffer[digit_count(short_number)] = { 0 }; /* initialisation permitted here */
char int_buffer[digit_count(int_number)];
sprintf(short_buffer, "%d", short_number);
sprintf(int_buffer, "%d", int_number);
}
As you can see, one powerful benefit here is that digit_count can be used for any type of integer without modification: char, short, int, long, long long, and the corresponding unsigned types.
One minor downside by comparison is that you waste a few bytes of storage, particularly for small values like 1. In many cases, the simplicity of this solution more than makes up for this; The code required to count the decimal digits at runtime will occupy more space in memory than is wasted here.
If you're prepared to throw away the simplicity and generic qualities of the above code, and you really want to count the number of decimal digits, Zacks advice applies: Remove the initialisation. Here's an example:
#include <stddef.h>
#include <stdio.h>
size_t digit_count(int num) {
return snprintf(NULL, 0, "%d", num) + 1;
}
int main(void) {
int number = 32767;
char buffer[digit_count(number)]; /* Erroneous initialisation removed as per Zacks advice */
sprintf(buffer, "%d", number);
}
In response to the malloc recommendations: The least horrible way to solve this problem is to avoid unnecessary code (eg. calls to malloc and later on free). If you don't have to return the object from a function, then don't use malloc! Otherwise, consider storing into a buffer provided by the caller (via arguments) so that the caller can choose which type of storage to use. It's very rare that this isn't an appropriate alternative to using malloc.
If you do decide to use malloc and free for this, however, do it the least horrible way. Avoid typecasts on the return value of malloc and multiplications by sizeof (char) (which is always 1). The following code is an example. Use either of the above methods to calculate the length:
char *buffer = malloc(digit_count(number)); /* Initialisation of malloc bytes not possible */
sprintf(buffer, "%d", number);
... and don't forget to free(buffer); when you're done with it.
try something like:
char* buffer =(char *)malloc(getDigits(number)*sizeof(char));
malloc and calloc are used to dinamic allocation.
For my money, there is one solution which has gone unmentioned but which is actually simpler than any of the above. There is a combined allocating version of sprintf called "asprintf" available on Linux and most BSD variants. It determines the necessary size, mallocs the memory, and returns the filled string into the first argument.
char * a;
asprintf(&a, "%d", 132);
// use a
free(a);
Using a stack allocated array certainly removes the need for the free, but this completely obviates the need to ever separately calculate the size.
below may help
char* buffer;
buffer = (char*)malloc(number * sizeof(char));
You'll need to use malloc to allocate a dynamic amount of memory.
Initializing the way you did is allowed only if the size is known at compile time.

One liner to find length of a variable

I just stumbled upon the idea that since printf returns the no.of characters it has printed to the output stream why not use it to find length of any variable in c?
The code goes something like this,
#include<stdio.h>
int main()
{
char *a="Length";
int i=1000;
printf("Size: %d\n",printf("%d\n",i)-1);
printf("String Size: %d",printf("%s\n",a)-1);
return 1;
}
Am I right? I am not concerned about where it is being used. just wanted to know if my understanding is right.
What do you mean by "length of any variable"? You mean the number of bytes used to store the variable (which better achieved with the sizeof and strlen functions) or the byte length of the string representation of the variables?
For the latter one, you should be careful, since you can use format options to actually modify the results. Consider the following example:
float num = 10.0f;
printf("%.10f", num); // return value should be 13
printf("%f", num); // return value depends on the implementation of printf and the float value supplied
Also you have to consider that there are other representations than the decimal one.
As others have already stated, printf has the side effect that it actually writes to stdout. If you do not want this, you can use snprintf to write to a buffer and not to stdout:
char buffer[256];
int x = 10;
snprintf(buffer, sizeof(buffer), "%d", x); // return value is '2'
"One liner to find length of a variable"
Not possible unless its builtin to your compiler, or you define a wild and hairy macro half a page long with a few enums to state your type...
For strings, (which you cannot use sizeof on...) see: https://stackoverflow.com/a/22128415/3370790

string input and output in C

I have this snippet of the code:
char* receiveInput(){
char *s;
scanf("%s",s);
return s;
}
int main()
{
char *str = receiveInput();
int length = strlen(str);
printf("Your string is %s, length is %d\n", str, length);
return 0;
}
I receive this output:
Your string is hellàÿ", length is 11
my input was:
helloworld!
can somebody explain why, and why this style of the coding is bad, thanks in advance
Several questions have addressed what you've done wrong and how to fix it, but you also said (emphasis mine):
can somebody explain why, and why this style of the coding is bad
I think scanf is a terrible way to read input. It's inconsistent with printf, makes it easy to forget to check for errors, makes it hard to recover from errors, and is incompatable with ordinary (and easier to do correctly) read operations (like fgets and company).
First, note that the "%s" format will read only until it sees whitespace. Why whitespace? Why does "%s" print out an entire string, but reads in strings in such a limited capacity?
If you'd like to read in an entire line, as you may often be wont to do, scanf provides... with "%[^\n]". What? What is that? When did this become Perl?
But the real problem is that neither of those are safe. They both freely overflow with no bounds checking. Want bounds checking? Okay, you got it: "%10s" (and "%10[^\n]" is starting to look even worse). That will only read 9 characters, and add a terminating nul-character automatically. So that's good... for when our array size never needs to change.
What if we want to pass the size of our array as an argument to scanf? printf can do this:
char string[] = "Hello, world!";
printf("%.*s\n", sizeof string, string); // prints whole message;
printf("%.*s\n", 6, string); // prints just "Hello,"
Want to do the same thing with scanf? Here's how:
static char tmp[/*bit twiddling to get the log10 of SIZE_MAX plus a few*/];
// if we did the math right we shouldn't need to use snprintf
snprintf(tmp, sizeof tmp, "%%%us", bufsize);
scanf(tmp, buffer);
That's right - scanf doesn't support the "%.*s" variable precision printf does, so to do dynamic bounds checking with scanf we have to construct our own format string in a temporary buffer. This is all kinds of bad, and even though it's actually safe here it will look like a really bad idea to anyone just dropping in.
Meanwhile, let's look at another world. Let's look at the world of fgets. Here's how we read in a line of data with fgets:
fgets(buffer, bufsize, stdin);
Infinitely less headache, no wasted processor time converting an integer precision into a string that will only be reparsed by the library back into an integer, and all the relevant elements are sitting there on one line for us to see how they work together.
Granted, this may not read an entire line. It will only read an entire line if the line is shorter than bufsize - 1 characters. Here's how we can read an entire line:
char *readline(FILE *file)
{
size_t size = 80; // start off small
size_t curr = 0;
char *buffer = malloc(size);
while(fgets(buffer + curr, size - curr, file))
{
if(strchr(buffer + curr, '\n')) return buffer; // success
curr = size - 1;
size *= 2;
char *tmp = realloc(buffer, size);
if(tmp == NULL) /* handle error */;
buffer = tmp;
}
/* handle error */;
}
The curr variable is an optimization to prevent us from rechecking data we've already read, and is unnecessary (although useful as we read more data). We could even use the return value of strchr to strip off the ending "\n" character if you preferred.
Notice also that size_t size = 80; as a starting place is completely arbitrary. We could use 81, or 79, or 100, or add it as a user-supplied argument to the function. We could even add an int (*inc)(int) argument, and change size *= 2; to size = inc(size);, allowing the user to control how fast the array grows. These can be useful for efficiency, when reallocations get costly and boatloads of lines of data need to be read and processed.
We could write the same with scanf, but think of how many times we'd have to rewrite the format string. We could limit it to a constant increment, instead of the doubling (easily) implemented above, and never have to adjust the format string; we could give in and just store the number, do the math with as above, and use snprintf to convert it to a format string every time we reallocate so that scanf can convert it back to the same number; we could limit our growth and starting position in such a way that we can manually adjust the format string (say, just increment the digits), but this could get hairy after a while and may require recursion (!) to work cleanly.
Furthermore, it's hard to mix reading with scanf with reading with other functions. Why? Say you want to read an integer from a line, then read a string from the next line. You try this:
int i;
char buf[BUSIZE];
scanf("%i", &i);
fgets(buf, BUFSIZE, stdin);
That will read the "2" but then fgets will read an empty line because scanf didn't read the newline! Okay, take two:
...
scanf("%i\n", &i);
...
You think this eats up the newline, and it does - but it also eats up leading whitespace on the next line, because scanf can't tell the difference between newlines and other forms of whitespace. (Also, turns out you're writing a Python parser, and leading whitespace in lines is important.) To make this work, you have to call getchar or something to read in the newline and throw it away it:
...
scanf("%i", &i);
getchar();
...
Isn't that silly? What happens if you use scanf in a function, but don't call getchar because you don't know whether the next read is going to be scanf or something saner (or whether or not the next character is even going to be a newline)? Suddenly the best way to handle the situation seems to be to pick one or the other: do we use scanf exclusively and never have access to fgets-style full-control input, or do we use fgets exclusively and make it harder to perform complex parsing?
Actually, the answer is we don't. We use fgets (or non-scanf functions) exclusively, and when we need scanf-like functionality, we just call sscanf on the strings! We don't need to have scanf mucking up our filestreams unnecessarily! We can have all the precise control over our input we want and still get all the functionality of scanf formatting. And even if we couldn't, many scanf format options have near-direct corresponding functions in the standard library, like the infinitely more flexible strtol and strtod functions (and friends). Plus, i = strtoumax(str, NULL) for C99 sized integer types is a lot cleaner looking than scanf("%" SCNuMAX, &i);, and a lot safer (we can use that strtoumax line unchanged for smaller types and let the implicit conversion handle the extra bits, but with scanf we have to make a temporary uintmax_t to read into).
The moral of this story: avoid scanf. If you need the formatting it provides, and don't want to (or can't) do it (more efficiently) yourself, use fgets / sscanf.
scanf doesn't allocate memory for you.
You need to allocate memory for the variable passed to scanf.
You could do like this:
char* receiveInput(){
char *s = (char*) malloc( 100 );
scanf("%s",s);
return s;
}
But warning:
the function that calls receiveInput will take the ownership of the returned memory: you'll have to free(str) after you print it in main. (Giving the ownership away in this way is usually not considered a good practice).
An easy fix is getting the allocated memory as a parameter.
if the input string is longer than 99 (in my case) your program will suffer of buffer overflow (which is what it's already happening).
An easy fix is to pass to scanf the length of your buffer:
scanf("%99s",s);
A fixed code could be like this:
// s must be of at least 100 chars!!!
char* receiveInput( char *s ){
scanf("%99s",s);
return s;
}
int main()
{
char str[100];
receiveInput( str );
int length = strlen(str);
printf("Your string is %s, length is %d\n", str, length);
return 0;
}
You have to first allocate memory to your s object in your receiveInput() method. Such as:
s = (char *)calloc(50, sizeof(char));

Resources