I'm trying to calculate the product of 5 consecutive integer, but the result the completely wrong. I think my logic is correct, but why it shows me an unreal number: 344362200
The sequence number is from 1 to 10, code is below (just for testing only):
void problem8()
{
char *input = "123456789";
char c;
int step = 5, i = 0, prod = 0, temp = 1;
for (; i < step; i++)
{
temp *= *(input + i);
printf("%d\n", temp);
}
}
The output is really weird! At the first loop, the result is 42 ## while it should be 1, and 1 only. I checked individual result from *(input + 0) or 1 2 4 etc., it's correct. But the product is wrong.
You need to distinguish between the codes for the digits (48 for '0', 49 for '1', etc), and the numbers 1, 2, etc. You should be getting 49 on the first iteration; indeed, I get:
49
2450
124950
6497400
344362200
If you want the first 5 factorials, you'll need to use temp *= input[i] - '0'; (where input[i] is neater than *(input + i), IMNSHO).
The codes I gave are valid for code sets such as ISO 8859-1, and also UTF-8, and many other related code sets. They're not valid for EBCDIC, though.
The problem is that you are converting a char to an int, and not taking into account the ASCII offsets in the ASCII table. Integers start at hex 0x30 for ASCII.
#include <stdio.h>
#include <string.h>
int multiplyFiveSingleDigitNumbersInAString (const char* input, size_t inputLength);
int main(void) {
int tmp = 0;
const char* buf = "12345"; /* Create null-terminated string */
tmp = multiplyFiveSingleDigitNumbersInAString(buf, strlen(buf));
printf("Result of calculation for string %s is %d\n", buf, tmp);
return 0;
}
int multiplyFiveSingleDigitNumbersInAString (const char* input, size_t inputLength) {
if (inputLength != 5) {
printf("Wrong string length (%d), should be %d\n", (int)inputLength, 5);
return 0;
}
int i;
int multiSum = 1;
for (i=0; i<inputLength; i++) {
multiSum *= (int)input[i] - 0x30;
}
return multiSum;
}
References
ASCII Table, Accessed 2014-04-08, <http://www.asciitable.com/>
IMO, the other answers approach this backwards. Simply don't use chars when you want ints. Just change
char *input = "123456789";
to
int input = { 1, 2, 3, 4, 5 };
and your code will work.
P.S. Here's a solution to the actual problem:
char digits[] = "731...";
int main(void)
{
int max = 0;
for (int len = sizeof digits - 1, i = 0; i < len - 4; i++)
{
int prod = 1;
for (int j = 0; j < 5; j++)
prod *= digits[i + j] - '0';
if (max < prod) max = prod;
}
printf("%d\n", max);
return 0;
}
Related
Hello everyone I'm a beginner in coding and I try to figure out how to output all the digits. Example in the number 158 the number 1,5,8,15,58,158. Sorry for the bad English.
I have tried something but it doesnt work for all numbers plus i believe there must be a better way to code it without all the while loops.
#include <stdio.h>
int main(){
long num = 5025;
int num1=num ,num2= num, num3=num;
while(num1 !=0)
{
int digit = num1 % 10;
num1 = num1/10;
printf("%d\n", digit);
}
while(num2 >10)
{
int digit = num2 % 100;
num2 = num2 / 10;
printf("%.2d\n", digit);
}
while(num3 >100)
{
int digit = num3 % 1000;
num3 = num3 / 10;
printf("%.3d\n", digit);
}
return 0;
}
My take, without strings and a bit less complexity. If the number has a 0 digit, it will print duplicates for the digit to the right.
#include <stdio.h>
int main(void)
{
int digits[64]; // size of array must cover however many digits are in long max
int numDigits = 0;
long num = 15876;
// populate array with each digit
while (num)
{
digits[numDigits++] = num % 10;
num /= 10;
}
// start at the end of the array (since digits are loaded in it backwards)
for (int first=numDigits-1; first>=0; first--)
{
int temp = digits[first];
printf("%d\n", temp); // print the initial condition
for (int last=first-1; last>=0; last--)
{
// continue to build temp by multiplying by 10 and adding the next digit
temp = (temp * 10) + digits[last];
// could easily put the output in a comma-separated list if that's needed
printf("%d\n", temp);
}
}
}
Output
1
15
158
1587
15876
5
58
587
5876
8
87
876
7
76
6
Demo
One could print to a string and then post its various combinations
long num = 158;
char buf[25];
snprintf(buf, sizeof buf, "%ld", num);
for (int first = 0; buf[first]; first++) {
for (int last = first; buf[last]; last++) {
int width = last - first + 1;
printf("%.*s\n", width, buf + first);
}
}
Output
1
15
158
5
58
8
Depending on the value, you may get repeats. OP has not yet defined what to do in that case.
For a math only approach, I'd use recursion, yet I expect that is beyond OP's ken at this time.
Here is function printing it for any unsigned int number without fancy printf formats. It also prints in the order from shortest to longest:
void print(unsigned num)
{
char nums[20];
size_t len;
len = sprintf(nums, "%u", num);
for(size_t seql = 1; seql <= len; seql++)
{
for(size_t ndig = 0; ndig < len - seql + 1; ndig ++)
{
for(size_t dig = 0; dig < seql; dig++)
{
printf("%c", nums[dig + ndig]);
}
printf("%c", seql == len ? '\n' : ',');
}
}
}
int main(void)
{
print(15895678);
}
Or without strings:
char getNthDigit(unsigned num, size_t digit, size_t len)
{
size_t pos = len - digit;
while(--pos) num /= 10;
return num % 10;
}
size_t getNdigits(unsigned num)
{
size_t count = 0;
while(num)
{
count++;
num /= 10;
}
return count;
}
void print(unsigned num)
{
char nums[20];
size_t len;
len = num ? getNdigits(num) : 1;
for(size_t seql = 1; seql <= len; seql++)
{
for(size_t ndig = 0; ndig <= len - seql; ndig ++)
{
for(size_t dig = 0; dig < seql; dig++)
{
printf("%c", '0' + getNthDigit(num,dig + ndig, len));
}
printf("%c", seql == len ? '\n' : ',');
}
}
}
https://godbolt.org/z/Wa8nKns9E
#include <stdio.h>
int main(void) {
int num = -158;
char text[12];
sprintf(text, "%d", abs(num));
for(int w=0; w<strlen(text); ++w)
for(int s=0; s<strlen(text)-w; ++s)
printf("%.*s\n", w+1, text+s);
return 0;
}
From IDEOne
Output
Success #stdin #stdout 0s 5632KB
1
5
8
15
58
158
Problem:
How can print string num? It seems that final statement cannot execute?
Question desciptions:
Notice that the number 123456789 is a 9-digit number consisting exactly the numbers from 1 to 9, with no duplication. Double it we will obtain 246913578, which happens to be another 9-digit number consisting exactly the numbers from 1 to 9, only in a different permutation. Check to see the result if we double it again!
Now you are suppose to check if there are more numbers with this property. That is, double a given number with k digits, you are to tell if the resulting number consists of only a permutation of the digits in the original number.
/* Have Fun with Numbers */
#include <stdio.h>
#include <string.h>
int book[10] = { 0 };
int main(int argc, char* argv[])
{
char num[22];
int temp = 0;
scanf_s("%s", num, 1);
// Length of numbers
int len = strlen(num);
int flag = 0;
for (int i = len - 1; i >= 0; --i) {
// Convert an ASCII value of a digit into an integer
temp = num[i] - '0';
// Add 1 each time read a digit
++book[temp];
temp = temp * 2 + flag;
flag = 0;
if (temp >= 10) {
temp -= 10;
flag = 1;
}
// Convert an integer into an ASCII value of a digit
num[i] = (temp + '0');
// Subtract 1 each time generate a digit
--book[temp];
}
int flag1 = 0;
for (int i = 0; i < 10; ++i) {
if (book[i] != 0) {
flag1 = 1;
}
}
printf("%s", (flag == 1 || flag1 == 1) ? "No\n" : "Yes\n");
if (flag == 1) {
printf("1");
}
printf("%s", num);
return 0;
}
In this like
scanf_s("%s", num, 1);
You are reporting the buffer size as 1 to scanf_s() while the actual size is 22.
Use correct buffer size.
scanf_s("%s", num, 22);
or
scanf_s("%s", num, (unsigned)(sizeof(num) / sizeof(*num)));
I"m trying to store int array as a str and display it but in the reverse order.
Its only while printing the str that i get junk.
What is wrong in my code?
int main() {
int a[] = { 1, 2, 3 }; // Output should be 321 (char)
int size = sizeof(a) / sizeof(int);
char str[size + 1];
int i;
for (size = size - 1; size >= 0; size--) {
sprintf(&str[size], "%d", a[size]);
//printf("%c\n", str[size]);
}
printf("%s\n", str); // I get garbage.
}
I modified your solution with several bug fixes. For starters, you can't assume that your integer array will only hold single digit values.
And that for loop as you have it:
for(size=size-1;size >= 0;size--)
Is very suspicious looking. (the index variable is the thing its based off?)
Simple solution
This is likely what you meant:
for(i = 0; i < size; i++) {
sprintf(&str[i],"%d", a[size-1-i]);
}
str[size] = '\0';
Or this:
str[size] = '\0';
for(i = size-1; i <= 0; i--) {
sprintf(&str[i],"%d", a[size-1-i]);
}
Better solution
I'm not sure what you are expecting to do if an integer within the a array is negative. So the - sign will just get inserted into str inplace.
The solution I have will first count how many chars are needed for each integer in a. Then it will allocate the str buffer with that length (+1 for null char).
Then we make use of the return value from sprintf to figure out where to concatenate onto. We could use strcat, but this is likely faster.
int main() {
int j = 0;
int a[] = { 1,2,3 }; // Output should be 321 (char)
int size = sizeof(a) / sizeof(int);
int length = 1; // +1 for final null char
// Count the size of characters needed for each integer
// Do a dummy sprintf and use its return value to figure out how many chars are needed
for (int i = 0; i < size; i++) {
char tmp[sizeof(int) * 5]; // sizeof(int)*5 is big enough to hold any integer including a negative value
length += sprintf(tmp, "%d", a[i]); // utilize the return value from sprintf and add it to the running length
}
char str[length];
str[0] = '\0'; // initially null terminate our string
// reverse print chars from a into str
for (int i = 0; i < size; i++) { // use i as index variable, not size
j += sprintf(str + j, "%d", a[size - 1 - i]);
}
printf("%s\n", str);
}
Alternative solution, closer to original posts, and clearly not trying to address the general problem (assume values are single digit):
int a[]={1,2,3}; // Output should be 321 (char)
int size = sizeof(a)/sizeof(int);
char str[size+1];
for(int i=0; i<size ; i++) {
str[size-1-i] = ‘0’ + a[i];
}
str[size] = 0;
printf("%s\n", str); // I get garbage.
}
Taking advantage of the assumed input value, converting each int to character representation at the reverse position.
I am self teaching C programming.
I am trying to count number of int present in given string which are separated by space.
exp:
input str = "1 2 11 84384 0 212"
output should be: 1, 2, 11, 84384, 0, 212
total int = 6
When I try. It gives me all the digits as output which make sense since I am not using a right approach here.
I know in python I can use str.split (" ") function which can do my job very quickly.
But I want to try something similar in C. Trying to create my own split method.
#include <stdio.h>
#include <string.h>
void count_get_ints(const char *data) {
int buf[10000];
int cnt = 0, j=0;
for (int i=0; i<strlen(data); i++) {
if (isspace(data[i] == false)
buf[j] = data[i]-'0';
j++;
}
printf("%d", j);
}
// when I check the buffer it includes all the digits of the numbers.
// i.e for my example.
// buf = {1,2,1,1,8,4,3,8,4,0,2,1,2}
// I want buf to be following
// buf = {1,2,11,84384,0,212}
I know this is not a right approach to solve this problem. One way to keep track of prev and dynamically create a memory using number of non space digits encountered.
But I am not sure if that approach helps.
You want to build your number incrementally until you hit a space, then put that into the array. You can do this by multiplying by 10 then adding the next digit each time.
void count_get_ints(const char *data) {
int buf[10000];
int j = 0;
int current_number = 0;
// Move this outside the loop to eliminate recalculating the length each time
int total_length = strlen(data);
for (int i=0; i <= total_length; i++) {
// Go up to 1 character past the length so you
// capture the last number as well
if (i == total_length || isspace(data[i])) {
// Save the number, and reset it
buf[j++] = current_number;
current_number = 0;
}
else {
current_number *= 10;
current_number += data[i] - '0';
}
}
}
I think strtok will provide a cleaner solution, unless you really want to iterate over every char in the string. It has been a while since I did C, so please excuse any errors in the code below, hopefully it will give you the right idea.
#include <stdio.h>
#include <stdlib.h>
int main() {
char str[19] = "1 2 11 84384 0 212";
const char s[2] = " ";
char *token;
int total;
total = 0;
token = strtok(str, s);
while (token != NULL) {
printf("%s\n", token);
total += atoi(token);
token = strtok(NULL, s);
}
printf("%d\n", total);
return 0;
}
You can check the ascii value of each character by doing c-'0'. If it's between [0,9], then it's an integer. By having a state variable, when you're inside an integer by checking if a given character is a number of space, you can keep track of the count by ignoring white space. Plus you don't need a buffer, what happens if data is larger than 10,000, and you write pass the end of the buffer?, undefined behavior will happen. This solution doesn't require a buffer.
Edit, the solution now prints the integers that are in the string
void count_get_ints(const char *data) {
int count = 0;
int state = 0;
int start = 0;
int end = 0;
for(int i = 0; i<strlen(data); i++){
int ascii = data[i]-'0';
if(ascii >= 0 && ascii <= 9){
if(state == 0){
start = i;
}
state = 1;
}else{
//Detected a whitespace
if(state == 1){
count++;
state = 0;
end = i;
//Print the integer from the start to end spot in data
for(int j = start; j<end; j++){
printf("%c",data[j]);
}
printf(" ");
}
}
}
//Check end
if(state == 1){
count++;
for(int j = start; j<strlen(data); j++){
printf("%c",data[j]);
}
printf(" ");
}
printf("Number of integers %d\n",count);
}
I believe the standard way of doing this would be using sscanf using the %n format specifier to keep track of how much of the string is read.
You can start with a large array to read into -
int array[100];
Then you can keep reading integers from the string till you can't read anymore or you are done reading 100.
int total = 0;
int cont = 0;
int ret = 1;
while(ret == 1 && total < 100) {
ret = sscanf(input, "%d%n", &array[total++], &cont);
input += cont;
}
total--;
printf("Total read = %d\n", total);
and array contains all the numbers read.
Here is the DEMO
Example using strtol
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#include <ctype.h>
int count_get_ints(int output[], int output_size, const char *input) {
const char *p = input;
int cnt;
for(cnt = 0; cnt < output_size && *p; ++cnt){
char *endp;
long n;
errno = 0;
n = strtol(p, &endp, 10);
if(errno == 0 && (isspace((unsigned char)*endp) || !*endp) && INT_MIN <= n && n <= INT_MAX){
output[cnt] = n;
while(isspace((unsigned char)*endp))
++endp;//skip spaces
p = endp;//next parse point
} else {
fprintf(stderr, "invalid input '%s' in %s\n", p, __func__);
break;
}
}
return cnt;
}
int main(void) {
const char *input = "1 2 11 84384 0 212";
int data[10000];
int n = sizeof(data)/sizeof(*data);//number of elements of data
n = count_get_ints(data, n, input);
for(int i = 0; i < n; ++i){
if(i)
printf(", ");
printf("%d", data[i]);
}
puts("");
}
Assuming you don't have any non-numbers in your string, you can just count the number of spaces + 1 to find the number of integers in the string like so in this pseudo code:
for(i = 0; i < length of string; i++) {
if (string x[i] == " ") {
Add y to the list of strings
string y = "";
counter++;
}
string y += string x[i]
}
numberOfIntegers = counter + 1;
Also, this reads the data between the white spaces. Keep in mind this is pseudo code, so the syntax is different.
I am having an array of integer say int example[5] = {1,2,3,4,5}. Now I want to convert them into character array using C, not C++. How can I do it?
Depending on what you really want, there are several possible answers to this question:
int example[5] = {1,2,3,4,5};
char output[5];
int i;
Straight copy giving ASCII control characters 1 - 5
for (i = 0 ; i < 5 ; ++i)
{
output[i] = example[i];
}
characters '1' - '5'
for (i = 0 ; i < 5 ; ++i)
{
output[i] = example[i] + '0';
}
strings representing 1 - 5.
char stringBuffer[20]; // Needs to be more than big enough to hold all the digits of an int
char* outputStrings[5];
for (i = 0 ; i < 5 ; ++i)
{
snprintf(stringBuffer, 20, "%d", example[i]);
// check for overrun omitted
outputStrings[i] = strdup(stringBuffer);
}
#include <stdio.h>
int main(void)
{
int i_array[5] = { 65, 66, 67, 68, 69 };
char* c_array[5];
int i = 0;
for (i; i < 5; i++)
{
//c[i] = itoa(array[i]); /* Windows */
/* Linux */
// allocate a big enough char to store an int (which is 4bytes, depending on your platform)
char c[sizeof(int)];
// copy int to char
snprintf(c, sizeof(int), "%d", i_array[i]); //copy those 4bytes
// allocate enough space on char* array to store this result
c_array[i] = malloc(sizeof(c));
strcpy(c_array[i], c); // copy to the array of results
printf("c[%d] = %s\n", i, c_array[i]); //print it
}
// loop again and release memory: free(c_array[i])
return 0;
}
Outputs:
c[0] = 65
c[1] = 66
c[2] = 67
c[3] = 68
c[4] = 69
You can convert a single digit-integer into the corresponding character using this expression:
int intDigit = 3;
char charDigit = '0' + intDigit; /* Sets charDigit to the character '3'. */
Note that this is only valid, of course, for single digits. Extrapolating the above to work against arrays should be straight-forward.
You need to create the array, because sizeof(int) is (almost surely) different from sizeof(char)==1.
Have a loop in which you do char_example[i] = example[i].
If what you want is to convert an integer into a string you could just sum your integer to '0' but only if you're sure that your integer is between 0 and 9, otherwise you'll need to use some more sophisticated like sprintf.
In pure C I would do it like this:
char** makeStrArr(const int* vals, const int nelems)
{
char** strarr = (char**)malloc(sizeof(char*) * nelems);
int i;
char buf[128];
for (i = 0; i < nelems; i++)
{
strarr[i] = (char*)malloc(sprintf(buf, "%d", vals[i]) + 1);
strcpy(strarr[i], buf);
}
return strarr;
}
void freeStrArr(char** strarr, int nelems)
{
int i = 0;
for (i = 0; i < nelems; i++) {
free(strarr[i]);
}
free(strarr);
}
void iarrtostrarrinc()
{
int i_array[] = { 65, 66, 67, 68, 69 };
char** strarr = makeStrArr(i_array, 5);
int i;
for (i = 0; i < 5; i++) {
printf("%s\n", strarr[i]);
}
freeStrArr(strarr, 5);
}