I am new in c programming and I am studying arrays right now. I saw that unlike java you can't print them automatically by using Arrays.toString() method. I want to write a simple function that prints the array.
In the program it asks us the size of the array and when we write it, it asks what is the value for each element and then the program calls the displayArray() function to print the array on a single line.
For example :
Hello. What will be the size of the new array?
3
Enter the 1. element
7
Enter the 2. element
5
Enter the 3. element
1
The result should be "Your array is: 7 5 1" but instead of that I get "Your array is: 3 6356728 2" as a result. Can you help?
#include <stdio.h>
void displayArray();
int main()
{
int size;
printf("Hello. What will be the size of the new array?\n");
scanf("%d", &size);
int myarray[size];
for (int i = 0; i < size; i++)
{
printf("Enter the %d. element\n" , (i + 1));
scanf("%d", &myarray[i]);
}
displayArray(myarray[size], size);
return 0;
}
void displayArray(int myarray[], int size)
{
printf("Your array is: ");
for (int i = 0; i < size; i++)
{
printf("%d ", myarray[i]);
}
return;
}
You have a problem in the function call (which your compiler should have warned you about, read the footnote later)
displayArray(myarray[size], size);
should be
displayArray(myarray, size);
because,
Type mismatch between formal parameter and actual argument: you function expects an array (a pointer to the first element of the array, to be precise), not an element of the array.
undefined behavior. For an array defined as int myarray[size], accessing element like myarray[size] is off-by-one, as C arrays are 0-based indexing.
Footnote:
If you try to compile your code, compiler should complain about the mismatch. It can happen either
You did not turn up the compiler warning level (which is a mistake from your side)
or, you chose to ignore the warnings (which is an "offense" from your side)
It's a common mistake which beginners commit.
While calling a function in which you pass an array, you only need to specify the name of the array you want to pass.
Related
I'm trying to create a complete C program to read ten alphabets and display them on the screen. I shall also have to find the number of a certain element and print it on the screen.
#include <stdio.h>
#include <conio.h>
void listAlpha( char ch)
{
printf(" %c", ch);
}
int readAlpha(){
char arr[10];
int count = 1, iterator = 0;
for(int iterator=0; iterator<10; iterator++){
printf("\nAlphabet %d:", count);
scanf(" %c", &arr[iterator]);
count++;
}
printf("-----------------------------------------");
printf("List of alphabets: ");
for (int x=0; x<10; x++)
{
/* I’m passing each element one by one using subscript*/
listAlpha(arr[x]);
}
printf("%c",arr);
return 0;
}
int findTotal(){
}
int main(){
readAlpha();
}
The code should be added in the findTotal() element. The output is expected as below.
Output:
List of alphabets : C C C A B C B A C C //I've worked out this part.
Total alphabet A: 2
Total alphabet B: 2
Total alphabet C: 6
Alphabet with highest hit is C
I use an array to count the number of the existence of each character,
I did this code but the display of number of each character is repeated in the loop
int main()
{
char arr[100];
printf("Give a text :");
gets(arr);
int k=strlen(arr);
for(int iterator=0; iterator<k; iterator++)
{
printf("[%c]",arr[iterator]);
}
int T[k];
for(int i=0;i<k;i++)
{
T[i]=arr[i];
}
int cpt1=0;
char d;
for(int i=0;i<k;i++)
{int cpt=0;
for(int j=0;j<k;j++)
{
if(T[i]==T[j])
{
cpt++;
}
}
if(cpt>cpt1)
{
cpt1=cpt;
d=T[i];
}
printf("\nTotal alphabet %c : %d \n",T[i],cpt);
}
printf("\nAlphabet with highest hit is : %c\n",d,cpt1);
}
There is no way to get the number of elements You write in an array.
Array in C is just a space in the memory.
C does not know what elements are actual data.
But there are common ways to solve this problem in C:
as mentioned above, create an array with one extra element and, fill the element after the last actual element with zero ('\0'). Zero means the end of the actual data. It is right if you do not wish to use '\0' among characters to be processed. It is similar to null-terminated strings in C.
add the variable to store the number of elements in an array. It is similar to Pascal-strings.
#include <stdio.h>
#include <string.h>
#define ARRAY_SIZE 10
char array[ARRAY_SIZE + 1];
int array_len(char * inp_arr) {
int ret_val = 0;
while (inp_arr[ret_val] != '\0')
++ret_val;
return ret_val;
}
float array_with_level[ARRAY_SIZE];
int array_with_level_level;
int main() {
array[0] = '\0';
memcpy(array, "hello!\0", 7); // 7'th element is 0
printf("array with 0 at the end\n");
printf("%s, length is %d\n", array, array_len(array));
array_with_level_level = 0;
const int fill_level = 5;
int iter;
for (iter = 0; iter < fill_level; ++iter) {
array_with_level[iter] = iter*iter/2.0;
}
array_with_level_level = iter;
printf("array with length in the dedicated variable\n");
for (int i1 = 0; i1 < array_with_level_level; ++i1)
printf("%02d:%02.2f ", i1, array_with_level[i1]);
printf(", length is %d", array_with_level_level);
return 0;
}
<conio.h> is a non-standard header. I assume you're using Turbo C/C++ because it's part of your course. Turbo C/C++ is a terrible implementation (in 2020) and the only known reason to use it is because your lecturer made you!
However everything you actually use here is standard. I believe you can remove it.
printf("%c",arr); doesn't make sense. arr will be passed as a pointer (to the first character in the array) but %c expects a character value. I'm not sure what you want that line to do but it doesn't look useful - you've listed the array in the for-loop.
I suggest you remove it. If you do don't worry about a \0. You only need that if you want to treat arr as a string but in the code you're handling it quite validly as an array of 10 characters without calling any functions that expect a string. That's when it needs to contain a 0 terminator.
Also add return 0; to the end of main(). It means 'execution successful' and is required to be conformant.
With those 3 changes an input of ABCDEFGHIJ produces:
Alphabet 1:
Alphabet 2:
Alphabet 3:
Alphabet 4:
Alphabet 5:
Alphabet 6:
Alphabet 7:
Alphabet 8:
Alphabet 9:
Alphabet 10:-----------------------------------------List of alphabets: A B C D E F G H I J
It's not pretty but that's what you asked for and it at least shows you've successfully read in the letters. You may want to tidy it up...
Remove printf("\nAlphabet %d:", count); and insert printf("\nAlphabet %d: %c", count,arr[iterator]); after scanf(" %c", &arr[iterator]);.
Put a newline before and after the line of minus signs (printf("\n-----------------------------------------\n"); and it looks better to me.
But that's just cosmetics. It's up to you.
There's a number of ways to find the most frequent character. But at this level I recommend a simple nested loop.
Here's a function that finds the most common character (rather than the count of the most common character) and if there's a tie (two characters with the same count) it returns the one that appears first.
char findCommonest(const char* arr){
char commonest='#'; //Arbitrary Bad value!
int high_count=0;
for(int ch=0;ch<10;++ch){
const char counting=arr[ch];
int count=0;
for(int c=0;c<10;++c){
if(arr[c]==counting){
++count;
}
}
if(count>high_count){
high_count=count;
commonest=counting;
}
}
return commonest;
}
It's not very efficient and you might like to put some printfs in to see why!
But I think it's at your level of expertise to understand. Eventually.
Here's a version that unit-tests that function. Never write code without a unit test battery of some kind. It might look like chore but it'll help debug your code.
https://ideone.com/DVy7Cn
Footnote: I've made minimal changes to your code. There's comments with some good advice that you shouldn't hardcode the array size as 10 and certainly not litter the code with that value (e.g. #define ALPHABET_LIST_SIZE (10) at the top).
I have used const but that may be something you haven't yet met. If you don't understand it and don't want to learn it, remove it.
The terms of your course will forbid plagiarism. You may not cut and paste my code into yours. You are obliged to understand the ideas and implement it yourself. My code is very inefficient. You might want to do something about that!
The only run-time problem I see in your code is this statement:
printf("%c",arr);
Is wrong. At this point in your program, arr is an array of char, not a single char as expected by the format specifier %c. For this to work, the printf() needs to be expanded to:
printf("%c%c%c%c%c%c%c%c%c%c\n",
arr[0],arr[1],arr[2],arr[3],arr[4],
arr[5],arr[6],arr[7],arr[8],arr[9]);
Or: treat arr as a string rather than just a char array. Declare arr as `char arr[11] = {0};//extra space for null termination
printf("%s\n", arr);//to print the string
Regarding this part of your stated objective:
"I shall also have to find the number of a certain element and print it on the screen. I'm new to this. Please help me out."
The steps below are offered to modify the following work
int findTotal(){
}
Change prototype to:
int FindTotal(char *arr);
count each occurrence of unique element in array (How to reference)
Adapt above reference to use printf and formatting to match your stated output. (How to reference)
Variable length arrays are not allowed. But then, I recently learned that user-defined function manipulates the original array, not its own personal copy. So I thought of creating a function that gets the desired size of the array by the user and therefore modifying the size (I also initialized the array in this function).
void fill_array(int array[], int size, int in_val);
void main(){
int n, value, list[1], ctr;
clrscr();
printf("Enter the size of the array: ");
scanf("%d", &n);
printf("Enter the value that you want all of the elements to take initially: ");
scanf("%d", &value);
printf("\nAfter scanning value, n = %d\n", n);
fill_array(list, n, value);
printf("\nAfter Function fill_array Execution");
printf("\nThe values of each element of the array is now: %d ", list[0]);
printf("%d ", list [1]);
printf("%d ", list [2]);
printf("\nn = %d\n", n);
printf("value = %d\n", value);
getch();
}
void fill_array(int array[], int size, int in_val){
int ctr;
for (ctr = 0; ctr < size; ++ctr)
array[ctr] = in_val;
printf("\nInside Function");
printf("\nn = %d\n", size);
printf("value = %d\n", in_val);
}
Here's the console / a sample run:
Enter the size of the array: 3
Enter the value that you want all of the elements to take initially: 444
After scanning value, n = 3
Inside Function
n = 3
value = 444
After Function fill_array Execution
The value of each element of the array is now: 444 444 444
n = 444
value = 444
The function did modify list. However, as you can see, it also changed the value of n. After every fill_array execution, n always equals value. Will someone please explain to me why the function is changing the value of n. I don't want the value of n to change.
Within the fill_array function you are trying to write into memory that is out of bounds for list array. Doing so will result in undefined behaviour.
From wiki article on undefined behaviour:
The behavior of some programming languages—most famously C and C++—is undefined in some cases. In the standards for these languages the semantics of certain operations is described as undefined. These cases typically represent unambiguous bugs in the code, for example indexing an array outside of its bounds.
The C Committee draft (N1570) states this about Undefined Behavior:
3.4.3
1 undefined behaviour
behavior, upon use of a nonportable or erroneous program construct or of erroneous data,
for which this International Standard imposes no requirements
2 NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
Once an array is defined, there is no way to change its size.
A workaround for this is to use dynamic memory allocation and then use the allocated memory as if it is an array. This could look something like:
printf("Enter the size of the array: ");
if (scanf("%d", &n) != 1) exit(1);
printf("Enter the value that you want all of the elements to take initially: ");
if (scanf("%d", &value) != 1) exit(1);
int * list = malloc(n * sizeof *list); // allocate memory
fill_array(list, n, value);
// and just use it as an array
list[1] = list[0] + 42; // assuming n >= 2
...
...
free(list);
If you later on need to resize the array, you can use the function realloc
As the requirement is that "Variable lenght arrays are not allowed" the only possible soulution is to allocate an array of "big enough" size.
Then you do not pass as n the size of the array, but the number of elements.
So you just loop over the array and stop at lenght n. You need to rewrite the function fill_array to accomplish this behavior.
Why you get the output you get is because of undefined behaviour. See P.W's answer for more info on that.
I am trying to use Bubblesort for a 2-D array, using a custom sized 2D Array with the max limit of [100][2]. I am a beginner at this, so i am not great at formatting code properly so shedding light would be great.
my input
How many items of data do you wish to enter? 4
Please enter in the X coordinate: 4
Please enter in the Y coordinate: 4
Please enter in the X coordinate: 3
Please enter in the Y coordinate: 3
Please enter in the X coordinate: 2
Please enter in the Y coordinate: 2
Please enter in the X coordinate: 1
Please enter in the Y coordinate: 1
So that prints out how many numbers you wish to enter from a custom array input.
output(Meant to compare each array and switch to ascending order).
Printing in Ascending Order:
[4][3]
[3][3]
[3][3]
It prints 3 arrays not 4, and doesn't print out any of the numbers i entered.
so
But could anybody shed some light on this? It is specifically the Bubblesort function.
int main()
{
int arrayHeight, array[100][2];
printf ("***** Bubble Sort ***** \n");
InputArray(array, arrayHeight);
}
int InputArray(int array[100][2], int arrayHeight, int swap)
{
int i, xCoord, yCoord;
printf("\n How many items of data do you wish to enter? ");
scanf("%d",&arrayHeight);
for(i=0; i<arrayHeight; i++)
{
printf("Please enter in the X coordinate: ");
scanf("%d", &xCoord);
printf("Please enter in the Y coordinate: ");
scanf("%d", &yCoord);
array[i][0] = xCoord;/* Name of XCoordinate and position within Array*/
array[i][1] = yCoord;/*Name of YCoordinate and position within Array*/
}
DisplayArray(array, arrayHeight);
}
int DisplayArray(int array[100][2], int arrayHeight, int swap)
{
int i, j;
printf("\n The 2-D Array contains : \n");
for(i=0; i<arrayHeight; i++)
{
printf("[%d][%d]\n\r", array[i][1], array[i][0]);
}
BubbleSort(array, arrayHeight);
}
int BubbleSort(int array[100][2], int arrayHeight)
{
int swap, i, j, k;
printf("\n Printing in Asending Order: ");
for (i = 0; i <arrayHeight-1; i++)
{
if (array[i][0] > array[i][1 + 1])
{
array[1][i] = array[1][0+1];
swap = array[1][i];
array[i][1 + 1];
printf("\n [%d][%d] ", array[i][0], array[1][i]);
}
}
}
There's a fair amount of things going on here.
Your Question
Your program is printing out strange parts of your array because of the way you're calling printf from within BubbleSort. While BubbleSort is still running, your array isn't fully sorted. However, the function calls printf after each attempt at swapping array elements. If you'd like to print your whole array after sorting, it would be better to allow the sorting function to run to completion, then print out the array in full afterwards.
Other Stuff
There are a lot of points tangential to your question that I'd like to raise to help you out from a style and correctness perspective. Also, some of these are rather interesting.
#include Statements
When compiling this, you should be getting several warnings. If you're using gcc, one of those warnings will be something like:
main.c: warning: incompatible implicit declaration of built-in function ‘printf’
printf ("***** Bubble Sort ***** \n");
This states that the function printf has been implicitly declared when it was called. That is, the compiler inferred that a function printf exists because you called a function named printf. The problem is that it knows nothing about this function other than that it probably exists. This means the complier doesn't know what the function is supposed to return or what arguments it is supposed to accept, so it cannot help you if you use it inappropriately. To avoid this problem, you should include the standard C Input/Output headers in your program like so:
#include <stdio.h>
The stdio.h header file includes many functions besides just printf. Check out man 3 stdio for more information on it.
Define or Declare Functions Before Calling Them
One of the less-modern aspects of C is that it runs through your program from top to bottom. Many modern languages allow you to put your function declarations anywhere in your code and then it works things out on its own. Javascript's variable and function hoisting is an example of this.
Because C does not do this, you should define or declare your functions before you call them. If you call them without a declaration or definiton, the compiler will fall back to the default function signature extern int <function_name>(); That is, if you do not supply a declaration or definition for your function, C will assume that function is defined elsewhere, returns an int, and takes an unspecified number of arguments.
In this program, the function DisplayArray is defined with three arguments:
int DisplayArray(int array[100][2], int arrayHeight, int swap);
However, it is called with only two arguments:
DisplayArray(array, arrayHeight);
This can only happen because when the function is first called, it hasn't yet been defined, so the compiler, without knowing any better, assumes the call is made correctly.
When this is corrected (the definition is put above the first call), the compiler will throw an error stating that the function DisplayArray takes three arguments, but it was called with only two.
Calling Functions / Program Structure
The most oft-cited benefit of creating functions in your code is modularity. This is the idea that you can freely re-use code at different points in your program while knowing what that code is going to do. This program sacrifices this benefit by creating a sort of function-chain, where each function calls the other. InputArray calls DisplayArray, and DisplayArray calls BubbleSort.
This means any time you'd like to print an array, you must be okay with it being bubble-sorted as well. This is considered bad practice because it reduces the amount of times calling the function is useful. A more useful function would be one that displays the array but does not call BubbleSort or modify the array in any way.
Bubble Sorting
Your question doesn't specify exactly how you'd like to bubble sort, but the function here doesn't implement the BubbleSort algorithm. Generally, it's best to make sure you understand the algorithm before applying it to strange cases like 2-D arrays. I've included a working example below, which I hope helps get you on the right track.
Briefly, note that there two loops in a bubble sort:
* an inner loop that runs through the array and swaps neighboring elements
* an outer loop that runs the inner loop until the entire array is sorted
Minor Things
C programs generally prefer snake_case to CamelCase, but more generally, you should do what works best for you. If you're on a team, use a style consistent with that team.
All of the functions in this program return int, yet none of them actually use a return statement or return a useful value. If you have a function does not return a useful value, return void instead (e.g. - void DisplayArray(int array[100][2], int arrayHeight)).
Your displayArray function swaps the position of x and y. printf will display parameters in the order you specify unless directed otherwise. Check out man 3 printf for more on that function.
Working Example
#include <stdio.h>
void DisplayArray(int array[100][2], int arrayHeight)
{
int i, j;
printf("\n The 2-D Array contains : \n");
for(i=0; i<arrayHeight; i++)
{
printf("[%d][%d]\n\r", array[i][0], array[i][1]);
}
}
void BubbleSort(int array[100][2], int arrayHeight)
{
int i;
int swap[2];
int swapHappened = 1;
// the outer loop runs until no swaps need to be made
// no swapping implies the array is fully sorted
while (swapHappened) {
swapHappened = 0;
// the inner loop swaps neighboring elements
// this is what 'bubbles' elements to the ends of the array
for (i = 0; i < arrayHeight-1; i++)
{
if ((array[i][0] > array[i+1][0]) ||
(array[i][0] == array[i+1][0]) && (array[i][1] > array[i+1][1]))
{
// if a swap happens, the array isn't sorted yet, set this variable
// so the `while` loop continues sorting
swapHappened = 1;
// save the higher-value row to a swap variable
swap[0] = array[i][0];
swap[1] = array[i][1];
// push the lower-valued row down one row
array[i][0] = array[i+1][0];
array[i][1] = array[i+1][1];
// put the saved, higher-value row where the lower-valued one was
array[i+1][0] = swap[0];
array[i+1][1] = swap[1];
}
}
DisplayArray(array, arrayHeight);
}
}
int main()
{
int arrayHeight, array[100][2];
printf ("***** Bubble Sort ***** \n");
int i, xCoord, yCoord;
printf("\n How many items of data do you wish to enter? ");
scanf("%d",&arrayHeight);
for(i=0; i<arrayHeight; i++)
{
printf("Please enter in the X coordinate: ");
scanf("%d", &xCoord);
printf("Please enter in the Y coordinate: ");
scanf("%d", &yCoord);
array[i][0] = xCoord;/* Name of XCoordinate and position within Array*/
array[i][1] = yCoord;/*Name of YCoordinate and position within Array*/
}
DisplayArray(array, arrayHeight);
BubbleSort(array, arrayHeight);
DisplayArray(array, arrayHeight);
return 0;
}
I don't get what you are trying to do with your BubbleSort function.
But just to get a few things right :
if (array[i][0] > array[i][1 + 1])
this shouldn't work, your array was initialized as "int array [100][2]". Conventionally the highest number that should be in the second square bracket is 1. (1+1 =2, by the way)
array[1][i] = array[1][0+1];
swap = array[1][i];
C executes code in a sequential basis, so the array[1][i] is overwritten with array[1][0+1] even before the original value is saved in the 'swap' variable.
array[i][1 + 1];
This line of code does not seem do anything.
If you could tell whether you are trying to sort 'by element' or by 'line' (ie by each array in the 2D array), maybe we could help you approach the problem correctly.
int akki(int arr[],int m,int n){
int i;
for(i=0;i<m;i++){
if(arr[i]==n)
return i;
}
return 20;
}
void main(){
int i,m,n,arr[10],a;
printf("Enter size of array:");
scanf("%d",&m);
printf("Enter %d elements of array:",m);
for(i=0;i<m;i++){
scanf("%d",arr[i]);
}
printf("Enter element to be searched:");
scanf("%d",&n);
a=akki(arr,m,n);
if(a!=20)
printf("Element found at %d position",a+1);
else
printf("Element not found");
}
IT is Returning 20 or some garbage value..even if condition matches... it is returning value of i.It is linear search function where m is size of array arr and n is element to be searched...
please explain in detail..i am new in c language
thankzzz in advance
You have a problem in your code. Change
scanf("%d",arr[i]);
To
scanf("%d",&arr[i]);
This is done because scanf expects an argument of type int* but you provide argument arr[i] which is of type int. Also add a check that ends the program if user inputs a number which is greater than 10 for the first scanf.
There can be two reasons.
Case 1 [Much likely for _always_]
Simple. Because your if(arr[i]==n) condition is not met, and i<m became false. It came out of for() loop and hence, return 20.
case 2 [Less likely for _always_]
By chance, the value of n is present at the 21st location [index 20] in the input array.
Apart from the coding aspect, did you understand what's the logical purpose of this function? If not, begin with that. It searches for a specific value in an array of given length, and if no element of the array matches that value, it returns 20.
Now analyze your case, based on your input.
EDIT:
After seeing the complete code, as Mr. CoolGuy has pointed out, use
scanf("%d",&arr[i]);
Just for more reference, you can look at Chapter 7.19.6.2, paragraph 12 , %d format specifier, which goes like
... The corresponding argument shall be a pointer to signed integer.
In your code, arr[i] is of type int. What you need is a int *, i.e., &arr[i].
I want to add numbers to an array using scanf
What did i do wrong? it says expected an expression on the first bracket { in front of i inside the scanf...
void addScores(int a[],int *counter){
int i=0;
printf("please enter your score..");
scanf_s("%i", a[*c] = {i});
}//end add scores
I suggest:
void addScores(int *a, int count){
int i;
for(i = 0; i < count; i++) {
printf("please enter your score..");
scanf("%d", a+i);
}
}
Usage:
int main() {
int scores[6];
addScores(scores, 6);
}
a+i is not friendly to newcomer.
I suggest
scanf("%d", &a[i]);
Your code suggests that you expect that your array will be dynamically resized; but that's not what happens in C. You have to create an array of the right size upfront. Assuming that you allocated enough memory in your array for all the scores you might want to collect, the following would work:
#include <stdio.h>
int addScores(int *a, int *count) {
return scanf("%d", &a[(*count)++]);
}
int main(void) {
int scores[100];
int sCount = 0;
int sumScore = 0;
printf("enter scores followed by <return>. To finish, type Q\n");
while(addScores(scores, &sCount)>0 && sCount < 100);
printf("total number of scores entered: %d\n", --sCount);
while(sCount >= 0) sumScore += scores[sCount--];
printf("The total score is %d\n", sumScore);
}
A few things to note:
The function addScores doesn't keep track of the total count: that variable is kept in the main program
A simple mechanism for end-of-input: if a letter is entered, scanf will not find a number and return a value of 0
Simple prompts to tell the user what to do are always an essential part of any program - even a simple five-liner.
There are more compact ways of writing certain expressions in the above - but in my experience, clarity ALWAYS trumps cleverness - and the compiler will typically optimize out any apparent redundancy. Thus - don't be afraid of extra parentheses to make sure you will get what you intended.
If you do need to dynamically increase the size of your array, look at realloc. It can be used in conjunction with malloc to create arrays of variable size. But it won't work if your initial array is declared as in the above code snippet.
Testing for a return value (of addScores, and thus effectively of scanf) >0 rather than !=0 catches the case where someone types ctrl-D ("EOF") to terminate input. Thanks #chux for the suggestion!