Convert ASCII string to int/float/long - c

I have this code to convert an ASCII string to and int, float, or double. However, it prints "42" for all of them. Where did I go wrong? The syntax looks correct, no warnings.
#include <stdlib.h>
int main(void)
{
char *buf1 = "42";
char buf2[] = "69.00";
int i;
double d;
long l;
i = atoi(buf1);
l = atol(buf1);
d = atof(buf2);
printf("%d\t%d\t%d\n", i, l, d);
return 0;
}

First, you should avoid use of the ato* functions (ie: atoi, atof, etc), because there are cases where the conversion failed, and it just returns zero, so you have no way to know if the input was really a string representing zero, or if it was due to a processing error. If you modify the example below, for example, and change buf2 to "z16", you will get a warning you can handle. atoi would not let you know about that error.
Second, your format specifiers are incorrect in your printf call. Your compiler should have generated warnings about this.
Please refer to the example below for a working version that includes conversion error handling. Not that the explicit casting of strtol to (int) in my example does allow for a potential integer overflow. Try making buf1 a large number, and see what happens.
Good luck!
Code Listing
#include <stdio.h> /* printf */
#include <stdlib.h> /* strtox */
#include <errno.h> /* error numbers */
#define BASE (10) /* use decimal */
int main(void) {
char* errCheck;
char *buf1 = "42";
char *buf2 = "16";
char buf3[] = "69.00";
int i;
double d;
long l;
/* Handle conversions and handle errors */
i = (int)strtol(buf1, &errCheck, BASE);
if(errCheck == buf1) {
printf("Conversion error:%s\n",buf1);
return EIO;
}
l = strtol(buf2, &errCheck, BASE);
if(errCheck == buf2) {
printf("Conversion error:%s\n",buf2);
return EIO;
}
d = strtod(buf3, &errCheck);
if(errCheck == buf3) {
printf("Conversion error:%s\n",buf3);
return EIO;
}
printf("%d\t%ld\t%lf\n", i, l, d);
return 0;
}

Change
printf("%d\t%d\t%d\n", i, l, d);
to
printf("%d\t%ld\t%f\n", i, l, d);

Please don't use ato* functions as ato* functions has been deprecated by strto* and should not be used in new code.
The problem with ato* is, if the converted value is out of range it causes undefined behavior.
For more information check here.

Related

What is wrong with this code? It is showing the output correctly but ending with exit status 56. what does it mean?

#include<stdio.h>
#include<ctype.h>
#include <stdlib.h>
int main()
{
char n;
int a;
scanf("%s",&n);
if(isdigit(n))
{
a=atoi(&n);
if(a%2==0)
{
printf("EVEN");
}
else
{
printf("ODD");
}
}
else
printf("not a number");
}
it is showing an exit status 56 error along with the output. The question is to print given input is even or odd or it's not a number using nested if loop
You never return a value from main, so you invoke undefined behaviour and end up with an arbitrary return value. You should enable your compiler's warnings as it should warn about this.
In newer versions of C, a return 0; is implied for main. Your compiler does not appear to support this version of C.
As an aside, note that your program suffers from a buffer overflow. You allocate but a single character for the string to read in, which is too small for any useful input since the string-terminating NUL requires one character.
You need to use a large buffer. Even then, you'd need to add some protection against reading more than the buffer can handle.
Your int main() function is not explicitly returning any value, you have to return a value with the desired exit code at the end of your main function (or wherever you'd like to if you want to exit due to an error), you need to:
int main( void )
{
// your code here...
return EXIT_SUCCESS; // EXIT_SUCCESS => 0 (contained in stdlib.h)
}
you can also use these exit code macros to exit your program due to an error
int main( void )
{
int *ptr = calloc( 10, sizeof( *ptr ) );
if( ptr == NULL )
{
puts("Couldn't allocate memory");
exit( EXIT_FAILURE ); // or return EXIT_FAILURE; since you are in main function
}
return EXIT_SUCCESS;
}
and btw, your using a char variable to read a string, you should use %c in scanf since you are reading a single character
scanf("%c", &n);
You have several errors. Among other things, your code cannot give a 100% accurate result due to incorrect use of the isdigit() and atoi () functions. The isdigit() function works with a character, and the atoi() function works with a string. Depending on your conditions, there are several types of implementation.
According to the rules of the C language, the atoi( ) function returns a number-the result of converting a string if there is a number at the beginning of the string. If there is a non-digit character at the beginning of the string, the function returns zero. If the number in the string exceeds the maximum or minimum size of an int number, the function returns the maximum or minimum allowed number for the int type, respectively. The returned value depends on the hardware platform on which the program is running.
It differs from the atol () function by the type of the returned number and, as a result, the maximum long string to be converted. For atoi() , the returned number is of the int type, and, accordingly, the bit depth is 16 or 32 bits, depending on the hardware platform on which the program is running. For atol() , the returned number is of the long int type, which is always 32-bit, regardless of the processor architecture.
In accordance with this, I propose the following implementation of your task:
#include<ctype.h>
#include<stdlib.h>
#include<stdio.h>
int main(void)
{
char n[10];
int a;
scanf("%9s",n);
if((a=atoi(n))!=0)
{
if(a%2==0)
{
printf("EVEN");
}
else
{
printf("ODD");
}
}
else
printf("not a number");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int containsOnlyDigits(char s[100], int len)
{
int i, flag;
char ch;
flag = 1;
for (i = 0; i < len; i++)
{
if (s[i] >= '0' && s[i] <= '9')
continue;
flag = 0;
}
return flag;
}
int main()
{
char s[100];
int len, n;
scanf("%s", &s);
len = strlen(s);
if (containsOnlyDigits(s, len))
{
n = atoi(s);
if (n % 2 == 0)
printf("Even");
else
printf("Odd");
}
else
printf("Not a number");
return 0;

Passing argument 1 of 'strcmp' makes pointer from integer without a cast. What is a cast?

I am new to coding in the C language. I am trying to make a program that detects when the RobloxPlayerBeta.exe is being run, but upon compiling it says that "passing argument 1 of 'strcmp' makes pointer from integer without a cast".
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int logout();
char retrieve();
int main(){
char value;
while(1){
system("cmd.exe /C tasklist > Tasks.txt");
value = retrieve();
printf("%d\n",value);
int thing;
thing = strcmp(value,"1");
printf("%d",thing);
if (thing == 0){
int x = logout();
}
sleep(10);
}
return 0;
}
int logout(){
system("c:\\windows\\system32\\shutdown /l");
return 0;
}
char retrieve(){
system("cmd.exe /C start C:\\Users\\chall\\Documents\\Ccode\\Logout\\dist\\FindTask\\FindTask.exe");
FILE *f;
f = fopen("Tasks.txt","r");
int number = fgetc(f);
return number;
}
FindTask.exe is an exe made with the following python code:
with open(r"C:\Users\chall\Documents\Ccode\Logout\Tasks.txt","r") as db:
dataset = db.readlines()
for data in dataset:
if(data[:20].strip().lower() == "robloxplayerbeta.exe"):
with open("Tasks.txt","w") as f:
f.write("1")
I would like to know what a cast is and why I need one.
Cast is to tell the system convert data of one type to another type.
Example:
#include <stdio.h>
int main(void) {
int a = 10;
double b = (double)a; /* cast is used here */
printf("%f\n", b);
return 0;
}
In this case you don't need cast. strcmp() is for compareing strings. You should use operators to deal with numbers to compare single character.
Wrong:
thing = strcmp(value,"1");
Correct:
thing = value - '1';

How to convert string to int64_t?

How to convert program parameter from argv to int64_t? atoi() is suitable only for 32 bit integers.
There are a few ways to do it:
strtoll(str, NULL, 10);
This is POSIX C99 compliant.
you can also use strtoimax; which has the following prototype:
strtoimax(const char *str, char **endptr, int base);
This is nice because it will always work with the local intmax_t ... This is C99 and you need to include <inttypes.h>
A C99 conforming attempt.
[edit] employed #R. correction
// Note: Typical values of SCNd64 include "lld" and "ld".
#include <inttypes.h>
#include <stdio.h>
int64_t S64(const char *s) {
int64_t i;
char c ;
int scanned = sscanf(s, "%" SCNd64 "%c", &i, &c);
if (scanned == 1) return i;
if (scanned > 1) {
// TBD about extra data found
return i;
}
// TBD failed to scan;
return 0;
}
int main(int argc, char *argv[]) {
if (argc > 1) {
int64_t i = S64(argv[1]);
printf("%" SCNd64 "\n", i);
}
return 0;
}
Users coming from a web search should also consider std::stoll.
It doesn't strictly answer this original question efficiently for a const char* but many users will have a std::string anyways. If you don't care about efficiency you should get an implicit conversion (based on the user-defined conversion using the single-argument std::string constructor) to std::string even if you have a const char*.
It's simpler than std::strtoll which will always require 3 arguments.
It should throw if the input is not a number, but see these comments.
strtoll converts it to a long long which is usually a 64-bit int.
Doing this 100% portably is a little bit tricky. long long is required to be at least 64 bits, but need not necessarily be twos complement, so it might not be able to represent -0x7fffffffffffffff-1, and thus using strtoll could have a broken corner case. The same issue applies to strtoimax. What you could do instead is consume leading space (if you want to allow leading space) and check for the sign first, then use strtoull or strtoumax, either of which is required to support values up to the full positive range of int64_t. You can then apply the sign:
unsigned long long x = strtoull(s, 0, 0);
if (x > INT64_MAX || ...) goto error;
int64_t y = negative ? -(x-1)-1 : x;
This logic is written to avoid all overflow cases.
How to convert string to int64_t?
The simplest
#include <stdlib.h>
int64_t value = atoll(some_string); // Lacks error checking. UB on overflow.
Better
long long v = strtoll(s, NULL, 0); // No reported errors, well defined on overflow.
Robust: Create a helper function to detect all problems.
#include <stdbool.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
// Return error flag
bool my_strtoi64(int64_t *value, const char *s) {
// Maybe add a s==NULL, value==NULL checks.
char *endptr;
errno = 0;
long long v = strtoll(s, &endptr, 0);
// Optional code for future growth of `long long`
#if LLONG_MIN < INT64_MIN || LLONG_MAX > INT64_MAX
if (v < INT64_MIN) {
v = INT64_MIN;
errno = ERANGE;
} else if (v > INT64_MAX) {
v = INT64_MAX;
errno = ERANGE;
#endif
*value = (int64_t) v;
if (s == endptr) { // No conversion, v is 0
return true;
}
if (errno == ERANGE) { // Out of range
return true;
}
if (errno) { // Additional implementations specific errors
return true;
}
while (isspace(*(unsigned char* )endptr)) { // skip trailing white-space
endptr++;
}
if (*endptr) { // Non-numeric trailing text
return true;
}
return false; // no error
}
This worked for me with a different int64 type, and I like the clean C++ style:
std::istringstream iss(argv[i]);
int64_t i64;
iss >> i64;
You may get an compile error: operartor<<... is not defined.
And I don't know what happens, if argv[i] contains "HALLO".

how can i write a function that returns a string in c?

When I try calling my function using printf(" %s",course_comment(1.0) );, the program crashes. This is my function:
char *course_comment(float b)
{
if(b < 2.0)
return("Retake");
}
Why does it crash? How can I fix it?
If your strings are constants and there is no intention to modify the result, working with string literals is the best choice, e.g.:
#include <stdio.h>
static const char RETAKE_STR[] = "Retake";
static const char DONT_RETAKE_STR[] = "Don't retake";
const char *
course_comment (float b)
{
return b < 2.0 ? RETAKE_STR : DONT_RETAKE_STR;
}
int main()
{
printf ("%s or... %s?\n",
course_comment (1.0),
course_comment (3.0));
return 0;
}
Otherwise, you can use strdup to clone the string (and don't forget to free it):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *
course_comment (float b)
{
char result[256];
if (b < 2.0)
{
snprintf (result, sizeof (result), "Retake %f", b);
}
else
{
snprintf (result, sizeof (result), "Do not retake %f", b);
}
return strdup (result);
}
int main()
{
char *comment;
comment = course_comment (1.0);
printf ("Result: %s\n", comment);
free (comment); // Don't forget to free the memory!
comment = course_comment (3.0);
printf ("Result: %s\n", comment);
free (comment); // Don't forget to free the memory!
return 0;
}
Depending on the order / structure of your program when 'course_comment' is first called - it maybe be undeclared & C will default its return type to an 'int'. Check for compiler warnings when you err.. compile.
Also make sure you understand about function prototypes, when & where they should be used (everywhere basically). I think the 'f' missing on the 1.0 means the argument will be auto cast to an int.
This works - not that I would ever do this:
#include <stdio.h>
const char *course_comment(float b); // <- fn prototype
int main(int argc, char *argv[]) {
printf(" %s",course_comment(1.0f));
}
const char *course_comment(float b)
{
if(b < 2.0)
return("Retake");
}
You should probably return a literal as const char * as they cannot be modified.
what does your function return if b is not less than 2.0?
what do you think would happen if you tried to use the return value?
Is your exact code what is crashing?
see this answer
As other said add an else with some return value ... And tell us exactly what the error is, please !
my2c
because your getting a NULL-pointer since 1.0 doesn't return anything.
Not your function crashes, printf crashes with:
printf(" %s", NULL);
Rule Of Thumb:
always have a defined return
gcc -Wall shows you all warnings
Return a pointer like that isn't particularly pretty. The least evil thing you can do is something like this:
main.c
#include "some_other_file.h"
int main()
{
printf(" %s", course_comment(1.0f) );
return 0;
}
some_other_file.h
#ifndef YADA_YADA_H
#define YADA_YADA_H
const char* course_comment(float b);
#endif
some_other_file.c
static const char COMMENT_RETAKE [] = "Retake";
const char* course_comment(float b)
{
const char* result;
if(b < 2.0f)
{
result = COMMENT_RETAKE;
}
else
{
result = ""; /* empty string */
}
return result;
}
Please note that you should use 1.0f notation when dealing with floats, and 1.0 notation when dealing with doubles. Otherwise the compiler will do silent promotions of your variables to double, and the code will turn slower.
If you want to return a string literal like return "blah", return type should be const char*.

The showbits() function

While reading a book called "Let us C" I read that a function showbit() exists which can show you the bits of the number. There wasn't any special header file mentioned for it. Searched for it on the internet and didn't found anything useful. Is there such a function? I want this to print the binary of decimal numbers. Else please give me a replacement function. Thanks
All integers are actually in binary in your computer. Its just that it is turned into a string that is the decimal representation of that value when you try to print it using printf and "%d". If you want to know what it looks like in some other base (e.g. base 2 or binary), you either have to provide the proper printf format string if it exists (e.g. "%x" for hex) or just build that string yourself and print it out.
Here is some code that can build the string representation of an integer in any base in [2,36].
#include <stdio.h>
#include <string.h>
char digits[]="01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
void reverse(char* start, char* end)
{
for(end--;start<end;start++,end--)
{
char t=*start;
*start=*end;
*end=t;
}
}
int base_change(int n, int base,char* buffer)
{
int pos=0;
if (base>strlen(digits))
return -1;
while(n)
{
buffer[pos]=digits[n%base];
n/=base;
pos++;
}
buffer[pos]='\0';
reverse(buffer,buffer+pos);
return 0;
}
int main()
{
char buffer[32];
int conv=base_change(1024,2,buffer);
if (conv==0) printf("%s\n",buffer);
return 0;
}
You can also try this snippet which uses bit-shifting:
EDIT: (I've made it more portable)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BITS_IN_BYTE 8
#define INTEGRAL_TYPE unsigned int
void showBits(INTEGRAL_TYPE x) {
int i;
static int intSizeInBits = sizeof(INTEGRAL_TYPE) * BITS_IN_BYTE;
static char symbol[2] = {'0','1'};
char * binary = (char*) malloc(intSizeInBits + 1);
memset(binary, 0, intSizeInBits + 1);
for (i=0; i< intSizeInBits; i++) {
binary[intSizeInBits-i-1] = symbol[(x>>i) & 0x01];
}
printf("%s\n", binary);
free(binary);
}
int main() {
showBits(8698513);
return 0;
}
HTH!
This is a very simple solution for printing the bits of an integer
int value = 14;
int n;
for (n=8*sizeof(int)-1;n>=0;n--) {
printf("%d",(value >>n)&1);
}
The book "Let Us C" doesn't define it as a built-in function. The showbits() function is defined in later part of the book as a complete user defined function as I personally went through it. This answer is to anyone who haven't reached that later part of the book and are stuck at the first appearance of the function in the book.
you need to look here
#downvoter It works fine in c also. You just need to reformat your code in c-style.
#include <stdlib.h>
#include <stdio.h>
int main()
{
char buffer[20];
int i = 3445;
_itoa( i, buffer, 2 );
printf("String of integer %d (radix 2): %s",i,buffer);
return 0;
}
*you need to save your file as .c in MSVC++ for _itoa() to work.*
this is the header file for showbits
void showbits(unsigned int x)
{
int i;
for(i=(sizeof(int)*5)-1; i>=0; i--)
(x&(1u<<i))?putchar('1'):putchar('0');
printf("\n");
}
No there is no pre built function and you do not need to include any specific header file.
You will have to provide implementation for function showbits(int).
#include <stdio.h>
void showbits(int);
int main()
{
int j,k;
for(j=0;j<=11;j++)
{
printf("\nBinary value of decimal %d is :",j);
showbits(j);
}
return 0;
}
showbits(int n){
int i,k,andmask;
for(i = 15;i>=0;i--){
andmask = 1<<i;
k = n & andmask;
k==0 ? printf("0"):printf("1");
}
}
If you want to print out the bits of a float, for example you could do something like:
float myFloat = 45.2;
for (int n=0;n<8*sizeof(float);n++) {
printf("%d",(myFloat>>n)&1);
}

Resources