C program with two dimensional arrays? - c

in a two dimensional array there are kept the working hours for N workers and M projects,the names of the workers are kept in an array with the name Worker and the name of the projects in an array with the name "Project".Write a program which reads the data and displays the worker with more working hours.So I tried this,but everytime I ran it,it seems to be a logical error,because it says :Give the number of the project,and If I type "2" this is also the number of the workers according to my program,and then it asks for the hours for each worker..
#include<stdio.h>
#include<conio.h>
int main()
{
int i, j, n, worker[100][10], hours[30][100];
printf("The number of the project: ");
scanf("%d", &n);
for (i=0; i<n; i++)
{
printf("Give the worker %d: ", i+1);
scanf("%s", &worker[i]);
}
for (i=0; i<n; i++)
{
printf("\n The worker %s\n", worker[i]);
for (j=0; j<30; j++)
{
printf("The number of the hours for the day %d: ", j+1);
scanf("%d", &hours[i][j]);
}
}
for (i=0; i<n; i++)
{
for (j=0; j<30; j++)
if (hours[i][j]==0)
break;
if (j==30)
printf("%s\n", worker[i]);
}
getch();
return 0;
}

You seem to be taking the input incorrectly.
scanf("%s", &worker[i]);
worker is a 2D array of type int. So, you need to have another index while taking input. Also the format specifier for int is %d. Any decent compiler should have given you warnings during compilation.

Seems to me that you first must ask how many workers (N) and how many projects (M) with something like:
int ii, m, n;
char **worker;
char **project;
printf("How many workers? ");
scanf("%d", &n);
printf("How many projects? ");
scanf("%d", &m);
Then ask for the names of the workers:
// Allocate space for n worker string pointers
worker = (char **)malloc(n * sizeof(char *));
for (ii = 0; ii < n; ++ii)
{
char bufname[1024]; // danger here if input too long
printf("Name of worker[%d]? ", ii + 1);
scanf("%s", bufname);
worker[ii] = strdup(bufname);
}
Then ask for the names of the projects, similarly. Then get the hours, then calculate the max, then free up the dynamically allocated worker & project strings (and the two array of pointers).

Related

Having problems with 2D char arrays

So I've got an assignment where my program asks the brand (10 letters), model (10 letters), age (1986 - 2019) and cost (positive real number) of 10 cars and then wants the program to check which car is the oldest and to print out it's brand and model. I don't have a problem with the first part but with the second part.
The code is:
//First part
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define C 10
#define M 11
int main(void)
{
char brand[C][M];
char model[C][M];
int year[C];
float cost[C];
int i, len1, len2, min;
for(i=0; i<C; i++){
printf("Car %d\n", i+1);
do{
printf("Brand: ");
scanf("%s", brand[i]);
len1 = strlen(brand[i]);
} while(len1<0 || len1>10);
do{
printf("Model: ");
scanf("%s", model[i]);
len2 = strlen(model[i]);
} while(len2<0 || len2>10);
do{
printf("Year: ");
scanf("%d", &year[i]);
} while(year[i]<1986 || year[i]>2019);
do{
printf("Cost: ");
scanf("%d", &cost[i]);
} while(cost[i]<=0);
}
//Second part
year[0] = min;
for(i=0; i<10; i++)
if(year[i] < min){
min = year[i];
printf("\nThe oldest car is %s %s\n", brand[i], model[i]);
}
For some reason it either prints out gibberish in the place of brand[i] or if I lose the columns of the if statement prints out all the car brands and their models, where I only want the oldest one.
Aside from scanf not being recommended there are some problems with this code, first when you read the brand and model you do:
do{
printf("Brand: ");
scanf("%s", brand[i]);
len1 = strlen(brand[i]);
} while(len1<0 || len1>10);
The problem here is that you first write the string to brand[i] and then check if it's too long, but you have already written it into the array so if the string is longer than your space you already have a buffer overflow. Limit the size you can read with scanf using scanf("%10s, brand[i]) or better yet use fgets(brand[i], sizeof(brand[i]), stdin).
Next in the second part you use min without initializing it, and you overwrite the content of year[0] with it. You probably wanted something like:
min = 2020; // or a number that will be bigger than all your cars anyway
int older = 0;
i = 0;
for(i=0; i<C; i++){ // Use C here, you have it might as well use it instead of magic numbers
if(year[i] < min){
older = i;
min = year[i];
}
}
printf("\nThe oldest car is %s %s\n", brand[older], model[older]);
but bare in mind that this solution will print multiple cars if they are the oldest ones and have the same year

C Program forLeast Square Regression Line and Errors

I wanted to create a program to calculate the regression line of some given data, along with the errors, so I can use in my university assignments. This is the following program:
#include <stdio.h>
#include <math.h>
int main(void)
{
int i,n,N;
double x[n],y[n],a=0.0,b=0.0,c=0.0,d=0.0,D,P=0.0,p,Sx,A,B,dA,dB;
printf("Give the number of data you want to input for x : ");
scanf("\n%d", &N);
printf("\nGive the values of x : ");
for (i=1; i<=N; i++);
{
printf("\n Enter x[%d] = ", i);
scanf("%lf", &x[i]);
a+=x[i];
b+=pow(x[i],2);
}
printf("\nGive the values of y : ");
for (i=1; i<=N; i++);
{
printf("\n Enter y[%d] = ", i);
scanf("%lf", &y[i]);
c+=y[i];
}
D=N*b-pow(a,2);
A=(b*c-a*d)/D;
B=(N*d-a*c)/D;
for (i=1; i<=N; i++);
{
d+=x[i]*y[i];
p=y[i]-A-B*x[i];
P+=pow(p,2);
}
Sx=sqrt(P/N-2);
dA=Sx*sqrt(b/D);
dB=Sx*sqrt(N/D);
printf("\n x \t \t \t y");
for (i=1; i<=N; i++);
printf("\nx[%d] = %lf\t%lf = y[%d]", x[i],y[i]);
printf("\nA = %lf\t B = %lf", A,B);
printf("\nThe errors of A & B are dA = %lf and dB = %lf", dA,dB);
printf("\nThe equation of the regression line is y=%lfx+(%lf)", B,A);
return 0;
}
I have two problems.
Despite giving a value to N, the program runs so that I can only give one value for x and one value for y. Why and where is the mistake?
When printing the "Enter x[%d]", it displays x[11] and at the end when printing "x[%d] = %lf\t%lf = y[%d]", it displays x[0]. Again why and where is the mistake?
Thank you for your help!
You are trying to create a dynamic array in C.
To do that, you need to use dynamic memory allocation with malloc and free. So, your code should look something like this:
int N;
double *x;
printf("Give the number of data you want to input for x :\n");
scanf("%d", &N);
x = malloc(sizeof(double) * N);
Then, at the end of your program you need to free the memory:
free(x);
If you don't want to deal with manual memory management (or can't for some reason), you can use a static maximum array size like this:
#define MAX_N_X 100
int main(void) {
int N;
double x[MAX_N_X];
printf("Give the number of data you want to input for x :\n");
scanf("%d", &N);
if (N > MAX_N_X) {
printf("Can't handle that many inputs! Maximum %d\n", MAX_N_X);
return 0;
}
}
You simply missed two parameters to printf.
Yo wrote:
printf("\nx[%d] = %lf\t%lf = y[%d]", x[i],y[i]);
But it should be:
printf("\nx[%d] = %lf\t%lf = y[%d]", i, x[i], y[i], i);
I found the main problem with this program a few days after posting this and the fix would be removing the ; from the for commands, along with some other minor changes. I thought I might add this comment to let you know and now it is working like a charm. The simplest of mistakes fools even the trained eyes. After I found this, I was shocked that no one picked up on this mistake.

C: Array of Structs (Input into int array within array of structs)

Hi I have to create a database that stores students number, name and also stores an array of course marks (1-N) in C Programming Language.
Everything worked until I started coding for the array of course marks. Then every time I compiled the code it kept crashing as soon as it asked to input the course marks.
Can you please tell me where I'm going wrong in my programming for this task? I have attached it to this message.
The program worked for inputting the name, student number, however I could not get the program to input array of marks. I have asked how many course marks to be entered and then used a for loop within the "void insert(void)" function to keep inputting the course marks into the array *marks. I am referring specifically to lines 24 to 30 in my programming code.
Always at this point the program kept crashing and I could not proceed further to enter more names or print the stored student details.
I think there is a problem with this part:
for (i= 0; i < num_marks; i++)
{
printf("Enter Course Mark: \n");
scanf("%d", &(list[num_students].marks[num_marks]));
}
Anyway here is the full code:
#include <stdio.h>
#include <string.h>
struct student{
int number;
char name[10];
int marks[5];
};
struct student list[10];
int num_students = 0;
int num_marks = 0;
int *p;
void insert(void)
{
int student_number;
int i;
printf("Enter number: \n");
scanf("%d", &list[num_students].number);
printf("Enter NAME: \n");
scanf("%s", &list[num_students].name);
printf("Enter NO of courses: \n");
scanf("%d", num_marks);
for (i= 0; i < num_marks; i++)
{
printf("Enter Course Mark: \n" );
scanf("%d", &(list[num_students].marks[num_marks]));
}
num_students++; // HOW DO WE INPUT ARRAY MARKS??? MARK1: , MARK2: , MARK3 ,
}
void printtest(void)
{
int i;
for (i=0; i < num_students; i++)
{
printf("Name: \n");
puts(list[i].name);
printf("Number: %d \n", list[i].number);
printf("Mark: %d /100 \n", list[i].marks);
printf("\n");
}
}
int main(void)
{
int code;
int opt1;
int courses, i, k, j, counter;
for (;;){
printf("Enter operation code: \n");
printf("(1) ADD NEW STUDENT DETAILS: \n");
printf("(2) DISPLAY REPORT OF ALL STUDENTS: \n");
scanf(" %d", &code);
switch (code){
case 1 :
insert();
break;
case 2 :
printtest();
break;
default:
printf("Illegal code\n");
printf("\n");
}
}
}
Apart from what others pointed out, I'd like to draw your attention towards the following:
void insert(void)
{
int student_number;
int i;
printf("Enter number: \n");
scanf("%d", &list[num_students].number);
printf("Enter NAME: \n");
scanf("%s", &list[num_students].name);
printf("Enter NO of courses: \n");
scanf("%d", num_marks);
for (i= 0; i < num_marks; i++)
{
printf("Enter Course Mark: \n" );
scanf("%d", &(list[num_students].marks[num_marks]));
}
num_students++;
}
void printtest(void)
{
int i;
for (i=0; i < num_students; i++)
{
printf("Name: \n");
puts(list[i].name);
printf("Number: %d \n", list[i].number);
printf("Mark: %d /100 \n", list[i].marks);
printf("\n");
}
}
There are three problematic statements:
scanf("%s", &list[num_students].name); This is why beginners should use compilers with all warnings enabled.
printf("Mark: %d /100 \n", list[i].marks); What did you declare marks as in the first place?
scanf("%d", num_marks); Seems like you put & operator where not needed and ignore where needed. Read your textbook before asking a question next time.
Seems like you're having a tough time understanding the concept of arrays and pointers. Read your text book thoroughly before venturing into the world of pointers. If you don't use them correctly, even compiler can't help you.
Also, even if I don't expect your program to have a robust input mechanism, at least array bounds checking is expected. Learn good habits from the beginning. They'll save a lot of your time while debugging later.
Seems to be an error in:
for (i= 0; i < num_marks; i++)
{
printf("Enter Course Mark: \n" );
scanf("%d", &(list[num_students].marks[num_marks]));
}
The crash is probably because num_marks as index indexes beyond the array. Change to:
for (i= 0; i < num_marks; i++)
{
printf("Enter Course Mark: \n" );
scanf("%d", &(list[num_students].marks[i]));
}

Small c programming help needed

I have this problem I've been trying to get this done for last 7 hours, but I'm not getting anywhere. I have tried many options but I seem to fail all time. I'd be delighted if someone helped me out with this so I could see where I'm going wrong. I have made small attempt but the further I go to worst I get. I'd be happy if someone gave me some guidance please. Here is what the program should be like.
I have to enter integer numbers only if it's a floating number than it should display an error and that I need to try again. The minimum amount of numbers are 10.
Once all the numbers are entered it should display what the percentage of the numbers are even numbers.
At any time i can exit the program by typing "exit"
int i;
for(i=1; i<=10; ++i)
printf("Enter 10 integers: ");
scanf("%d",&i);
printf("Enter the next integer or type exit to end the program: %d",i);
system("PAUSE");
return (printf);
Since you asked for guidance rather than a full working solution, here goes.
First you currently have
for(i=1; i<=10; ++i)
printf("Enter 10 integers: ");
scanf("%d",&i);
The for will just loop around the next line, unless you use braces, i.e. it will print "Enter..." 10 times:
for(i=1; i<=10; ++i)
printf("Enter 10 integers: ");
scanf("%d",&i);
It may help to get used to putting everything you want to loop (even a one-liner) in braces:
for(i=1; i<=10; ++i)
{
printf("Enter 10 integers: ");
scanf("%d",&i);
//...
}
Often people (with good reason) start at 0 in C:
for(i=0; i<10; ++i)
{
printf("Enter 10 integers: ");
scanf("%d",&i);
//...
}
If you structure your code like that it may help to pull out a get_valid_input function
for(i=0; i<10; ++i)
{
printf("Enter 10 integers: ");
get_valid_input(); //what do you intend to do with this?
//...
}
with
int get_valid_input()
{
int i;
scanf("%d",&i); //how do they type "exit"?
//..
}
This needs thought though - should it return an int?
You could then store them somewhere.
But you could keep track of percentage of even numbers as you go.
Also, at any time you can press "exit" (type in the string or press a key?) so you need to be able to indicate that.
Don't forget to print the result, once you have worked it out. (Left as an exercise for the reader)
int i, v, n=0, even;
int array[10] = {0};
char buff1[32], buff2[32];
printf("Enter 10 integers: \n");
for(i=1; i<=10; ++i){
printf("Enter the next integer or type exit to end the program %d:\n", i);
fgets(buff1, sizeof buff1, stdin);
strcpy(buff2, strtok(buff1, " \t\n"));//trim
if(strcmp(buff2, "exit")==0)
break;
if(1!=sscanf(buff2, "%d%s", &v, buff1)){
printf("invalid input\n");
--i;
continue;
}
array[n++] = v;
}
for(even=i=0;i<n;++i){
printf("%d ", array[i]);
if((array[i] & 1) == 0)
++even;
}
printf("\n");
if(n)
printf("Even proportions : %.1f%%\n", 100.0*even / n);
system("PAUSE");
return 0;

Reallocating memory and adding a string at the reallocated memory space in C

I am having trouble adding "records" at the end of a dynamically allocated string array. Before reallocating more memory for the records to be added, everything works fine, and then I basically replicate what I initially did but now with realloc. And after I am done inputting the added Records I get an error and I don't know how to go about adding records. NOTE* The posed code is really stripped down from the original. I've tried many things but to no avail, thanks for all the help in advance.
#include <stdio.h>
#include <stdlib.h>
#define STRINGSIZE 21
void addRecords( char **Names, int classSize);
int main(){
char **Names;
int classSize, i;
//User will be able to choose how many records he woudld like to input.
printf("Please indicate number of records you want to enter:\n");
scanf("%d", &classSize);
Names=malloc(classSize*sizeof(char*));
for (i=0; i<classSize; i++) {
Names[i]=malloc(STRINGSIZE*sizeof(char));
}
printf("Please input records of students (enter a new line after each record), with following format: first name....\n");
for (i=0; i<classSize; i++) {
scanf("%s", *(Names + i));
}
for (i=0; i<classSize; i++) {
printf("%s ", *(Names+i));
printf("\n\n");
}
addRecords(Names, classSize);
}
void addRecords(char **Names, int classSize){
int addition, i;
printf("How many records would you like to add?\n");
scanf("%d", &addition);
Names=realloc(Names, (classSize+addition)*sizeof(char*));
for (i=classSize; i<(classSize+addition); i++) {
Names[i]=malloc(STRINGSIZE*sizeof(char));
}
printf("Please input records of students (enter a new line after each record), with followingformat: first name....\n");
for (i=classSize; i<classSize+addition; i++) {
scanf("%s", *(Names + (classSize + i)));
}
printf("\n\n");
for (i=0; i<classSize+addition; i++) {
printf("%s ", *(Names+i));
}
printf("\n\n");
}
You are writing out of the bounds of the array:
for (i=classSize; i<classSize+addition; i++) {
scanf("%s", *(Names + (classSize + i)));
change to
for (i=classSize; i<classSize+addition; i++) {
scanf("%s", *(Names + i));
Note that Names[i] is more readable than *(Names + i)
First, your Names argument is passed by value to addRecords function, so you will be unable to observe the reallocation outside it (it may work if the reallocation does not give you a new address, but in general it does so).
Second, the loop in addRecords contains a mistake. You loop from classeSize up to classSize+addition and you use it in (Names + (classSize+i)). That should be either looping from 0 to addition or using it as Names + i.

Resources