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.
Related
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.
I'm currently doing the CS50 course, and I'm stuck on the credit problem. The idea is to make a program to verify cards due to their inbuilt checksum. The first step is to take every second digit and multiply it by 2, then add all the digits of the products together.
My code isn't finished, but I've set it up to print some intermediary steps just so I can see what's going on.
#include <stdio.h>
#include <string.h>
void checksum (char number[20]);
int main (void){
char *card;
printf("Please enter a card number:");
scanf("%s", card);
if (strlen(card) == 13 || strlen(card) == 16 || strlen(card) == 15) {
checksum(card);
}
else{
printf("Not a number. Please try again.\n");
main();
}
}
void checksum (char *number) {
int check = 0;
int digits = 0;
for(int i = 1; i < 17; i += 2){
printf("No%c\n", number[i]);
digits = (number[i] * 2);
printf("D%i\n", digits);
while (digits > 0) {
check += digits % 10;
printf("C%i\n", check);
digits = digits / 10;
}
}
}
I know the first part is far from perfect but it's the checksum function I'm concerned with at the moment. When it takes the second digit(5) everything is fine. But then when it's multiplied by 2 according to the next line, somehow the result is 106(?)
Can someone explain what's going on here?
terminal output
You read in a string, i.e. a sequence of characters, probably in ASCII format. So your input "1500150015001500" is actually a sequence of characters terminated by string terminating character 0x0, e.g. like { '1', '5', '0', .... '\0' }. A single character value like '1', when interpreted as an integral value, is represented by its ASCII code, which is 48 for '0', 49 for '1', ... , and 53 for '5'. Hence, an expression like char c = '5'; int digit = c*2 actually yields 106 for digit. To take character '5' as integral value 5, you could write int digit = (c - '0'), which is the same as if you wrote (53 - 48).
Without modifying your code to much, test what happens:
#include <stdio.h>
#include <string.h>
void checksum (char *number);
int main (void){
char card[30];
printf("Please enter a card number:");
scanf("%s", card);
if (strlen(card) == 13 || strlen(card) == 16 || strlen(card) == 15) {
checksum(card);
}
else{
printf("Not a number. Please try again.\n");
main();
}
}
void checksum (char *number) {
int check = 0;
int digits = 0;
for(int i = 1; i < strlen(number); i += 2){
printf("No%c\n", number[i]);
digits = ((number[i]-'0') * 2);
printf("D%i\n", digits);
while (digits > 0) {
check += digits % 10;
printf("C%i\n", check);
digits = digits / 10;
}
}
}
A couple of things:
char *card; scanf("%s", card); is not going to work. You need to either declare card as an array of fixed size (i.e. char card[20]), or use malloc to allocate memory for the pointer char *card;. If you choose the latter option you also need to use free on the memory when you're done with it.
In your function checksum, you need to convert the characters you read in the string card into numbers. If the character set on your system is ASCII, you can achieve this by subtracting the value 0x30 (i.e. the numeric value of the character '0') from each character in the string before performing arithmetic on it.
char number[20] in a function signature is pointless; see this question for more information. Since the array decays to a pointer to its first element when passed as a function argument, you may as well have char *number in the function signature.
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.
I want to scan in a string that can take at least 200 characters and then I want to convert the string to an int, so that I can print it with e.g. printf("%d", digit).
How can I write a function kinda like this I've written here
(this one does not work!):
int main()
{
char car[200];
int number;
int i,x;
int sum = 0;
printf("Write in number: \n");
scanf("%c", &car);
for (i=0; i<200; i++) {
if (car[i] != '\0') {
x = car[i]-'0';
sum = sum + x;
if (i != 0) {
sum = sum*10;
}
}
}
return 0;
}
first:
scanf("%c", &car);
from man scanf:
c
Matches a sequence of characters whose length is specified by the maximum field width (default 1); the next pointer
must be a pointer to char, and there must be enough
room for all the characters (no terminating null byte is added). The usual skip of leading white space is suppressed. To
skip white space first, use an explicit space
in the format.
So you're reading exactly one character, not a whole string.
Then, you rely on a terminating null byte being added, which isn't happening. Use %199s instead, leaving enough room for the terminating null byte.
Then, considering no int in this world should have enough space for numbers with 199 decimal digits, you should think about your 200 character buffer.
If your goal is not to write such a function for educational purposes, but because you need one:
int number;
scanf("%d", &number);
does exactly that: Read one number from the input, and place it in number.
scanf("%s", car);
You need to read a string %s not a single char %c. Also char array will decay to a pointer when passed as an argument, so you shouldn't use &char.
Here is the solution,Start from the end of the string because units place is from right to left then increment the units place to ten's place then 100 and so on.
#include<stdio.h>
#include<string.h>
int main()
{
char input[9];
int digit,number=0,i=1;
printf("Enter Number:\n");
scanf("%s",input);
digit=strlen(input)-1;
while(digit>=0)
{
number=number + i*(input[digit]-'0');
digit=digit-1;
i=i*10;
}
printf("%d",number);
return 0;
}
Close. Suggested changes below.
Use char car[200+1] to "take at least 200 characters".
Use "%200s" rather than "%c" to read a string rather than a char and to limit its input.
//int main()
int main(void) {
// char car[200];
char car[200+1];
int number;
int i,x;
int sum = 0;
printf("Write in number: \n");
// scanf("%c", &car);
scanf("%200s", car);
// for (i=0; i<200; i++) {
for (i=0; car[i]; i++) {
// if (car[i] != '\0'){
x = car[i]-'0';
// sum = sum + x;
sum = 10*sum + x;
// if (i != 0) { sum = sum*10; }
}
printf("%d\n", sum)
return 0;
}
Unless input is like "000000000000000000000000000123", 200 digits will certainly overflow sum.
To detect that
x = car[i]-'0';
if (sum >= INT_MAX/10 && (sum > INT_MAX/10 || x > INT_MAX%10)) {
x = INT_MAX;
// maybe set an error flag
break;
}
sum = 10*sum + x;
An int has an maximum value of INT_MAX from #include < limits.h>. It is at least 32767. Some platforms use 16-bit, 32-bit or 64-bit int Other ranges are possible. Let us assume a worst case of 128-bit. That would need about 39 decimal digits. Leaving room for a sign and terminating null character, suggest
char car[39+1+1];
I'm looking to read in a number from the keyboard and then I have to manipulate each digit individually (it's an Octal to Decimal converter).
Is there something similar to the charAt() method from Java that can be used to work with s particular digit?
I currently have the below code (incomplete) but when compiling, it returns "error: subscripted value is neither array nor pointer"
#include <stdio.h>
#include <math.h>
#include <string.h>
int main()
{
printf("Please enter an octal number ending with #");
char nextNum = getchar();
char number;
int counterUp = 0; //Records how many digits are entered
int counterDown = 1; //Records progress during conversion
int decimalNumber = 0;
while(nextNum != '#') //reads in the whole number, putting the characters together to form one Octal number.
{
number = (number + nextNum);
counterUp++;
nextNum = getchar();
}
//Begin converson from Octal to Decimal
while(counterUp >= 0)
{
int added = (number[counterUp] * (pow(8, counterDown)));
decimalNumber = (decimalNumber + added);
counterDown++;
}
}
I'm not looking to be told how to go from octal to decimal, just how to work with one digit at a time.
Use fgets() instead of a single char:
char number[25]; // max of 25 characters in string
fgets(number, 24, stdin); // read a line from 'stdin', with a max of 24 characters
number[24] = '\0'; // append the NUL character, so that we don't run into problems if we decide to print the string
Now you can subscript number at will, e.g. number[10] = 'A'.
I think you're used to Java way where you can write something like:
String number = "";
number += "3";
number += "4";
Strings in C do not work like that. This code doesn't do what you think it does:
char number = 0; // 'number' is just a one-byte number
number += '3'; // number now equals 51 (ASCII 3)
number += '4'; // number now equals 103 (meaningless)
Maybe something like this will work for you:
char number[20];
int i = 0;
number[i++] = '3';
number[i++] = '4';
Or, you could simply use scanf to read a number in from the keyboard.
I recommend that you find a good book about C and read about strings first, then scanf second.
I think you need to step back and look at your algorithm more closely.
What does char number store? What do you expect this loop to do:
while(nextNum != '#') //reads in the whole number, putting the characters together to form one Octal number.
{
number = (number + nextNum);
counterUp++;
nextNum = getchar();
}
In particular, what does number = (number + nextNum); mean?
You need to define number as an array of chars.
e.g.
char number[16];
Then change your reading loop to append to the array.
while(nextNum != '#')
{
number[counterUp] = nextNum;
counterUp++;
nextNum = getchar();
}