I am in the process of learning C thoroughly. I got the code below from another site and have some questions about it. I apologize in advance if I am not using this site correctly. I am new to posting here. Can someone please explain why scanf() is used in the while loop and not before it?
#include <stdio.h>
#include <conio.h>
void main()
{
int a[2][2],*p;
p = &a[0][0];
printf("enter 4 numbers\n");
while ( p < (&a[0][0]+4) && scanf("%d",p++) );
printf("the numbers are\n");
p=&a[0][0];
while( p < (&a[0][0]+4) && printf("%d",*p++) );
}
conio.h was used in MS-DOS. Are you using MS-DOS? Probably not. Don't include this header.
Add a {} or ; to the end of each while loop. This is proper syntax. Otherwise, you will get a parser error.
While this code will print the four values entered once you fix those issues, it is a convoluted way to teach you about loops. printf will return the number of characters printed. scanf on success, the function returns the number of items of the argument list successfully filled. This count can match the expected number of items or be less (even zero) due to a matching failure, a reading error, or the reach of the end-of-file.
&a[0][0]+4 are memory addresses. Each time you run this program, you will get different memory addresses.
p=&a[0][0] will start p at the beginning to prepare it to print out the values in the next while loop.
You can read more on pointer arithmetic of multi-dimensional arrays here.
The integer pointer variable p is already initialized. In the while loop this reference is checked to see whether the array holds the four numbers.
while ( p < (&a[0][0]+4) && scanf("%d",p++) );
the actual code is
#include <stdio.h>
#include <conio.h>
int main()
{
int a[2][2],*p;
p = &a[0][0];
printf("enter 4 numbers\n");
while ( p < (&a[0][0]+4) && scanf("%d",p++) );
printf("the numbers are\n");
p=&a[0][0];
while( p < (&a[0][0]+4) && printf("%d",*p++) );
return 0;
}
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)
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 was working on a program for my intro to C class (xtra credit assignment) and can't figure out how to discard duplicates numbers on an array. The problem asks to only print non duplicates; so I able to print the first number, compare the following and print if different, I discard the next if a duplicate, but the thing is I've only figured out how to compare the one number it following one, I figured I could do another for loop inside the for loop, but I'm getting super confused and just can't figure it out. I've already submitted my code last week, I've just been working on this trying to figure it out for myself so any help/guidance would be greatly appreciated.
"EDIT: Here's the problem: Use a single-subscripted array to solve the following problem. Read in 20 numbers, each of which is between 10 and 100, inclusive. As each number is read, print it only if it's not a duplicate of a number already read. Provide for the worst case in which all 20 numbers are different. Use the smallest possible array to solve this problem"
Thanks in advance, and any advice on how I'm writing my program would also be appreciated as I'm a total noob, and trying to be a good programmer with as little bad habits as possible.
#include <stdio.h>
#include <stdlib.h>
#define AS 20
void findDuplicate (int af[], int fAS);
int main(){
int a[AS], i , j, k;
int last = 0;
printf("Enter %d numbers between 10 and 100:\n", AS);
for (i = 0; i < AS; i++){
scanf("%d",&a[i] );
if (a[i] >= 10 && a[i] <= 100 ){
continue;
} else {
printf("You must enter values between 10 - 100\n");
i = i -1;
}
}
findDuplicate(a, AS);
system ("pause");
return 0;
}
void findDuplicate (int af[], int fAS){
int c;
printf("You entered ");
for (c=0; c < fAS; c++){
if (af[c] != af[c+1]){
printf("%d ", af[c]);
}
continue;
}
printf("\n");
}
You should first define an Array which can save as many variables as you want ..
Lets say you are comparing for 10-100 which means 91 possible different digits.
so , define array with the size of 91. and then do the scanning in for loop for 91 times to find out if you have that variable entered previously. If not then save it and display it ,else discard it.
What I want to do is reverse a string of numbers that the user enters. what happens is it compiles and runs till i hit enter after the scanf. then I get some Microsoft runtime error... what's going wrong???
NOTE: this is homework, but i've got the logic figured out. what baffles me is this error.
#include <stdio.h>
int main()
{
unsigned int giveStr = 0;
char* charIt;
printf("Enter a number to be reversed.\t");
scanf("%d", &giveStr);
fflush(stdin);
sprintf(charIt, "%d", giveStr);
revStr(giveStr);
getchar();
return 0;
}
revStr(unsigned int n)
{
char buffer[100];
int uselessvar, counter = 0;
for (; n > 0;)
{
uselessvar = sprintf(&buffer[counter], "%d", n);
counter++;
}
for (counter = 0; counter > 0;)
{
printf("%c", buffer[counter]);
counter--;
}
return 0;
}
EDIT: flushing stdin for newlines :/ and also image here just not with that program. with mine.
You are trying to access memory which is not allocated in:
sprintf(charIt, "%d", giveStr);
Change char* charIt; to char charIt[50]; and all should be well (well, at least the segmentation fault part)
Also... pass charIt to revStr, as charIt contains the string with our number.
Then, a simple for loop in revStr will do the trick (what was the purpose of the second one, anyway?)
void revStr(char *giveStr)
{
int counter;
for (counter = strlen(giveStr)-1; counter >= 0; counter--)
{
printf("%c", giveStr[counter]);
}
printf("\n");
}
This will print each char our char representation has from the last one till the first one. You should read more on for loops.
For your home work problem, if you have the K&R book, turn to section 3.5 and read it thoroughly.
Note the functions reverse() and itoa(). They should give you a pretty good idea on how to solve your problem.
How does your program get out of the for (; n > 0;) loop? Won't counter simply increase until you get a bus error?
ED:
Respectfully, I think the claim that "i've got the logic figured out" is a little optimistic. :^) Doubtless someone will post the way it should have been done
by the time I'm done writing this, but it's probably worth drawing attention to what went wrong (aside from the memory allocation problems noted elsewhere):
Your first loop, "for (; n > 0;)", is strange because you're printing the entire number n into the buffer at counter. So why would you need to do this more than once? If you were selecting individual digits you might, but you're not, and obviously you know how to do this because you already used "sprintf(charIt, "%d", giveStr);". [Aside: giveStr isn't a great name for an unsigned integer variable!]
Your second loop also has strange conditions: you set counter to 0, set the condition that counter > 0, and then decrease counter inside. This obviously isn't going to loop over the characters in the way you want. Assuming you thought the first loop was character-by-character, then maybe you were thinking to loop down from counter-1 to 0?
So I have only ever programmed in c++, but I have to do a small homework that requires the use of c. The problem I encountered is where I need a loop to read in numbers separated by spaces from the user (like: 1 5 6 7 3 42 5) and then take those numbers and fill an array.
the code I wrote is this:
int i, input, array[10];
for(i = 0; i < 10; i++){
scanf("%d", &input);
array[i] = input;
}
EDIT: added array definition.
any suggestions or hints would be very highly appreciated.
Irrespective of whatever is wrong here, you should quickly learn to NEVER write code that does not check the return value from any API call that you make. scanf returns a value, and you have to be interested in what it says. If the call fails, your logic is different, yes?
Perhaps in this case it would tell you what's going wrong. The docs are here.
Returns the number of fields
successfully converted and assigned;
the return value does not include
fields that were read but not
assigned. A return value of 0
indicates that no fields were
assigned.
This code working good.
If your numbers is less than 10, then you must know how many numbers is before you start reading this numbers, or last number must be something like 0 to terminate output then you can do while(true) loop, but for dynamically solution you must read all line into string and then using sscanf to reading numbers from this string.
You need the right #include and a proper main. The following works for me
#include <stdio.h>
int main(void) {
/* YOUR CODE begin */
int i, input, array[10];
for (i = 0; i < 10; i++) {
scanf("%d", &input);
array[i] = input;
}
/* end of YOUR CODE */
return 0;
}
i'm not a c programmer but i can suggest an algorithm which is to use scanf("%s",&str) to read all the input into a char[] array then loop over it and test using an if statment if the current char is a space, if it is then add the preceeding number to the array