How to convert a string to a complete integer number in C? - c

I have tried in this way:
//Write a program to find out the reverse order of a given integer
#include <stdio.h>
int
main(void){
//Put variables for the further proceed
int number, quotient=1, remainder;
//Declare a character array
char text[]="princeX";
//Show the message to the user
printf("Enter an integer number :");
//Taking input from the user
scanf("%d",&number);
//To find out the integer number in the reverse order
while(quotient!=0){
quotient=number/10;
remainder=number%10;
number=quotient;
text[6] = remainder + '0';
puts(text);
}
//Converts the string to a whole integer
int numberUpdate=atoi(text);
printf("%d",numberUpdate);
}
I want to achieve: The user will give an integer number then my system will give the reverse order of the given integer number. To accomplish this goal I stored an integer into a character array but not entirely.
For the input: 123456
Output shows like from my code:
prince6
prince5
prince4
prince3
prince2
prince1
Bu my expectation was:
6
5
4
3
2
1
After that, I just simply wanted to print those as an integer. But I could not do that. When I am going to transform these characters into an integer but the output shows zero. Which problem I have been made in my program and how can I solve that puzzle?

The problem started with this line text[6] = remainder + '0';
puts(text); You only changed text[6], which contains ‘X’ and then printed then whole text. That explains why you go
Prince6
Prince5
Prince4
Prince3
Prince2
Prince1
If you want to get the correct output, you should make these changes:
Declare another variable i=0 before while loop.
Replace the problematic lines with text[i] = remainder+‘0’; printf(“%c\n”, text[i]); i++;
You do this because you want to replace all elements within the text. Then you should expect the correct output. These line int numberUpdate=atoi(text);
printf("%d",numberUpdate); will work afterward. It didn’t work at first simply because it couldn’t convert a string with letters into numbers. Since your string only contains number now, everything should work fine as expected.
I hope it was helpful for you, I did my best explaining the issue, I hope you can understand by reading it. :)))

Here you have number to string conversion function.
char *reverse(char *str)
{
char *wrk = str, *end;
if(str)
{
end = str + strlen(str) -1;
while(end > str)
{
char tmp = *wrk;
*wrk++ = *end;
*end-- = tmp;
}
}
return str;
}
char digits[] = "01234567890abcdefghijklmnopqrstxyvwz";
char *convert(char *buff, unsigned long long val, int radix)
{
char *tmp = buff;
if(radix > sizeof(digits) - 1 || radix < 2) return NULL;
while(val)
{
*tmp++ = digits[val % radix];
val /= radix;
}
*tmp = 0;
return reverse(buff);
}
int main(void)
{
char str[30];
printf("decimal: %s\n", convert(str, 345676, 10));
printf("binary: %s\n", convert(str, 345676, 2));
printf("octal: %s\n", convert(str, 345676, 8));
printf("hex: %s\n", convert(str, 345676, 16));
printf("Base 5: %s\n", convert(str, 345676, 5));
printf("Base 29: %s\n", convert(str, 345676, 29));
}
https://godbolt.org/z/6Ge6bs

Related

scanf makes first element null in C

I am trying to get 2, length of 8, inputs. With the code I have, my problem is that bit1[0] is null. Where is my problem ?
This is kind of debug I have, to see it null-ifies the first element
PS: Dont mind about the calculations I have at the bottom of the code. I am trying to create a calculator that does binary summation. I still couldn't try my code, it can be meaningless to do it in the way I do. But its not the question I am asking so please avoid giving advice on that one. Thank you.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char bit1[8];
char bit2[8];
int result[8];
int sum;
int dig1;
int dig2;
printf("Enter first binary number without any whitespaces!\t");
scanf("%s", bit1);
printf("Enter second binary number without any whitespaces!\t");
scanf(" %s", bit2);
int handle = 0;
puts(bit1);
puts(bit2);
for(int i = 7; i >= 0; i--){
//printf("%d", bit1[i] - '0');
dig1 = bit1[i] - '0';
dig2 = bit2[i] - '0';
if(dig1 + dig2 + handle < 2){
result[i] = dig1 + dig2 + handle;
handle = 0;
} else {
result[i] = (dig1 + dig2 + handle)%2;
handle = 1;
}
printf("dig1: %d\tdig2: %d\thandle: %d\n", dig1, dig2, handle);
printf("%d is added!\n", result[i]);
}
for(int i = 0; i < 8; i++){
printf("%c", result[i]);
}
printf(" And carry is: %d", handle);
return 0;
}
UPDATED
Working code is:
char bit1[9];
char bit2[9];
int result[8];
int sum;
int dig1;
int dig2;
printf("Enter first binary number without any whitespaces!\t");
scanf("%8s", bit1);
printf("Enter second binary number without any whitespaces!\t");
scanf("%8s", bit2);
Rest are the same
When you want to get a string (that is exactly 8 characters) from user input you should write:
char string[9];
scanf("%8s", string);
The reason you need char string[9] and not char string[8] is because a C-string always ends in the null-character (0 or '\0'). Thus, you need one extra space to store that null-character.
Don't forget to always use %8s. If the user input then exceeds the 8 characters you want, C will automatically cut off the exceeding characters.

Trying to check if a number is a palindrome through the use of strings [duplicate]

This question already has answers here:
How do I check if a number is a palindrome?
(53 answers)
Closed 5 years ago.
I am trying to check if an input number is a palindrome. I am doing it through strings rather than ints. So, I am taking in a string and reversing it into another string. However, when I use the string compare function it does not give me 0, stating that the strings are not the same. Even when I put in for example "1001", both the input and reverse strings displays 1001. I have figured it out with other methods but am trying to understand what is wrong with this one in specific.
#include <stdio.h>
#include <string.h>
int main(void)
{
char input[100];
char reverse[100];
int numLen = 0;
printf("Enter a number\n");
fgets(input, 100, stdin);
printf("The number is: %s\n", input);
numLen = strlen(input) - 1;
printf("Length of string is: %d\n", numLen);
for (int i = 0; i < numLen; i++)
{
reverse[i] = input[numLen - 1 - i];
if (i == numLen - 1)
{
reverse[i + 1] = '\0';
}
}
printf("The reverse number is: %s\n", reverse);
printf("The original number is: %s\n", input);
int result = strcmp(input, reverse);
printf("Result of strcmp gives us: %d\n", result);
if (strcmp(input, reverse) == 0)
{
printf("These numbers are palindromes\n");
}
else
{
printf("These numbers are not palindromes\n");
}
return 0;
}
The problem is you are not handling the strings properly. You should overwrite the '\n' with \0.
...
char input[100];
char reverse[100];
int numLen = 0;
printf("Enter a number\n");
fgets(input, 100, stdin);
printf("The number is: %s\n", input);
input[strcspn(input,"\n")]='\0'; // getting the length of the
// string without `\n`
// and overwriting with `\0`
numLen = strlen(input) ; // now you don't need to put the -1
printf("Length of string is: %d\n", numLen);
for (int i = 0; i < numLen; i++)
{
....
Apart from these two changes everything else remains the same. You were reversing it all right. And then you used strcmp right way. But the extra \n is removed in the code I have shown.
(still) Why it works?
Now to give you a better idea. You formed the reversed string alright. But the original string has \n within itself.
printf("The reverse number is: (%s)\n", reverse);
printf("The original number is: (%s)\n", input);
In the previous program you just do write these two lines. You will understand where you went wrong.
On giving input 1001Enter it gives this output.
The reverse number is: (1001)
The original number is: (1001
)
What is strcspn doing?
I have using strcspn function got the length without \n and overwriting it with \0.
0 1 2 3 4 5 --> indices
1 0 0 1 \n \0 --> strcspn(input,"\n") returns 4.
1 0 0 1 \0 \0 --> input[strcspn(input,"\n")]='\0'
You can do simply like this without the copying and everything.
Without extra memory - in place palindrome checking
bool checkPal(const char *s){
for(int i = 0, j= strlen(s)-1; i< strlen(s) && j>=0 ; i++)
if(s[i] != s[j])
return false;
return true;
}
int main(void)
{
char input[100];
char reverse[100];
printf("Enter a number\n");
if( fgets(input, 100, stdin) )
printf("The number is: %s\n", input);
input[strcspn(input,"\n")]='\0';
int numLen = strlen(input) ;
printf("Length of string is: %d \n", numLen);
printf("These numbers are %spalindromes\n", checkPal(input)?"not ":"");
return 0;
}
A more succinct way to write the checkPal() would be,
bool checkPal(const char *first){
const char *last = first + strlen(first);
while (first < last) {
if (*first++ != *--last) {
return false;
}
}
return true;
}
last points to the \0 character. Subtraction is necessary before we start doing comparison. To get a clear idea of what happens you have to know the precedence and few rules.
The first<last part is obvious. We are comparing till we reach a point where we first > last (For even length strings) or first = last (for odd length strings).
The if is a bit tricky. *first++ there are two operators involved. * (indirection) and ++(post increment).
And precedence of ++ is higher than de-reference *.
So *first++ will be - first is incremented. Then you might think that we are missing one character very first time but that's not the case. Value of a postfix expression is the value before we do first++. So now you have the first character.
Same way *--last will have the same effect except the value of the prefix expression is the value after the operation. So you are considering the last character.
If they matches we continue. first and last already contain the modified value. We repeat the same logic for rest of the characters in the smaller sub-string.
If a mismatch occurs then we return immediately. (Because it's not a palindrome).
Sorry, my bad. Try this:
#include <stdio.h>
#include <string.h>
// A function to check if a string str is palindrome
void isPalindrome(char str[])
{
// Start from leftmost and rightmost corners of str
int l = 0;
int h = strlen(str) - 1;
// Keep comparing characters while they are same
while (h > l)
{
if (str[l++] != str[h--])
{
printf("%s is Not Palindromen", str);
return;
}
}
printf("%s is palindromen", str);
}
// Driver program to test above function
int main()
{
isPalindrome("abba");
isPalindrome("abbccbba");
isPalindrome("geeks");
return 0;
}
Does this one work?
A variant, recursive version that has no more that the string as argument (or a copy of the original string)
int pal(char *s) {
int n = strlen(s);
if (n <= 1) return 1;
if (s[0] != s[n-1]) return 0;
s[n-1] = '\0';
return pal(++s);
}
return 0: not a palindrome, 1: is a palindrome
Note the string is altered, so you can call it this way if it's a problem (or if the string is created in a static area)
char *copy = malloc(strlen(string)+1); // string is original string
strcpy(copy, string);
int ispal = pal( copy );
printf("Is %s a palindrome\n", ispal ? "":"not");

return array to coder.ceval

I need to call a c-function from matlab using y=coder.ceval() and return a string from the function. However the coder.ceval() function only allows me to return a scalar value. String is however an array of char, and thus cannot be returned. The code in matlab function looks like:
function y = abc(param)
y = '';
if strcmp(coder.target,'rtw'),
y=coder.ceval('c-function',param);
end
end
Is there any solution or workaround for it?
Looking forward for some help. Thank you very much!
EDITING
This is a workaround and you should use it at your own risk! ;)
I mean if it is really your last option.
As you do not specify the kind of string I assume for simplicity that it is composed only by uppercase letters (AABBBCC).
Uppercase letters are represented as decimal numbers by 2 digits (A = 65, Z = 90, man ascii).
This method comprises two steps:
1) In your function that you call via coder.ceval you should build a scalar value from the string you want to return. 2) You have to rebuild the string from the scalar value.
The following code illustrates by a simple example how to carry out the two steps. Keep in mind that is only an example and you have to work on it. Let's suppose for example that you need to return the string "ABC" then you can return the scalar "656667" which is composed by the three 2-digits numbers: 65=A, 66=B, 67=C.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int i, len, n;
// First convert a string in a scalar value
char str[] = {'A', 'B', 'C', '\0'};
printf("str = %s\n", str);
len = strlen(str);
for (i = 0; i < len; i++) {
n = str[i] + i*100;
}
printf("n = %d\n", n);
// You return a scalar that is composed by 65,66,67 ---> A,B,C
int y = 656667;
char num[100];
char letter[3];
// convert the number in a string
snprintf(num, 100, "%d", y);
printf("num = %s\n", num);
len = strlen(num);
printf("num len = %d\n", len);
// here we assume that the number of digits id even only ascii letters
if ((len%2) != 0) exit(1);
// Now we have to store the number of two digits as numbers and
// then convert the to char and finally append tehm to a string
int *ni = malloc((len/2)*sizeof(int));
char *string = malloc(len + 1);
// Here I use a lot of intermediate steps to make it clear
char c = 0;
for (i = 0; i < len/2; i+=1) {
snprintf(letter, 3, "%c%c", num[2*i], num[2*i+1]);
ni[i] = atoi(letter);
c = (char)ni[i];
printf("letter %d = %s, x = %d, c = %c\n", i, letter, ni[i], c);
string[i] = c;
printf("string[%d] = %c\n", i, string[i]);
}
// print the final string
string[len] = '\0';
printf("string = %s\n", string);
return 0;
}
Lowercase letters starts at 97 but then become 3 digits, however by using some "special number" of 2 digits one can even decide to read 2 digits at the beginning of the string and 3 digits after the "special number".
Ok, I am not sure that this will help but, at least, I hope you find it interesting.

How to extract numbers from string in c?

Say I have a string like ab234cid*(s349*(20kd and I want to extract all the numbers 234, 349, 20, what should I do ?
You can do it with strtol, like this:
char *str = "ab234cid*(s349*(20kd", *p = str;
while (*p) { // While there are more characters to process...
if ( isdigit(*p) || ( (*p=='-'||*p=='+') && isdigit(*(p+1)) )) {
// Found a number
long val = strtol(p, &p, 10); // Read number
printf("%ld\n", val); // and print it.
} else {
// Otherwise, move on to the next character.
p++;
}
}
Link to ideone.
A possible solution using sscanf() and scan sets:
const char* s = "ab234cid*(s349*(20kd";
int i1, i2, i3;
if (3 == sscanf(s,
"%*[^0123456789]%d%*[^0123456789]%d%*[^0123456789]%d",
&i1,
&i2,
&i3))
{
printf("%d %d %d\n", i1, i2, i3);
}
where %*[^0123456789] means ignore input until a digit is found. See demo at http://ideone.com/2hB4UW .
Or, if the number of numbers is unknown you can use %n specifier to record the last position read in the buffer:
const char* s = "ab234cid*(s349*(20kd";
int total_n = 0;
int n;
int i;
while (1 == sscanf(s + total_n, "%*[^0123456789]%d%n", &i, &n))
{
total_n += n;
printf("%d\n", i);
}
here after a simple solution using sscanf:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char str[256]="ab234cid*(s349*(20kd";
char tmp[256];
int main()
{
int x;
tmp[0]='\0';
while (sscanf(str,"%[^0123456789]%s",tmp,str)>1||sscanf(str,"%d%s",&x,str))
{
if (tmp[0]=='\0')
{
printf("%d\r\n",x);
}
tmp[0]='\0';
}
}
Make a state machine that operates on one basic principle: is the current character a number.
When transitioning from non-digit to digit, you initialize your current_number := number.
when transitioning from digit to digit, you "shift" the new digit in:
current_number := current_number * 10 + number;
when transitioning from digit to non-digit, you output the current_number
when from non-digit to non-digit, you do nothing.
Optimizations are possible.
If the numbers are seprated by whitespace in the string then you can use sscanf(). Since, it's not the case with your example,
you have to do it yourself:
char tmp[256];
for(i=0;str[i];i++)
{
j=0;
while(str[i]>='0' && str[i]<='9')
{
tmp[j]=str[i];
i++;
j++;
}
tmp[j]=0;
printf("%ld", strtol(tmp, &tmp, 10));
// Or store in an integer array
}
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
void main(int argc,char *argv[])
{
char *str ="ab234cid*(s349*(20kd", *ptr = str;
while (*ptr) { // While there are more characters to process...
if ( isdigit(*ptr) ) {
// Found a number
int val = (int)strtol(ptr,&ptr, 10); // Read number
printf("%d\n", val); // and print it.
} else {
// Otherwise, move on to the next character.
ptr++;
}
}
}
Or you can make a simple function like this:
// Provided 'c' is only a numeric character
int parseInt (char c) {
return c - '0';
}

Addition of numbers from string delimited by ' . '

I want to write a C program which will take an IP address from the user like "112.234.456.789" in a string and give formatted output in addition of each block in string, e.g., "04.09.15.24" for the above IP address. Here's what I have so far:
#include<stdio.h>
#include<string.h>
#include<conio.h>
main()
{
char s[15],d[11];
int i=0,c = 0, sum[4] = {0};
d[i]=sum[c]/10;
printf("Enter ip address:");
gets(s);
printf("\n \n %s",s);
i=0;
for(c=0;c<15;c++)
{
if(s[c]!='.'||s[c]!='\0')
sum[i]=(s[c]-48)+sum[i];
else
i++;
}
for(i=0,c=0;c<4;c++,i+=3)
{
d[i]=(sum[c]/10)+48;
d[i+1]=sum[c]%10+48;
d[i+2]='.';
}
printf("\n \n %s",d);
getch();
}
The input should be an IP address like "112.234.546.234", and the output should be the result of adding the digits in each block, "04.09.15.06". The input and output should be in strings.
The problem with your code is that s[c]!='.'||s[c]!='\0' is going to evaluate true for any character in the input -- even '.'. This means i is never incremented, and ot only is every digit is summed to sum[0], but so is '.' - 48.
What you meant was s[c] != '.' && s[c] != '\0'.
I wrote the function you desire here.
#include <stdio.h>
#include <ctype.h>
void convert(const char *in, char *out) {
unsigned int sum = 0;
char ch;
do {
ch = *in++;
if (isdigit(ch)) {
sum += ch - '0';
} else {
*out++ = sum / 10 + '0';
*out++ = sum % 10 + '0';
if (ch == '.') {
*out++ = '.';
sum = 0;
}
}
} while (ch);
}
By the way, each "block" of the IPv4 address is an octet, and what you are doing is replacing each with its digit sum.
I just code you a simple example of how to "discard" unwanted characters.
#include <studio.h>
main ()
{
int add1, add2, add3, add4;
printf("enter an ip in the form xxx.xxx.xxx.xxx: )";
scanf("%d%*c%d%*c%d%*c%d", &add1, &add2, &add3, &add4);
printf("add1 = %d add2 = %d add3 = %d add4 = %d\n\n", add1, add2, add3, add4);
return 0;
}
console output:
enter a ip in the form xxx.xxx.xxx.xxx: 123.321.456.654
add1 = 123 add2 = 321 add3 = 456 add4 = 654
EDIT: you just have to play along with the "add#" variables to do your math thing.
It looks like homework (if this is the case, please tag it as homework), so I am going to give a few pointers:
Use fgets to read the input from the user. Read the input into a string.
Use sscanf to parse the string. Since you know there will be four positive integers, use "%u.%u.%u.%u" as the format string.
For each one of the four integers, compute the sum of the digits (using division by 10 and remainder by 10, as you just did).
Print the formatted output using printf (or snprintf to print to a string). If you want each sum to be formatted as a two-digits integer, with leading 0, use "%02u" as format specifier.
P.S. Be careful with snprintf, it might bite.
Other tips
Focus on one step at a time. Divide and conquer. Write a digit_sum function, taking an integer as argument, which computes the sum of its digits:
unsigned int digit_sum(unsigned int n)
{
unsigned int sum = 0;
while (n > 0) {
sum += n % 10;
n /= 10;
}
return sum;
}
Once your digit_sum function is working well, proceed with the main task.

Resources