Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have a function called fun(int num, int * array); which takes an int and int array as its arugments. I'm trying to convert int to the array.
When i run the program i don't get the array displayed properly
int fun(int num, int*array) {
int count =0;
while(num>0) {
num/= 10;
count++;
}
array[count];
// for loop works
}
When i print the array in the program i.e. everytime I run the program i get random digits.
What this line is supposed to do ?
array[count];
Since your integer array will change in your fun function, you have to allocate the memory (by using malloc, realloc, ...).
edit : plus, you already change the value hold by "num" when you count how many digit there are in "num".
Make a copy of "num" !
edit 2 : the more i look your function, the more it seem you will have problem using it.
Fisrt, you want to explode your integer into an array of int.
Okay, but integer have range, thus meaning integer have a maximum digit.
From my memories, there are 20 digit in an 64bit integer.
So you can simply use "int array[NB_DIGIT_INT_MAX];" with "#define NB_DIGIT_INT_MAX 21".
So, allocating is not necessary AND add complexity in your code (the caller will have to free after the function call).
Second, your fun function doesn't say how many case will hold your integer.
Let's say num = 12, your array will have "array[0] = 1, array[1] = 2", but how do you know where to stop ?
If num = 2345, how do you know that only the 4 first case in your array is legit ?
There are 2 way : You have an another variable that hold the actual size of the array, or you have a special value in your array that say "it's the end" (like '\0' for char array used as string).
You can use "-1".
Let's give a try, and don't hesitate to ask question if thing are unclear (english is not my motherlanguage)
Your array is not even allocated, this can not work as expected. You are even lucky not to have a segmentation fault. If you want to add an integer to an array making it grow, you need to allocate a larger array, copy the values and add the new one to the new array and delete the previous array, keeping array variable as a pointer to the new array. Moreover, you need to pass the size of the actual array as an argument of fun.
The count variable can be global, Initialize it outside all functions like this
short count;
The whole program could be modified like below
#include<stdio.h>
#include<stdlib.h>
short count;
void fun(int num, int **ptr) {
// You need a pointer to a pointer and return type can be void
int num_copy=num;
count=0; // Setting the count to zero
while(num_copy>0) {
num_copy/= 10; // Don't modify the original number
count++;
}
//Allocate enough memory to store the digits
*ptr=malloc(count*sizeof **ptr);
if(NULL==*ptr){
perror("Can't allocate memory");
exit(1);
}
// Then do the loop part with original num
for(int i=count -1; i>=0; i--) {
(*ptr)[i] = num%10;
num /= 10;
}
// By now you have an array 'array' of integers which you could print in main.
}
int main()
{
int number = 123456789;
int *array;
fun(number,&array); // &array is of type pointer to a pointer to integers
//Now print the individual digits
printf("Individual digits are : \n");
for(int i=count-1;i>=0;i--)
printf("%d\n",array[i]);
}
Looks to me like you are converting from an integer to digits. But I don't see where your code writes anything to the array.
If the array wasn't initialized before this, that would explain why it still contains random values.
Related
I'm having trouble with the following: I want to take a large number (cca. 15-digit) and turn it into individual digits and store them in an array. I will need these digits further on in the code. The problem is, if I declare the array outside the while loop, it stores the first four values, but then I get a segmentation fault. If I declare it within the loop, the code works as I want it to, but then I don't know how to move the array out of that loop, so that I could use it further. How can I solve this? This is what I've compiled:
unsigned long long card_num;
printf("Enter your credit card number:\n");
scanf("%llu", &card_num);
int count = 0;
while (card_num != 0)
{
int digits[count]; //declaring array into which digits will be stored
digits[count] = card_num%10; // get last digit, store it in array
card_num = card_num/10; //remove last digit
printf("Digit[%i] = %i\n", count, digits[count]);
printf("Number of digits: %i\n", count);
count ++;
}
In your code, for the very first iteration
int digits[count];
count is 0, which violates the constraints mentioned in spec. As per C11, chapter 6.7.5.2,
In addition to optional type qualifiers and the keyword static, the [ and ] may delimit an expression or *. If they delimit an expression (which specifies the size of an array), the expression shall have an integer type. If the expression is a constant expression, it shall have a value greater than zero. [....]
and
If the size is an expression that is not an integer constant expression: if it occurs in a declaration at function prototype scope, it is treated as if it were replaced by *; otherwise, each time it is evaluated it shall have a value greater than zero
So, this is not a valid code.
As already mentioned, what you are doing is plain wrong.
There is several ways to solve this issue. The easiest would be to allocate an array at the beginning of your program with enough space for all your usecases with something like :
#define MAX_DIGIT 50
int digits[MAX_DIGIT];
Then you just have to check you are not going over this array by checking that count < MAX_DIGIT.
Another way would be using dynamic memory allocation using an int pointer int *digits and malloc (I let you google that) once you know the size of the array you'll need. You'll have to change a bit your code to know the number of digits before starting to get the digits as you need to allocate the memory before starting to store digits.
You could use realloc to keep a code similar to what you already have, but I wouldn't advise it as it is not efficient to realloc memory for each value that you add.
Your logic is fine.
What went wrong is that you tried to increase the length of a fixed-length array while iterating which is not allowed.
You should never change the length of a fixed-length array anywhere in the program.
However if you want to change the length of an array during runtime you must use the malloc and realloc functions to do so.
Check out this example:
//declarations
int *storeNum;
storeNum = (int *)malloc(1 * sizeof(int));
//logic
while(num != 0) {
if(i > 0)
storeNum = realloc(storeNum, (i+1) * sizeof(int));
storeNum[i] = num % 10;
num = num/10;
++i;
}
Here first I declared the array size initially as one and later incremented it using realloc function.
You also have the array size stored in i which you can use later in your code in loops.
But keep in mind that the digits will be stored in your array in reverse order.
Also, you shouldn't declare an array within a loop.
Since you have "declared" the array, each time the compiler enters the loop while iterating it will consider the array-declaration as a new array. That is all.
I want to get a variable from user and set it for my array size. But in C I cannot use variable for array size. Also I cannot use pointers and * signs for my project because i'm learning C and my teacher said it's forbidden.
Can someone tell me a way to take array size from user?
At last, I want to do this two projects:
1- Take n from user and get int numbers from user then reverse print entries.
2- Take n from user and get float numbers from user and calculate average.
The lone way is using array with variable size.
<3
EDIT (ANSWER THIS):
Let me tell full of story.
First Question of my teacher is:
Get entries (int) from user until user entered '-1', then type entry numbers from last to first. ( Teacher asked me to solve this project with recursive functions and with NO any array )
Second Question is:
Get n entries (float) from user and calculate their average. ( For this I must use arrays and functions or simple codes with NO any pointer )
Modern C has variable size arrays, as follows:
void example(int size)
{
int myArray[size];
//...
}
The size shouldn't be too large because the aray is allocated on the stack. If it is too large, the stack will overflow. Also, this aray only exists in the function (here: funtion example) and you cannot return it to a caller.
I think your task is to come up with a solution that does not use arrays.
For task 2 that is pretty simple. Just accumulate the input and divide by the number of inputs before printing. Like:
#include <stdio.h>
#include <stdlib.h>
int main()
{
float result = 0;
float f;
int n = 0;
printf("How many numbers?\n");
if (scanf("%d", &n) != 1) exit(1);
for (int i=0; i < n; ++i)
{
if (scanf("%f", &f) != 1) exit(1);
result += f;
}
result /= n;
printf("average is %f\n", result);
return 0;
}
The first task is a bit more complicated but can be solved using recursion. Here is an algorithm in pseudo code.
void foo(int n) // where n is the number of inputs remaining
{
if (n == 0) return; // no input remaining so just return
int input = getInput; // get next user input
foo(n - 1); // call recursive
print input; // print the input received above
}
and call it like
foo(5); // To get 5 inputs and print them in reverse order
I'll leave for OP to turn this pseudo code into real code.
You can actually use variable sized arrays. They are allowed when compiling with -std=c99
Otherwise, you can over-allocate the array with an arbitrary size (like an upper bound of your actual size) then use it the actual n provided by the user.
I don't know if this helps you, if not please provide more info and possibly what you have already achieved.
I'm quite puzzled by why my variable NumberOfArrays changes the second time through the for loop in my code. Can anyone help me out?
#include <stdio.h>
#include <cs50.h>
int main(int argc, string argv[])
{
//variable declarations
int NumberOfArrays = 0;
int arrayRack[0];
//Get number of arrays
printf("Key in the number of arrays you'd like to have\n");
NumberOfArrays = GetInt();
//Get number for each element in arrayRack[]
for(int i = 0; i < NumberOfArrays; i++)
{
printf("give me an int for the %i th array\n", i + 1);
arrayRack[i] = GetInt();
// *** on the second pass, my "NumberOfArrays" gets adjusted to my GetInt number here. Why?
}
//print out numbers stored in respective arrays
for(int j = 0; j < NumberOfArrays; j++)
{
printf("{%i}<-- number in %ith array\n", arrayRack[j], j + 1);
}
return 0;
}
Because you declared arrayRack as an empty array ([0]). Try int arrayRack[100]; or some other number, and make sure that NumberOfArrays is less than that number before you use it.
Explanation: (edit note that this may vary by compiler) your variables are most likely stored on the stack in nearby memory addresses. So arrayRack points somewhere close to NumberOfArrays in memory. C doesn't generally check if you've run off the end of an array, so accessing arrayRack[1] doesn't cause a compiler error in this situation. However, arrayRack[1] isn't part of your array, so accessing it actually accesses something else — in this situation, NumberOfArrays.
Edit gcc permits length-0 arrays but does not allocate space for them per this. However, length-0 arrays are prohibited by the C standard (e.g., see this, the answers to this, and this). Given the behaviour you've seen, it looks to me like the compiler is allocating one int's worth of space on the stack, pointing arrayRack to that space, and packing that space right next to NumberOfArrays. As a result, &(arrayRack[1]) == &NumberOfArrays. In any event, using variable-length arrays as suggested by #dasblinkenlight is a cleaner way to handle this situation.
In general, given int arrayRack[N];, you can only safely access arrayRack[0] through arrayRack[N-1].
You declared the array too early. Move the declaration to after the call of GetInt(), like this:
printf("Key in the number of arrays you'd like to have\n");
int NumberOfArrays = GetInt();
int arrayRack[NumberOfArrays];
Note: NumberOfArrays is not an ideal name for the variable, because it denotes the number of array elements, not the number of arrays; your code has only one array.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am trying to sum an array of numbers. The array has a length determined by an input and then the user gives the array. There were no compilation errors and I am able to run other programs. On the immediate start of running the program I am given a message that program has stopped working and that windows is searching for solution.
#include <stdio.h>
int main()
{
int sum, length, count;
int array[length];
sum=0;
scanf("%d",&length);
scanf("%d",&sum);
for(count=0; count<length-1; count++)
{
sum = sum + array[count];
}
printf("%d", sum);
return 0;
}
When you declare your array it depends on length but you ask the user for length after.
A solution could be to ask the user for length (scanf("%d",&length);) before declaring your actual array (int array[length];).
you should move int array[length] to after scanf("%d", &length). But it is not allowed in C to declare variables after the first non-declaration (it is however possible if you compile this program as C++).
In fact, in standard C you can't have a non-const length definition for an array variable. gcc on the other hand for example allows this nevertheless.
In your case, the problem is that length has an undefined value at the declaration of int array[length];. If you are lucky, your data segment has been initialized to zero (there is no guarantee for that) but otherwise, it may be any value, including a value which leads the program to exceed your physical memory.
A more standard way of doing this is:
int *array = NULL;
scanf("%d",&length);
...
array = (int*) malloc(sizeof(int) * length);
...
free(array);
By the way, even after fixing that, you will most likely get random numbers because you never actually assign the contents of the elements of array.
Local variable are initialized to 0. Hence value of length is 0. So you array is of length. You are then reading length, say 10, from stdin and expect the array to be of length 10. This can't be. Since this is a stack variable, the size is determined in time of pre-processing and not in run time. If you want to define the array length in run time then use malloc.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int sum, length, count;
int *array;
sum=0;
scanf("%d", &length);
scanf("%d",&sum);
array = (int *)malloc(sizeof(int) * length);
if (array == NULL) return 0;
memset(array, length, 0);
for(count=0; count<length-1; count++)
{
sum = sum + array[count];
}
printf("%d", sum);
return 0;
}
Thanks.
first problem:
the length variable is being used to set the number of entries in the array[], before the variable length is set. Therefore, length will contain what ever trash happens to be on the stack when the program starts so the number of entries defined in array[] is an unknown.
This results in undefined behaviour and could lead to a seg fault event, depending on what was on the stack and what the user entered for length.
second problem:
The array array[] is never initialized so will contain what ever trash is on the stack at program startup. This means the value being printed could be anything. And the 'sum' could overflow, depending on the trash values in array[]
OP program lacks the part of data input, it's asking for sum instead of the values to sum, which is weird. The only inputs requested are also never checked (the return value of scanf must always be checked).
In C (at least C99 and optionally C11) Variable Length Arrays, like the one defined by int array[length], can be used, but the variable length here is used uninitialized and before it is even asked to the user.
Moreover, the loop where the sum is calculated stops before the last element of the array (not really a big deal in this case, considering that all those variables are uninitialized...).
A better way to perform this task could be this:
#include <stdio.h>
// helper function to read an integer from stdin
int read_int( int *value ) {
int ret = 0;
while ( (ret = scanf("%d", value)) != 1 ) {
if ( ret == EOF ) {
printf("Error: Unexpected end of input.\n");
break;
}
scanf("%*[^\n]"); // ignore the rest of the line
printf("Please, enter a number!\n");
}
return ret;
}
int main(void) {
int sum = 0,
length = 0,
count,
i;
printf("Please, enter the number of values you want to add: ");
if ( read_int(&length) == EOF )
return -1;
// Use a VLA to store the numbers
int array[length];
// input the values
for ( count = 0; count < length; ++count ) {
// please, note ^^^^^^^^ the range check
printf("Value n° %2d: ", count + 1);
if ( read_int(&array[count]) == EOF ) {
printf("Warning: You entered only %d values out of %d.\n",
count, length);
break;
}
// you can sum the values right here, without using an array...
}
// sum the values in the array
for ( i = 0; i < count; ++i ) {
// ^^^^^^^^^ sum only the inputted values
sum += array[i];
}
printf("The sum of the values is:\n%d\n", sum);
return 0;
}
This question already has answers here:
Length of array in function argument
(9 answers)
Closed 7 years ago.
I have this piece of code:
#include <stdio.h>
int average(int array []);
int main () {
int num_array[];
int x = 0;
while(num_array[x] != -1){
printf("Enter a number\n");
scanf("%d",&num_array[x]);
x++;
}
printf("%d\n", average(num_array));
return 0;
}
int average(int array[]){
int i;
int total_size = (int)sizeof(array);
int sum = 0;
for(i = 0; i < total_size; i++){
sum = sum + array[i];
}
return sum/total_size;
}
But i get an error at compile time, because i'm not initialising the array. However i can't do it, since i don't know it's size.
How can i solve this ?
You can't declare an array like
int num_array[];
in C except when it is a parameter of a function. You must have to specify the size.
This is actually a surprisingly tricky problem in C unless you're using an array library. What you're actually talking about is a growable array. For what you're trying to do, you start with an initial size, say 10, using malloc() and as the inputs grow, you have to realloc() the array to a larger size. Generally, you double the size of the array every time the limit is hit. If you're a beginning C programmer, this is probably too much to take on. I would set a fixed limit, and enforce it by not accepting any more input after the limit is hit. Given that you can comfortably allocate 1000's of ints and a human won't want to type that much, you can easily make a practical limit ahead of time and declare the array as such:
int num_array[1000];
You need to provide the size of the array here: int num_array[];.
If you are working with a structure of unknown size, you could:
Ask the user how many numbers are going to be entered (not really practical, but might suffice if your case is a trivial one).
Initialize it with a default size, say 10 and then if you need, create larger arrays and copying your current data to the new one.
Or else, you use a linked list like data structure and create new elements as you go along, thus allowing your list to grow as much as you need it to be.