I keep getting this error when I try to run a piece of code say that the variable is being used which isn't initialized, despite I've declared it.
{
FILE *fptr;
int length;
int number_search;
struct student
{
char surname[15];
char initials[6];
char title[4];
int student_number;
char module_name[25];
char module_code[7];
int assesment_mark;
int exam_mark;
int tuition_fee;
};
struct student record_student;
struct student *student_ptr;
student_ptr=&record_student;
length=sizeof(struct student);
printf("2 has been called\n");
printf("Enter module code: \n");
scanf("%s", module_code);
clear_buffer(module_code);
printf("%s\n",module_code); /*Test the string entered is 6 charaters, AB1234 format*/
if (! modcheck(module_code)) /*Change this fucntion to a differnt one to check correct format*/
{
printf("Invalid input\n");
}
else
{
printf("input ok\n");
printf("Enter Student Number: \n");
scanf("%d",number_search);
}
it's saying that the int number_search isn't being initialized despite it being in the code above.
Change:
scanf("%d",number_search);
to
scanf("%d", &number_search);
//^See here the address operator
Indeed, number_search is not initialized.
And your call to scanf(3) is wrong. It should be
scanf("%d", &number_search);
and even with that correction, number_search is still uninitialized: scanf can fail (e.g. if your user types hello or Ctrl D on Linux) and you should test the result of scanf (number of successfully read items), at least:
if (scanf("%d", &number_search) != 1) {
perror("number_search input failure"); exit(EXIT_FAILURE);
}
I believe that you should always explicitly initialize local variables (if that initialization happens to become useless, the compiler would optimize it out), like
int number_search = 0;
PS. You should compile with all warnings and debug info, e.g. gcc -Wall -Wextra -g; once you are sure of not having bugs, add -O2 to get optimizations.
printf("Enter module code: \n");
scanf("%s", module_code);
This should be
printf("Enter module code: \n");
scanf("%s", student_ptr->module_code);
and
scanf("%d", &number_search);
Scan to the address of the variable which is given by &number_search
Related
This code grabs input from users, and first, to ensure they have entered the correct type of input, I let the function print out the menu on the screen and then scanf() the user input. It should be very straight forward code, but I keep getting errors and warnings which I don't understand, can someone plesae help me with this?
(I am still in the process of getting used to code in C.)
//include library
#include<stdio.h>
#include<string.h>
//variable declaration
int age,userInputOption,ptr_InputCk;
char name[20];
float point;
//Fuction prototype
void displayMenu();
void wrongInput();
char getTheName(char name[20]);
void optionSwitch();
int getTheAge(int age);
float getThePoint(float point);
//void clearData(char name, int age, float point);
int quitTheProgram();
void displayKnownData();
//main function
int main() {
displayMenu();
ptr_InputCk = scanf("%d", &userInputOption);
if (ptr_InputCk != 1) {
wrongInput();
displayMenu();
}
else if (userInputOption >=1 || userInputOption <=5) {
optionSwitch();
}
else if(userInputOption == 6) {
quitTheProgram();
}
return (0);
}
//Define Functions
void displayMenu() {
printf("1. enter a name: \n\n");
printf("2. enter an age: \n\n");
printf("3. enter the person’s points per game: \n\n");
printf("4. display the known data: \n\n");
printf("5. clear all data: \n\n");
printf("6. quit: \n\n");
printf("Please enter a number between 1 ~ 6:\n\n");
}
void wrongInput() {
printf("Wrong input, please re-enter");
}
void optionSwitch() {
switch (userInputOption) {
case 1:
getTheName(name);
break;
case 2:
getTheAge(age);
break;
case 3:
getThePoint(point);
break;
case 4:
displayKnownData();
break;
//case 5:
//clearData(name,age,point);
//break;
case 6:
quitTheProgram();
break;
}
}
char getTheName(char name[20]) {
printf("Please enter your name: \n");
scanf("%s", &name);
printf("You name: %s\n", name);
return (name[20]);
}
int getTheAge(int age) {
printf("Please enter your age: \n");
scanf("%d", &age);
printf("Your age: %d\n", age);
return (age);
}
float getThePoint(float point) {
printf("Please enter points: \n");
scanf("%f", &point);
printf("Your age: %f\n", point);
return (point);
}
/*/
void clearData() {
char* name = NULL;
int* age = NULL;
float* point = NULL;
return(name, age, point);
}*/
int quitTheProgram() {
_exit(0);
}
void displayKnownData() {
printf("name: %s\nage: %d\npoint: %f\n", name, age, point);
}
I would like to add that using scanf the way you did to fill a string isn't secure because you can easily overflow your buffer (char name[20]) if the user enters more than 19 characters.
Other solutions:
#include <stdio.h>
#define MAX_LIMIT 20
int main()
{
char str[MAX_LIMIT];
fgets(str, MAX_LIMIT, stdin);
printf("%s", str);
return 0;
}
Or
(...)
puts ("Please enter a string of 20 characters or fewer.");
scanf ("%20s", string1);
C4013 - _exit(0) does not exist in the declared libraries, if you were working on linux you'd find it in unistd.h.
Since you're working with msvc, apparenty you have such function declared on process.h (don´t quote me on that), I would, however, prefer to use the more appropriate exit(0) (or alternatively _Exit(0)), you should find these in stdlib.h, you need to include it in your file's headers.
C4477/C6067 - name is already a pointer, you need not to use the & operator:
scanf("%19s", name); // Be sure to include a width specifier to avoid buffer oferflow
C4996 - msvc does not like scanf at all, you can either:
1 - Use scanf_s as it tells you to (there are also some corrections I would make to the function itself as commented bellow):
void getTheName(char* name, size_t size) { // void return type
//buffer size for scanf_s
printf("Please enter your name: \n");
scanf_s("%s", name, size); //<---
printf("Your name: %s\n", name);
//no return needed, the input gets stored on the memory pointed by name
}
(Since name is global you could use sizeof(name) for buffer size, but I would advise you to make it local to its necessary scope, globals can get out of hand fast. The advice extends to all of your global variables, none of them seems to need to be global in your code.)
2 - Alternatively you could suppress that specific error, you can see how to do it here:
Why does Visual Studio 2013 error on C4996?
The safest bet, however, would be to use a better compiler if possible, for example gcc or clang, both can be used with Visual Studio.
C6031 - It complains about the lack of verification of scanf return value, and that's good advice, the function returns the number of read elements, in this case it shoud return 1, so you could use, for example:
if(scanf("%19s", name) != 1){
//handle error
}
//otherwise continue normal execution
This would make sure it works as expected.
The error C4566 is about character encoding, I suspect it may be a false positive or related to your encoding settings, anyway, fix the other problems and see if it still happens. You can then post a more specific question, if it remains.
Final notes - By clicking on the errors you'll navigate to the Microsoft docs of the respective error, that may help you understand the issue. Granted it's not always ver helpful. I would also advise, in the future, to post the errors as text, it's easier for users who want to help to find a possible solution by making research easier.
I wanted to create a program in c that reads the student name, roll number, marks of 3 subjects. when I run the program it is showing no errors, but the problem is whenever I try to input information it is taking only 2 inputs. Anyone please check the program and state the error in my program.
#include <stdio.h>
struct student
{
char sname[20];
int srollno;
int smarks[3];
};
int main ()
{
struct student e[3];
int i,j;
for (i=0;i<=2;i++)
{
scanf ("%s",e[i].sname);
scanf ("%d",e[i].srollno);
for (j=0;j<=2;j++)
{
scanf ("%d",e[i].smarks[j]);
}
}
}
it is taking only two inputs.
you have some problem in your scanf.
Try this:
scanf("%s",&e[i].sname);
I perform some little change on your code.
This is working version of code.
Code
#include <stdio.h>
struct student
{
char sname[20];
int srollno;
int smarks[3];
};
int main ()
{
struct student e[3];
int i,j;
for (i=0;i<=2;i++)
{
printf("Name: ");
scanf("%s", e[i].sname);
printf("roolNumber: ");
scanf("%d", &e[i].srollno);
for (j=0;j<=2;j++)
{
printf("Mark %d: ",j);
scanf("%d", &e[i].smarks[j]);
}
}
printf("\n\nprinting \n\n");
for (i=0;i<=2;i++)
{
printf("Name: %s\n", e[i].sname);
printf("roolNumber: %d\n", e[i].srollno);
for (j=0;j<=2;j++)
{
printf("Mark: %d\n", e[i].smarks[j]);
}
printf("\n");
}
}
Compile and Run
gcc -Wall source.c -o source
./source
I suggest to use printf() before try to scanf(), this makes User Interface better.
scanf() char array don't need & (address) operator. see this
char str[10];
scanf("%s", str);
printf("%s\n", str);
Work exactly like
char str[10];
scanf("%s", &str[0]);
printf("%s\n", str);
Because str is pointer to its first elementstr[0]. As stated in link we can write printf("%d\n", str==&str[0]); and always the result is one that show str and &str[0] are identical.
After I execute the exe I get this error :
undefined reference to `StudentScan'
error: ld returned 1 exit status|
Note: I'm bad and new to coding so don't mind my bad coding please^^
Note2: I'm just messing with random functions.
#include <stdio.h>
#include <stdlib.h>
struct student {
char firstName[20];
char AverageNum[2];
};
void StudentScan(int, struct student[]);
void StudentPrint(int, struct student[]);
int main() {
int i;
int length;
struct student *studentp;
printf ("\nEnter the host of students: ");
scanf ("%d ", &length);
struct student list[length];
studentp=malloc(length*sizeof(struct student));
if (studentp==NULL)
{
printf("Out of memory!");
return 0;
}
for(i = 0; i < length; i++) {
StudentScan(i,studentp);
printf("\nEnter average number: ");
scanf("%s", list[i].AverageNum);
}
free (studentp);
void StudentScan(int i, struct student list[])
{ printf("\nEnter first name : ");
scanf("%s", list[i].firstName);
printf("\nEnter average number: ");
scanf("%s", list[i].AverageNum);
}
return 0;
}
The posted code has defined StudentScan() within main(). But nested function definitions are not allowed in C. This should generate a compiler warning, such as:
warning: ISO C forbids nested functions [-Wpedantic]
void StudentScan(int i, struct student list[])
Pay attention to all compiler warnings and fix them. If no warning is seen when compiling this code, turn up the level of compiler warnings. On gcc, I suggest to always use at least gcc -Wall -Wextra, and I always add -Wpedantic. The -Wpedantic is needed with gcc to see a warning for this. Some compilers, and gcc is one of these, do support nested function definitions as a compiler extension. Still, this feature is nonstandard, and it is best to not rely on it.
The fix is simple: move the definition of StudentScan() out of main():
#include <stdio.h>
#include <stdlib.h>
struct student {
char firstName[20];
char AverageNum[2];
};
void StudentScan(int, struct student[]);
void StudentPrint(int, struct student[]);
int main(void) {
int i;
int length;
struct student *studentp;
printf ("\nEnter the host of students: ");
scanf ("%d ", &length);
struct student list[length];
studentp=malloc(length*sizeof(struct student));
if (studentp==NULL)
{
printf("Out of memory!");
return 0;
}
for(i = 0; i < length; i++) {
StudentScan(i,studentp);
printf("\nEnter average number: ");
scanf("%s", list[i].AverageNum);
}
free (studentp);
return 0;
}
void StudentScan(int i, struct student list[])
{ printf("\nEnter first name : ");
scanf("%s", list[i].firstName);
printf("\nEnter average number: ");
scanf("%s", list[i].AverageNum);
}
Also note that you should always specify maximum widths when reading strings using scanf() family functions with %s or %[] to avoid buffer overflow. For example:
scanf("%19s", list[i].firstName);
Note that 19 is used, even though the firstName field is an array of 20 char values. Remember that one space must be reserved for the \0 terminator. And since you are using %s to read a string into the AverageNum field, you should also have:
scanf("%1s", list[i].AverageNum);
That is, this field can only hold one digit. If the intention is to hold two digits, this field must be changed within the struct to: char AverageNum[3].
And while we are discussing scanf(), note that this function returns the number of successful assignments made during the function call. If no assignments are made, 0 is returned. This return value should always be checked. Consider: if the user mistakenly enters a letter when a digit is expected, nothing is stored in the intended variable. This may lead to undefined behavior. You may try something like this to validate numeric input:
printf ("\nEnter the host of students: ");
while (scanf ("%d ", &length) < 1) {
puts("Please enter a number");
int c;
while ((c = getchar()) != '\n' && c != EOF) {
continue;
}
}
This code asks the user to enter input again if a number is not entered when expected. Note that if the user does enter a non-digit, this character remains in the input stream and must be cleared before attempting to process more user input. The while loop is a typical construction which accomplishes this task.
Edit
Based on comments made by the OP, here is a modified version of the posted code. This version uses a float value instead of a character array for the AverageNum field of the struct. A floating-point type may be more useful than an integer type for storing averages. It is usually best to use double for floating-point values, but in this case it looks like AverageNum has little need for precision (the char array was intended to hold only two digits); float is probably sufficient for this use. If a different type is desired, it is simple enough to modify the code below.
Some input validation is implemented, but note that more could be done. The user is prompted to enter a number when non-numeric input is found where numeric input is expected. The input stream is cleaned with the while loop construction after such an input mistake; it would be good to remove this code to a separate function called clear_input(), for example.
If the user signals end-of-file from the keyboard, scanf() will return EOF; the code below chooses to exit with an error message rather than continue with malformed input in this case. This could also occur with input redirected from a file, and this condition may need to be handled differently if such input is expected.
The loop that populated the list[] array seemed to be operating inefficiently, asking for AverageNum twice in each pass. This has been streamlined.
Note that the call to malloc() can be rewritten as:
studentp = malloc(length * sizeof *studentp);
This is a very idiomatic way of writing such an allocation. Here, instead of using an explicit type as the operand of sizeof, that is, instead of sizeof (struct student), the variable which holds the address of the allocation is used. sizeof only uses the type of the expression *studentp, so this variable is not dereferenced here. Coding this way is less error-prone and easier to maintain when types change during the maintenance life of the code.
Yet, it is unclear why memory is allocated for studentp in the first place. In the posted code, both the firstName and AverageNum fields are filled for members of the dynamically allocated studentp in calls to StudentScan() in a loop; the same loop fills the AverageNum field of the members of list[] (a different array of structs) with different input. There seems to be no need for one of these arrays of student structs; I have commented-out the dynamically allocated array in favor of the statically allocated version.
Here is the modified code:
#include <stdio.h>
#include <stdlib.h>
struct student {
char firstName[20];
float AverageNum;
};
void StudentScan(int, struct student[]);
void StudentPrint(int, struct student[]);
int main(void) {
int i;
int length;
// struct student *studentp;
printf ("\nEnter the host of students: ");
while (scanf ("%d", &length) < 1) {
puts("Please enter a number");
int c;
while ((c = getchar()) != '\n' && c != EOF) {
continue;
}
}
struct student list[length];
/* This is fine */
// studentp = malloc(length * sizeof (struct student));
/* But this is better */
// studentp = malloc(length * sizeof *studentp);
// if (studentp == NULL)
// {
/* Not wrong, but... */
// printf("Out of memory!");
// return 0;
// fprintf(stderr, "Allocation failure\n");
// exit(EXIT_FAILURE);
// }
for(i = 0; i < length; i++) {
StudentScan(i, list);
}
/* Code to display results here */
// free (studentp);
return 0;
}
void StudentScan(int i, struct student list[])
{
putchar('\n');
printf("Enter first name: ");
if (scanf("%19s", list[i].firstName) != 1) {
puts("Input error");
exit(EXIT_FAILURE);
}
printf("Enter average number: ");
while (scanf("%f", &list[i].AverageNum) < 1) {
puts("Please enter a number");
int c;
while ((c = getchar()) != '\n' && c != EOF) {
continue;
}
}
}
You have to remove the scan function from the main. Also there is not a printstudent function you are declaring. You must remove /n from the printf and the scanf functions and place them accordingly. You can then test if your data are being added correctly in your struct with a simple loop.
#include <stdio.h>
#include <stdlib.h>
struct student {
char firstName[20];
char AverageNum[2];
};
int main() {
int i=0;
int length;
struct student *studentp;
printf ("Enter the host of students:");
scanf ("%d", &length);
struct student list[length];
studentp=malloc(length*sizeof(struct student));
if (studentp==NULL)
{
printf("Out of memory!");
return 0;
}
for(i = 0; i < length; i++) {
printf("Enter first name :");
scanf("%s", list[i].firstName);
printf("Enter average number: ");
scanf("%1s", list[i].AverageNum);
}
for(i = 0; i< length; i++){
printf("number of host is: %d , his/her first name: %s , his/her avg number: %s \n", i, list[i].firstName, list[i].AverageNum);
}
free (studentp);
return 0;
}
I am new to C and have been trying to get this simple code run which makes use of pointers to struct for calculating the average of grades entered. After entering the maths grade, the program throws an error and stops. What am I doing wrong.
Its also my first post in here, so please bear with me for any inconsistencies. Thanks!
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
char *name;
int mathGrade,scienceGrade,historyGrade,englishGrade;
}reportCard;
void average(reportCard *rc)
{
int avg = (rc->mathGrade +rc->scienceGrade+rc->historyGrade+rc->englishGrade)/4;
printf("The overall grade of %s is: %i ",rc->name, avg);
}
int main()
{
reportCard rc;
printf("Enter the Students Last name: ");
char studentName[20];
scanf("%s", studentName);
rc.name=studentName;
printf("Math Grade: \n");
scanf("%i", rc.mathGrade);
printf("Science Grade: \n");
scanf("%i", rc.scienceGrade);
printf("History Grade: \n");
scanf("%i", rc.historyGrade);
printf("English Grade: \n");
scanf("%i", rc.englishGrade);
average(&rc);
return 0;
}
You get an error because reading primitives with scanf requires pointers:
scanf("%i", &rc.mathGrade);
scanf("%i", &rc.scienceGrade);
// ^
// |
// Here
// ...and so on
scanf thinks that an uninitialized int that you pass is a pointer, and tries to write it, which results in an error.
In addition, you need to protect against buffer overruns on reading strings, like this:
scanf("%19s", studentName); // you allocated 20 chars; you need one for null terminator
struct subscriber
{
char phonenumber[20];
char name[50];
float amount;
}s;
void modifyrecords()
FILE *f;
char phonenumber[20];
long int size=sizeof(s);
if((f=fopen("c:/file.ojs","rb+"))==NULL)
exit(0);
system("cls");
printf("Enter phone number of the subscriber to modify:");
scanf("%[^\n]",phonenumber);
fflush(stdin);
while(fread(&s,sizeof(s),1,f)==1)
{
if(strcmp(s.phonenumber,phonenumber)==0)
{
system("cls");
printf("\n Enter phone number:");
scanf("%s",&s.phonenumber);
printf("\n Enter name: ");
fflush(stdin);
scanf("%[^\n]",&s.name);
printf("\n Enter amount: ");
scanf("%f",&s.amount);
fseek(f,-size,SEEK_CUR);
fwrite(&s,sizeof(s),1,f);
break;
}
}
fclose(f);
}
C:\Users***\Desktop\a.c|394|error: parameter 'size' is initialized|
I am getting parameter 'size' is initialized error in this code. After googling I found out I may have to pass certain arguments to suppress these kind of errors. Is this the only solution? Actually I am using Code::Blocks so if is the only way how do I pass command line arguments in it?
You have a simple syntax error here:
void modifyrecords()
should be:
void modifyrecords() {
Also, this:
scanf("%s",&s.phonenumber);
should be
scanf("%s",s.phonenumber);
And that applies to s.name as well.