Help on string handling in C - c

In a program to find whether the given number is an Armstrong number, I stored the input no (3 digit) as string as follows.
char input[10];
scanf("%s",&input);
Now I have to calculate cube of each digit by using pow method of math.h as follows.
int a;
a = pow(input[0],3);
By coding like this, I could not get correct result. If I print the value of "a", it shows some irrelevant answer. My doubt is, how to convert from string value to integer value?

You are performing your calculation on the ASCII value of the digit. You'll need to convert it to a numeric value like so:
int digit = input[0] - '0';
int a; a = pow(digit, 3);

There are two problems, both already detailed. The first is that your scanf needs a char*, not a char**. Fix this with what Jeremy said:
scanf("%s", input);
Next, calculate the power correctly, like Adam said:
a = pow(input[0]-'0',3);

You do not need to get the address of the input array using &input. Simply passing input will pass the pointer to your string to scanf(). Your call to scanf() should look like this:
scanf("%s", input);
Another way of doing it, with the address of operator:
scanf("%s", &input[0]);

armstrong numbers are numbers that exhibit the armstron property in any given base, not just base 10.
int isArmstrong(int n, int b)
{
int sum = 0;
int n2 = n;
int nDigits = 0;
while(n2 != 0)
{
nDigits++;
n2 /= b;
}
n2 = n;
for(int i = 0; i < nDigits; i+++)
{
sum += pow(n2 % b, nDigits);
n2 /= b;
}
return sum == n;
}

On the other hand, you may need to replace the power with a more generic one like power = strlen(input)
so the code should look like this.
char input[10];
int power, sum = 0;
scanf("%s", input);
power = strlen(input);
sum += pow(input[0] - '0', power);
/* you need to compare in here */

Doh, I might have spend too much time far of C, because I think most of the answers here miss the final goal... The advice on dropping the & is fine, of course, but there are several other issues with the scanf.
First, it should be OK for throw away code/homework, but it is dangerous: type 11 chars and get a buffer overflow.
Second, IIRC, since you need a number, you should use an int variable and get that. Untested code from a rusty mind:
int inputNumber;
scanf("%d", &inputNumber);
Here you need the & because you no longer have a pointer.
C should do the conversion for you, and you have a safer input.
Other problematic code:
int a = pow(input[0], 3);
You are not making math with the first digit, but with the Ascii value of the first digit! Ie. 49 for 1, 50 for 2...
Since you got a number from my previous correction, divide it by the correct power of 10 to get the digit.
If you prefer to go the string route, use input[0] - '0' at least.

Freehand coding, building on #PhiLho's idea to use an actual integer input:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int a, sum, i;
printf("Enter an Armstrong number, an integer in the range 100..999:\n");
if(scanf("%d", &a) != 1)
return EXIT_FAILURE;
if(a < 100 || a > 999)
return EXIT_FAILURE;
/* Now extract digits, and compute sum of cubes. */
for(sum = i = 0; i < 3; i++)
{
sum += pow(a % 10, 3);
a /= 10;
}
printf("sum is: %d\n", sum);
return EXIT_SUCCESS;
}

Related

How do I make the numbers in this C program print in the correct order and not in reverse?

I am new to C so I am having a little difficulty!
I want to take an integer input from the user and add 7 to each of the digit in the input. All of that works, but the digits are printing in the reverse order.
How do i make the digits print in the correct order? I checked other similar questions on Stack overflow but it does not seem to work. Thanks in advance!
int main(void)
{
int numToEncrypt;
printf("Please input a 4-digit number you wish to encrypt: ");
scanf("%d", &numToEncrypt);
while (numToEncrypt > 0)
{
int digit = numToEncrypt % 10;
// do something with digit
digit = (digit + 7)%10;
numToEncrypt /= 10;
printf("number is: %d \n",digit);
}
}
)
Converting the string input to an integer and back is pointless. Just work with the data as a string. eg:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void)
{
int c;
if( getenv("V") ) {
printf("Please input the number you wish to encrypt: ");
fflush(stdout);
}
while( (c = getchar()) != EOF ) {
if( isspace(c) ) {
fflush(stdout);
} else if( isdigit(c) ) {
c = '0' + (c - '0' + 7) % 10;
} else {
fprintf(stderr, "Invalid input: %c", c);
return EXIT_FAILURE;
}
putchar(c);
}
}
Note that a huge advantage of doing this is that it is easy to work with ten million digit integers. You will not be able to do that using scanf to convert the string into an integer.
One way is using a variable to specify which digit to process.
#include <stdio.h>
int main(void)
{
int numToEncrypt;
int delta = 1000; // for 4-digit number
printf("Please input a 4-digit number you wish to encrypt: ");
scanf("%d", &numToEncrypt);
while (delta > 0)
{
int digit = (numToEncrypt / delta) % 10;
// do something with digit
digit = (digit + 7)%10;
delta /= 10;
printf("number is: %d \n",digit);
}
}
As this is homework, you could use recursion:
#include <stdio.h>
void print_recursive(int num)
{
// print leading digits
if (num>9)
{
print_recursive(num/10);
}
// print last digits
printf("number is: %d\n", (num+7)%10);
}
int main(void)
{
int number;
printf("Please input a 4-digit number you wish to encrypt: ");
scanf(" %d", &number); // note: You should check the return value!
print_recursive(number);
}
It is not limited to 4 digits.
For a simple program like this, one usually does not bother with a lot of design. However, it is also beneficial to practice software design on simple problems like this, since the knowledge extends to more complicated programs. This is an application of divide and conquer (as a problem solving strategy, not the computer algorithm). The idea being that smaller problems are simpler than larger ones.
In this case, you consider encapsulating the work of "encrypting" to a function, and have the function return the encrypted value. We'll just implement a stub for now, and fill it in later.
int encryptBy7(int input) {
int output = 0;
return output;
}
In addition, we can encapsulate the work of "printing" to a function. And, this is your actual question, if we think about it critically.
void printDigitByDigit(int num, const char *msg) {
printf("stub\n");
}
So your main program would look like:
int main(void) {
int numToEncrypt;
int numEncrypted;
printf("Please input a 4-digit number you wish to encrypt: ");
scanf("%d", &numToEncrypt);
numEncrypted = encryptBy7(numToEncrypt);
printDigitByDigit(numEncrypted, "number is");
return 0;
}
So, your algorithm to encrypt seems to work, so let's just code that up in a way that it stores it as a number.
int encryptBy7(int input) {
int output = 0;
int pow10 = 1;
/* Original program didn't deal with 0 */
if (input == 0) return 0;
while (input > 0) {
int digit = input % 10;
// do something with digit
digit = (digit + 7)%10;
input /= 10;
// build output
output += digit * pow10;
pow10 *= 10;
}
return output;
}
So, now we get to the meat of your question, which is about how to print out the digits starting with the most significant digit. If we see how we built up the output in the previous function, we can reverse the same process of looking at the powers of 10 to find the most significant digit, and then work backwards from there.
void printDigitByDigit(int input, const char *msg) {
int pow10 = 1;
int x = input;
// Find the position of the most significant digit
while (x > 10) {
pow10 *= 10;
x /= 10;
}
// Divide by the input appropriate power of 10 to
// find and print the corresponding digit
while (pow10 > 0) {
int digit = (input / pow10) % 10;
printf("%s: %d\n", msg, digit);
pow10 /= 10;
}
}
Of course, you are free to choose to try to do this as a single program inside of main as you had originally attempted, and the result would probably be a shorter program. I'll leave that as an exercise. However, I would argue that breaking up the program into tasks will provide you more benefit in the long run, and itself is a problem solving tool. Each function becomes easier to think about, and thus an easier problem to solve.

Convert String to Integer without library function in C [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have to write a program that converts an user input (which is a string) to an Integer. In the same time it should check, if the user input really is a number.
And also everything in one method.
and NO LIBRARY FUNCTIONS allowed.
I can't figure any idea how to do it. All I got for the beginning is just this pathetic structure
#include <stdio.h>
void main()
{
char input[100];
int i;
int sum = 0;
printf("Type a String which will be converted to an Integer: ");
scanf("%c, &input");
for (i = 0; i < 100; i++)
{
}
}
I appreciate any help, thanks
The conversion is the easy part...
But if you must not use library functions,
there is only one way to take a string, and that is argv;
there is only one way to give an integer, and that is the exit code of the program.
So, without much ado:
int main( int argc, char * argv[] )
{
int rc = 0;
if ( argc == 2 ) // one, and only one parameter given
{
unsigned i = 0;
// C guarantees that '0'-'9' have consecutive values
while ( argv[1][i] >= '0' && argv[1][i] <= '9' )
{
rc *= 10;
rc += argv[1][i] - '0';
++i;
}
}
return rc;
}
I did not implement checking for '+' or '-', and did not come up with a way to signal "input is not a number". I also just stop parsing at the first non-digit. All this could probably be improved upon, but this should give you an idea of how to work around the "no library functions" restriction.
(Since this sounds like a homework, you should have to write some code of your own. I already gave you three big spoons of helping regarding argv, the '0'-'9', and the conversion itself.)
Call as:
<program name> <value>
(E.g. ./myprogram 28)
Check return code with (for Linux shell):
echo $?
On Windows it's something about echo %ERRORLEVEL% or somesuch... perhaps a helpful Windows user will drop a comment about this.
Source for the "'0'-'9' consecutive" claim: ISO/IEC 9899:1999 5.2.1 Character sets, paragraph 3:
In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous.
I'm sure this is preserved in C11, but I only have the older C99 paper available.
Take hightes digit and add it to number, multiply the number by 10 and add the next digit. And so on:
#include <stdio.h> // scanf, printf
void main()
{
char input[100];
printf("Type a String which will be converted to an Integer: ");
scanf("%s", input);
int number = 0;
int neg = input[0] == '-';
int i = neg ? 1 : 0;
while ( input[i] >= '0' && input[i] <= '9' )
{
number *= 10; // multiply number by 10
number += input[i] - '0'; // convet ASCII '0'..'9' to digit 0..9 and add it to number
i ++; // step one digit forward
}
if ( neg )
number *= -1;
printf( "string %s -> number %d", input, number );
}
input[i] - '0' works, because ASCII characters '0'..'9' have ascending ASCII codes from 48 to 57.
So basically you want to know how something like the standard library atoi works. In order to do this, you need to consider how strings represent numbers.
Basically, a string (that represents a number) is a list o digits from 0 to 9. The string abcd (where a, b, c, d are placeholders for any digit) represents the number a*10 ^ 3 + b*10^2 + c * 10 + d (considering base 10 here, similar for other bases). So basically you need to decompose the string as shown above and perform the required arhitmetic operations:
// s - the string to convert
int result = 0;
for (int index = 0; index < strlen(s); index++) {
result = result * 10 + s[index] - '0';
}
The operation s[index] - '0' converts the character that represent a digit to its value.
// the function returns true for success , and false for failure
// the result is stored in result parameter
// nb: overflow not handled
int charToInt(char *buff,int *result){
*result=0;
char c;
while(c=*buff++){
if((c < '0') || (c >'9')) // accept only digits;
return 0;
*result *= 10;
*result += c-'0';
}
return 1;
}
Lot of things which are missed. Firstly taking a string in is done by scanf("%s",input); By the way in which you are receiving it, it only stores a character, secondly run the loop till the length of the string recieved. Check the below code.
#include <stdio.h>
#include<string.h>
void main()
{
char input[100];
int i;
int sum = 0;
printf("Type a String which will be converted to an Integer: ");
scanf("%s", input);
for (i = 0; i < strlen(input); i++)
{
if(input[i]>=48 && input[i]<=57)
{
//do something, it is a digit
printf("%d",input[i]-48);
//48 is ascii value of 0
}
}
Try it:
#include <stdio.h>
void main()
{
char input[100];
int i,j;
int val = 0;
printf("Type a String which will be converted to an Integer: ");
scanf("%s",input);
for(j=0; input[j] != '\0'; j++); // find string size
for (i = 0; i < j; i++)
{
val = val * 10 + input[i] - 48;
}
}
If you want your code to be portable to systems that don't use ASCII, you'll have to loop over your char array and compare each individual character in the source against each possible number character, like so:
int digit;
switch(arr[i]) {
case '0':
digit=0; break;
case '1':
digit=1; break;
// etc
default:
// error handling
}
Then, add the digit to your result variable (after multiplying it by 10).
If you can assume ASCII, you can replace the whole switch statement by this:
if(isdigit(arr[i])) {
digit=arr[i] - '0';
} else {
// error handling
}
This works because in the ASCII table, all digits are found in a single range, in ascending order. By subtracting the ordinal value of the zero character, you get the value of that digit. By adding the isdigit() macro, you additionally ensure that only digit characters are converted in this manner.

Counting occurance of a specific number in an integer in C

I'm having some troubles... I'm trying to input a number, followed by an integer of multiple numbers. I am trying to count how many times the first number occurs in the integer.
Now, I made this really easy code to show you what I actually am trying to do. The thing is, this code only compares two integers and tells me if they are the same or not. Mind you, I am very unexperienced in C programming, hence this question...
int main(){
int numberOne;
int numberTwo;
int count = 0;
scanf("%d", &numberOne);
scanf("%d", &numberTwo);
if(numberOne == numberTwo){
count++;
}
printf("Amount of equals found: %d", count);
return 0;
}
Now, if I'd have the following input: '1 1021023234', the output would be: 'Amount of equals found:0'
The output should be (in this case) 'The output would be Amount of equals found:2'
I hope you guys can give me some tips.
If I have understood correctly then you need the following
#include <stdio.h>
int main(void)
{
unsigned int numberOne;
unsigned int numberTwo;
unsigned int x;
unsigned int base;
size_t n;
printf( "Enter first number: " );
scanf( "%u", &numberOne );
printf( "Enter second number: " );
scanf( "%u", &numberTwo );
x = numberOne;
base = 1;
do { base *= 10; } while ( x /= 10 );
n = 0;
do { n += numberOne == numberTwo % base; } while ( numberTwo /= 10 );
printf( "Amount of equals found: %u", n );
return 0;
}
For numbers 12 and 76512612 the output is
Amount of equals found: 2
you can read them as integer but you cannot compare them the way you are doing. to compare them you need to extract each digit from the number and compare.
temp = numbertwo % 10; //this gives the digit in the unit place
if(temp == numberone)
count++;
numbertwo = numbertwo / 10; //this now removes the last digit that has already been compared
keep the above code in a loop until numbertwo becomes zero. and it will work as you wanted
another way to do this would be to read the integer as a String.
char* numbertwo;
char = malloc(20);
fgets(numbertwo, 20, stdin);
and then compare the integer in a for loop
Write the code yourself. Here are the hints:
Since you need only one input,eliminate numbertwo from your program and implement the following:
numberone%10 would give the first digit of the user input. Assign it to a variable one.
If user input(numberone)<10 , print first digit is found 1 time in input and exit the program.
Use a while loop and put numberone>=10 in its condition.check if(numberone%10==one) in the loop if true,increment variable count. Add
numberone/10 after it.
Print your last printf and end the program
You can try it using strings as below..
#include<stdio.h>
#include<string.h>
main()
{
char int1[100];
char int2[100];
int cnt=0;
scanf("%s",int1);
scanf("%s",int2);
char *p;
while(p=strstr(s1,s2)) //searches for the string s2 in s1 and if found, returns the address to the pointer p//
{
cnt++
s1=p+strlen(s2); //now s1 points to the next location from the end of string s2 in s1//
}
printf("Amout of equals found:%d\n",cnt");
}

Binary number output in C

I have an assignment to write a program that converts decimal numbers to binary numbers, in the C programming language.
This is the code I wrote:
#include <stdio.h>
#define MAX_LEN 1000
void translate_dec_bin(char s[]){
unsigned int decNum;
sscanf_s(s, "%d", &decNum);
while (decNum > 0){
printf("%d", decNum % 2);
decNum = decNum / 2;
}
printf("\n");
}
main(){
char s[MAX_LEN];
char c='\0';
int count=0;
printf("enter a nunber\n");
while (c < MAX_LEN && ((c = getchar()) != EOF) && c != '\n'){
s[count] = c;
++count;
}
translate_dec_bin(s);
}
However, when the input is 1, the output I get is 1 instead of 0001. In other words, I want the 0's to appear in my output. How can I do that?
First, read mah's comment: although he suggest hitting a fly with a nuclear missile, he suggest you a right approach.
But in this case, your problem is simple: your loop in translate_dec_bin function finishes, because it has nothing left to do.
Think about for a second: your condition is "while decNum is greater than 0, print 1 or 0", right?
I guess you know by now, that in C if you divide integer, the remainder is ommited, so 1/2=0.
Now look at your code: when you give argument "1", the loop iterates only once, so you get only one character in the output.
If you want more characters, you need more conditions. I leave it to you to come up with them, I'm not THAT reputation-hungry as mah suggested :)
And by the way: there is no way you can fit 1000 digits long number in an unsigned int, and that's what you're trying to do.
Assuming you already have computed your decimal number
the basic idea without using print formating is the following:
char* list[] = {"0000", "000", "00", "0", ""};
char* leading_of(int num) {
int v = 0;
while(num > 0 && v < 4){
num = num /10;
v++;
}
return list[v];
}
printf("%s%d", leading_of(decNum), decNum);
If the number of characters or the padding character is variable you need to drop the list and do something more clever instead.

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