Variable Use Fgets with a char array in C - c

I'm trying to read in a grade (1-10) into an array called moduleGrades.
The fgets(moduleGrades[i]-1, sizeof(moduleGrades), stdin); causes an error, yet what i've typed is exactly what I need. I want to store 3 grades (if the number of modules entered was 3)
many thanks.
#include<stdio.h>
#include <string.h>
char name[30];
int moduleNumber;
char moduleGrades[2];
int main(int argc, char **argv)
{ //read name & module amount
printf ("Please enter your name: ");
fgets(name, sizeof(name), stdin);
printf ("How many Modules: ");
scanf("%d", &moduleNumber);
int i;
for (i = 1; i <= moduleNumber; i++)
{
printf ("Please enter module %d grade ", i);
fgets(moduleGrades[i]-1, sizeof(moduleGrades), stdin);
}
printf("%d", moduleGrades[0]);
printf("%d", moduleGrades[1]);
printf("%d", moduleGrades[2]);
return 0;
}

If you want to print three chars, as indicated by your output, then your array must also be able to hold three chars:
char moduleGrades[2];
Also this loop here:
int i;
for (i = 1; i <= moduleNumber; i++)
This isn't wrong in itself because you subtract the 1 you're off inside the loop, but I would do this and just put this instead:
for (int i = 0; i < moduleNumber; i++)
The fgets call inside the loop is wrong. You're giving it a char instead of a pointer to char. Instead of using fgets, I would just use scanf again:
scanf(" %c", &moduleGrades[i]);
When you print those char that you read in, you need to use the %c format specifier, too:
printf("%c", moduleGrades[0]);
This way it'll print the char that you read in earlier. For instance, if you pressed A, it will print A. With %d it will probably print 65, but it's undefined behavior, so anything else than that might happen instead and there's no guarantee on what exactly will happen.

Related

Code to print data of a name, price and its pages by using arrays

#include<stdio.h>
int main(){
char name[3];
float price[3];
int i,page[3];
printf("enter the name price and book\n");
for(i=0;i<3;i++){
scanf("%s",name[i]);
printf("enter character:\n");
}
for(i=0;i<3;i++) {
scanf("%f",&price[i]);
printf("enter floating point number:\n");
}
for(i=0;i<3;i++) {
scanf("%d",&page[i]);
printf("enter digit:\n");
}
printf("\n");
for(i=0;i<3;i++) {
printf("%s\n",name[i]);
}
for(i=0;i<3;i++) {
printf("%f\n",&price[3]);
}
for(i=0;i<3;i++){
printf("%d\n",&page[i]);
}
return 0;
}
When I was trying this code, I thought this was quite simple to do but I realized, there is something which I am missing in the code. The main problem with this code is it is not scanning the values of price and pages. I don't understand where I am mistaken.
So, please correct my code so that it will print the values of name price and pages.
There are a number of issues in your code. First and foremost, the %s specifier (for both the scanf and printf functions) expects a string argument (that is, a nul-terminated array of char for printf or an array sufficiently large to hold the input characters plus that terminator, for scanf); however, you are attempting to read (and print) a single char value in each of the relevant for loops.
To fix this, use the %c format specifier, instead of %s. However, when you use this, the newline character that is generated when you press the Enter key will be left in the input buffer, and that will be read as the actual char input on the next iteration of the first for loop. To clear any such newline (or, indeed other whitespace) from the input before the real input, add a space in the format string before the %c. Also, when using this, you will need to pass the address of each name element: scanf(" %c", &name[i]);.
Further, the printf function takes the actual values of the variables to be output, rather than their addresses – so remove the & from the arguments in your printf calls. (Also, and I assume it's a typo, the price[3] expression should be price[i] – the former attempts to access an out-of-bounds element of the price array.)
Another issue is that, in each of your input loops, you call the scanf function before you display the relevant prompt. In the code below, I have reversed your printf and scanf lines in each of those input loops.
Here's a possible fixed version:
#include<stdio.h>
int main()
{
char name[3];
float price[3];
int i, page[3];
printf("enter the name price and book\n");
for (i = 0; i < 3; i++) {
printf("enter character:\n");
scanf(" %c", &name[i]);
}
for (i = 0; i < 3; i++) {
printf("enter floating point number:\n");
scanf("%f", &price[i]);
}
for (i = 0; i < 3; i++) {
printf("enter digit:\n");
scanf("%d", &page[i]);
}
printf("\n");
for (i = 0; i < 3; i++) {
printf("%c\n", name[i]);
}
for (i = 0; i < 3; i++) {
printf("%f\n", price[i]);
}
for (i = 0; i < 3; i++) {
printf("%d\n", page[i]);
}
return 0;
}

Storing Integers in an Char Array in C

Im doing some work for Uni and wrote a programm which stores Integers in an char Array and converts them to their ASCII Values and prints them at the end. My code did not work before and only started working when i changed "%c" to "%i" in my scanf line. My question: Why does it have to be "%i" when i wanna store those Numbers in an char Array and not an Int Array. Thanks!
My code:
#include <stdio.h>
int main()
{
int i; /counter
char numbers[12];
printf("Please enter 12 Numbers\n");
for(i = 0; i < 12; i++){
printf("please enter the %i. Number\n", i+1);
scanf("%i", &numbers[i]);// <-- changed "%c" to "%i" and it worked.why?
}
for(i = 0; i < 12;i++){
printf("The %i.ASCII value is %i and has the Char %c\n", i+1, numbers[i], numbers[i]);
}
return 0;
}
%c is for reading a single character. So for example if you type in "123", scanf will read '1' into the char variable and leaves the rest in the buffer.
On the other side %i is the specifier for int and will therefore lead to undefined behavior when trying to read in a char.
I think what you are looking for is the %hhi specifier, which reads a number into a char variable.

fgets() doesn't function as expected [duplicate]

This question already has answers here:
fgets doesn't work after scanf [duplicate]
(7 answers)
scanf() leaves the newline character in the buffer
(7 answers)
Closed 5 years ago.
This is my code
int main(){
int N,i,radius,diameter,count =0;
char str[20];
char color[N][20];
printf("Get the num : ");
scanf("%d",&N);
printf("Enter the mesage\n");
for(i=0;i<N;i++){
fgets(color[i],20,stdin);
}
for(i=0;i<N;i++){
printf("%s",color[i]);
}
return 0;
}
Given inputs are:
N = 3
red 50,
50 green,
blue 50
Here the problem is fgets inside for loop gets executed only twice if N is 3. This problem doesn't arise if I comment the scanf statement. Can somebody explain me what is causing this problem and how it can be solved?
After a few hours of scratching my head, I realized the following:
Avoid using scanf. Managing buffer overflows is not easy.
Always try to use fgets to get user inputs.
Try this code here:
#include<stdio.h>
#include<stdlib.h>
int main(){
int N,i,radius,diameter,count =0;
char str[20];
printf("Get the num : ");
char buffer[64];
fgets(buffer, 64, stdin);
N = strtoul(buffer,NULL,10);
char color[N][20];
printf("%d\n",sizeof(color));
printf("Enter the mesage\n");
for(i=0;i<N;i++){
fgets(color[i],20,stdin);
if(color[i][strlen(color[i])-1]=='\n'){
color[i][strlen(color[i])-1]='\0';
}
else{
while((getchar())!='\n');//this is just to prevent an overflow for the size of char arrays
}
}
for(i=0;i<N;i++){
printf("%s\n",color[i]);
}
return 0;
}
Notice that I first input a number inside a char array. Convert that into a number using strtoul(string to unsigned long). Now inside the for loop I again use fgets to take inputs. The problem was, if you enter a string greater than 19 chars, the remaining part will be left inside the input buffer and shall be assigned to the subsequent input. To manage that I used getchar inside a while loop, which consumes all the unnecessary characters and the newline character from the input stream. Avoid using fflush as it may result in undefined behavior as answered here
-fflush(stdin) function does not work
-http://www.geeksforgeeks.org/clearing-the-input-buffer-in-cc/
Also note that you are using Variable Length Arrays which may not always be a good choice. Older versions of c compiler prohibit them. You had declared color[N][20] first before initializing N. That was wrong.
I suggest you to read this too
-C - scanf() vs gets() vs fgets()
After using scanf you'd need to clean the buffer. I suggest to never use scanf, just use fgets and then convert the output to a number:
int main(){
int N,i,radius,diameter,count =0;
char str[20];
char color[N][20];
printf("Get the num : ");
char buffer[64];
fgets(buffer, 64, stdin);
N = atoi(buffer); // you need to include stdlib.h
printf("Enter the mesage\n");
for(i=0;i<N;i++){
fgets(color[i],20,stdin);
}
for(i=0;i<N;i++){
printf("%s",color[i]);
}
return 0;
}
Due to this reference:
https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm
this will be correct:
int _tmain(int argc, _TCHAR* argv[])
{
int N, i, radius, diameter, count = 0;
char str[10];
char color[20];
printf("Get the num : ");
scanf_s("%d", &N);
printf("Enter the mesage\n");
//for (i = 0; i<N; i++){
fgets(color, 20, stdin);
//}
//for (i = 0; i<N; i++){
printf("%s", color);
//}
return 0;
}
I changed scanf to scanf_s for VC++.

C for loop iteration

I have a problem writing code which does the following: declare a struct{char c; int x; } array and load it with scanf via a loop. After it's loaded, a call to function f will be made which will replace every occurrence of digits in the struct's component c with 0, and will return the sum of the digits replaced by zero.
Code and output are below and I have problem that the loop in the function f seems to iterate one time, and it gives out some really weird values.
This is an exam question so I have to use printf, scanf etc. Also I have that exam in an hour so any quick help is appreciated :)
CODE:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 2
struct par {
char c;
int x;
};
int f(struct par *niz) {
int i;
int n=0;
for(i=0; i<MAX; i++) {
if(isdigit(niz[i].c)) {
niz[i].c = niz[i].c-'0';
printf("niz[i].c = %d\n i = %d", niz[i].c, i);
n=n+niz[i].c;
niz[i].c='0';
}
}
return n;
}
void main() {
int n;
int i;
struct par niz[MAX];
printf("enter\n");
for(i=0; i<MAX; i++) {
scanf("%c", &niz[i].c);
scanf("%d", &niz[i].x);
}
n=f(niz);
for(int i=0; i<MAX; i++) {
printf("%d\n", niz[i].c);
printf("%d\n", niz[i].x);
}
printf("n = %d\n", n);
}
OUTPUT:
enter
2
2
2
niz[i].c = 2
i = 048
2
10
2
n = 2
When you press enter after the first input, the newline is not scanned by scanf and is left in the input buffer. When you then try to read the number scanf sees the newline and not a number so doesn't scan anything.
The simple solution to that is to add a leading space in front of the formats:
scanf(" %c", &niz[i].c);
scanf(" %d", &niz[i].x);
/* ^ */
This tells scanf to skip whitespace.
Use
niz[i].c = getchar();
instead of
scanf("%c", &niz[i].c);
or, you can use other better methods for getting char input discussed at SO,
Now,
You see second time you provided input only once, that is because the Enter you pressed after giving 2 as input to first char remained in input buffer, and was read on second iteration.
You are getting 10 as output, because, it is ASCII for \r, the Enter. It is not a digit, so not replaced to be '0'.
I am looking at your code (i am not using console for a decade, but ) here are some insights:
try to rename MAX with something else
do not know your IDE but sometimes MAX is reserved
and using it as macro can cause problems on some compilers
change scanf("%c", &niz[i].c) to scanf("%c", &(niz[i].c))
just to be shore that correct adsress is send to scanf
change scanf("%d", &niz[i].x) to scanf("%i", &(niz[i].x))
change "%d" to the correct value (this is main your problem)
"%c" for char
"%i" for int
Try to trace line by line and watch for improper variables change if above points does not help
weird values?
because you forgot "\n" after the line, so next print is behind the line "i = %d".
And, check return value of every function except ones that return void.

Inputting array in C

Basically I have a C program where the user inputs a number (eg. 4). What that is defining is the number of integers that will go into an array (maximum of 10). However I want the user to be able to input them as "1 5 2 6" (for example). I.e. as a white space delimited list.
So far:
#include<stdio.h>;
int main()
{
int no, *noArray[10];
printf("Enter no. of variables for array");
scanf("%d", &no);
printf("Enter the %d values of the array", no);
//this is where I want the scanf to be generated automatically. eg:
scanf("%d %d %d %d", noArray[0], noArray[1], noArray[2], noArray[3]);
return 0;
}
Not sure how I might do this?
Thanks
scanf automatically consumes any whitespace that comes before the format specifier/percentage sign (except in the case of %c, which consumes one character at a time, including whitespace). This means that a line like:
scanf("%d", &no);
actually reads and ignores all the whitespace before the integer you want to read. So you can easily read an arbitrary number of integers separated by whitespace using a for loop:
for(int i = 0; i < no; i++) {
scanf("%d", &noArray[i]);
}
Note that noArray should be an array of ints and you need to pass the address of each element to scanf, as mentioned above. Also you shouldn't have a semicolon after your #include statement. The compiler should give you a warning if not an error for that.
#include <stdio.h>
int main(int argc,char *argv[])
{
int no,noArray[10];
int i = 0;
scanf("%d",&no);
while(no > 10)
{
printf("The no must be smaller than 10,please input again\n");
scanf("%d",&no);
}
for(i = 0;i < no;i++)
{
scanf("%d",&noArray[i]);
}
return 0;
}
You can try it like this.

Resources