Problems when making Array of struct and collate words - c

I just got an exercise of programming an array of struct of 2(or more) books with specified variables. Insert variables from keyboard and then find out if Publisher is "Kim Dong" then change the price of Book to 0.
Here is my code [I think something is wrong in collating step but cannot find out why :((]:
typedef struct book {
char *author[2000];
char *id[2000];
char *name[2000];
int *price;
char *publisher[2000];
} sach;
main()
{
int i;
sach Books[10];
for(i = 0; i < 2; i++)
{
printf("Nhap thong tin cua sach thu %d:\n", i+1);
fflush(stdin);
scanf("%s", &Books[i].name);
fflush(stdin);
scanf("%s", &Books[i].author);
fflush(stdin);
scanf("%s", &Books[i].id);
fflush(stdin);
scanf("%d", &Books[i].price);
fflush(stdin);
scanf("%s", &Books[i].publisher);
}
char NXB[8] ="KimDong";
for(i = 0; i < 2; i++)
{
int j = 0;
while( ((int)NXB[j]) == ((int)Books[i].publisher[j]) )
{
j++;
}
if(j == 6)
{
Books[i].price = 0;
}
}
for(i = 0; i < 2; i++)
{
printf("\nTen sach: %s", Books[i].name);
printf("\nID sach la: %s", Books[i].id);
printf("\nTac gia la: %s", Books[i].author);
printf("\nNXB la: %s", Books[i].publisher);
printf("\nGia sach la: %d", Books[i].price);
}
}
What's wrong?

Not sure what you actually want, but it's probably something like this:
#include <stdio.h>
typedef struct book {
char author[2000];
char id[2000];
char name[2000];
int price;
char publisher[2000];
}sach;
int main() {
int i;
sach Books[10];
for (i = 0; i<2; i++) {
printf("Nhap thong tin cua sach thu %d:\n", i + 1);
scanf("%s", &Books[i].name);
scanf("%s", &Books[i].author);
scanf("%s", &Books[i].id);
scanf("%d", &Books[i].price);
scanf("%s", &Books[i].publisher);
}
char NXB[8] = "KimDong";
for (i = 0; i<2; i++) {
int j = 0;
while ((NXB[j]) == (Books[i].publisher[j])) {
j++;
}
if (j == 6) {
Books[i].price = 0;
}
}
for (i = 0; i<2; i++) {
printf("\nTen sach: %s", Books[i].name);
printf("\nID sach la: %s", Books[i].id);
printf("\nTac gia la: %s", Books[i].author);
printf("\nNXB la: %s", Books[i].publisher);
printf("\nGia sach la: %d", Books[i].price);
}
}
fflush(stdin) is useless BTW.
The other answer concerning strcmp probably applies too here.
There is still room for improvement.

For string comparison use strcmp(str1,str2).
Note that if str1 is equal to str2, the return value will be 0. Contrary to the usual behavior of similar functions.

Related

swap strings function in c with pointers

When I try to swap between strings in the function Update_student it doesn't make it. Why?
#include <stdio.h>
#include <string.h>
#define SIZE 1
struct student {
int id_number;
char name[50];
char sex[6];
int quiz_score[2];
int total_score;
};
void Add_Student_Records(struct student *pupil) {
printf("ID:");
scanf("%d", &pupil->id_number);
printf("Name: ");
scanf("%s", &pupil->name);
printf("Sex :");
scanf("%s", &pupil->sex);
for (int i = 0; i < 2; i++) {
printf("Quit score %d:", i + 1);
scanf("%d", &pupil->quiz_score[i]);
}
pupil->total_score = pupil->quiz_score[0] + pupil->quiz_score[1];
return;
}
void Add_Students(struct student *students) {
for (int i = 0; i < SIZE; i++) {
printf("Student %d:\n", i + 1);
Add_Student_Records(students);
}
return;
}
void Print_Students(struct student *students) {
for (int i = 0; i < SIZE; i++) {
printf("Student %d details: \n", i + 1);
printf("ID:%d\n", students->id_number);
printf("Name:%s\n", students->name);
printf("Sex:%s\n", students->sex);
for (int i = 0; i < 2; i++) {
printf("Quit score %d:\n", students->quiz_score[i]);
}
printf("Total score: %d\n", students->total_score);
students++;
}
return;
}
void Replace_Strings(char **old_string, char **new_string) {
*old_string = *new_string;
return;
}
void Update_Student(struct student *students) {
int i = 0;
char name[50], new_name[50], cur_name[50];
printf("You can update name, and scores.\n");
printf(" current Name: ");
scanf("%s", name);
printf("new name: ");
scanf("%s", &new_name);
while (i < SIZE) {
strcpy(cur_name, students->name);
if (strcmp(cur_name, name) == 0) {
char *ptr_old_stud_name = students->name;
char *ptr_new_stud_name = new_name;
Replace_Strings(&ptr_old_stud_name, &ptr_new_stud_name);
}
i++;
students++;
}
return;
}
int main() {
struct student students[SIZE];
char ch;
/*1.Add student, 2. Print student*/
printf("1.Add student\n2.Print students\n3.Update student\n");
scanf("%c", &ch);
while (ch != 'E') {
if (ch == '1') {
Add_Students(&students[0]);
}
else if (ch == '2') {
Print_Students(&students[0]);
}
else if (ch =='3') {
Update_Student(&students[0]);
}
printf("Another operation:\t");
scanf("%c", &ch);
}
}
Replace_Strings(&ptr_old_stud_name,&ptr_new_stud_name); passes the addresses of ptr_old_stud_name and ptr_new_stud_name to ReplaceStrings.
ptr_old_stud_name and ptr_new_stud_name are local variables. The first is a pointer that has been set to point to students->name. The second is a pointer that has been set to point to new_name.
Replace_Strings changes the first thing it is passed a pointer to to the second thing it is passed a pointer to. So it changes ptr_old_stud_name to have the value of ptr_new_stud_name.
The result is that the local variable ptr_old_stud_name has a new value. This does not change the thing it points to, students->name.
More specifically, ptr_old_stud_name was pointing to the first character of students->name. students->name is an array, and it cannot be altered by changing pointers to it, and its address cannot be changed. To change its contents, you must copy new values into the bytes within it, which you could do by using strcpy to copy bytes into it from new_name.
Your function Update_student is confusing, you should just iterate through the array of students and compare the student's name with cur_name and replace the name when there is a match.
You should also pass the number of students to handle as an argument.
Here is a modified version:
void Update_Student(struct student *students, int count) {
char cur_name[50], new_name[50];
printf("You can update name, and scores.\n");
printf(" current Name: ");
scanf("%49s", cur_name);
printf("new name: ");
scanf("%49s", new_name);
for (int i = 0; i < count; i++) {
if (strcmp(cur_name, students[i].name) == 0) {
strcpy(students[i].name, new_name);
}
}
}
Call from main as Update_Student(students, SIZE);
Note also that you should ignore whitespace when reading the commands by adding a space before the %c:
scanf(" %c", &ch);
Here is a modified version with for multiple students:
#include <stdio.h>
#include <string.h>
#define SIZE 10
struct student {
int id_number;
char name[50];
char sex[6];
int quiz_score[2];
int total_score;
};
int Add_Student_Records(struct student *pupil) {
printf("ID:");
if (scanf("%d", &pupil->id_number) != 1)
return 0;
printf("Name: ");
if (scanf("%49s", pupil->name) != 1)
return 0;
printf("Sex :");
if (scanf("%1s", pupil->sex) != 1)
return 0;
for (int i = 0; i < 2; i++) {
printf("Quiz score %d:", i + 1);
if (scanf("%d", &pupil->quiz_score[i]) != 1)
return 0;
}
pupil->total_score = pupil->quiz_score[0] + pupil->quiz_score[1];
return 1;
}
int Add_Students(struct student *students, int count) {
int i;
for (int i = 0; i < count; i++) {
printf("Student %d:\n", i + 1);
if (Add_Student_Records(students + i) == 0)
break;
}
return i;
}
void Print_Students(struct student *students, int count) {
for (int i = 0; i < count; i++) {
printf("Student %d details: \n", i + 1);
printf("ID:%d\n", students->id_number);
printf("Name:%s\n", students->name);
printf("Sex:%s\n", students->sex);
for (int i = 0; i < 2; i++) {
printf("Quit score %d:\n", students->quiz_score[i]);
}
printf("Total score: %d\n", students->total_score);
students++;
}
}
void Update_Student(struct student *students, int count) {
char cur_name[50], new_name[50];
printf("You can update name, and scores.\n");
printf(" current Name: ");
if (scanf("%49s", cur_name) != 1)
return;
printf("new name: ");
if (scanf("%49s", new_name) != 1)
return;
for (int i = 0; i < count; i++) {
if (strcmp(cur_name, students[i].name) == 0) {
strcpy(students[i].name, new_name);
}
}
}
int main() {
struct student students[SIZE];
int n = 0;
char ch = 'E';
/* print the menu */
printf("1. Add student\n"
"2. Print students\n"
"3. Update student\n");
scanf(" %c", &ch);
while (ch != 'E') {
if (ch == '1') {
if (n == SIZE) {
printf("student array is full\n");
} else {
/* add more students */
n += Add_Students(&students[n], SIZE - n);
}
} else
if (ch == '2') {
Print_Students(students, n);
} else
if (ch =='3') {
Update_Student(students, n);
}
scanf("%*[^\n]"); // consume the rest of the pending input line
printf("Another operation:\t");
if (scanf(" %c", &ch) != 1)
break;
}
return 0;
}

How to printf all array in C Programming?

i was new with array for C programming. Anybody can help me? I want to print all array that saved from the assignment. Please help!
#include <stdio.h>
int main(){
const char *a[3];
char s[100];
int data, i=0;
back:
printf("Please insert name: ");
scanf(" %s", &s);
a[i] = s;
printf("Do you want to add data?: ");
scanf("%d", &data);
if (data==1){
i++;
goto back;}
else{
printf("%s", a[0] , a[1] , a[2]);}
return 0;
}
My suggestion would be never to use goto statement in C , it really mess up the readability of your source code. Also, go through this link, Why goto statement is not generally used.
Apart from this, you code can be simple re-written like this using for-loop statement.
#include <stdio.h>
int main(){
char *a[3];
char s[100];
int data = 1, i;
for(i=0; i<3 && data == 1; i++) {
printf("Please insert name: ");
scanf(" %s", &s);
a[i] = s;
printf("Do you want to add data?: ");
scanf("%d", &data);
}
for(i=0; i<3; i++)
printf("%s", a[i]);
return 0;
}
#include <stdio.h>
int main()
{
const char *a[3];
char s[100];
int data, i = 0, j;
back: printf("Please insert name: ");
scanf(" %s", &s);
a[i] = s;
printf("Do you want to add data?: ");
scanf("%d", &data);
i++;
if (data == 1)
{
goto back;
}
else
{
for (j = 0; j < i; j = j + 1)
printf("%s ", a[j]);
}
return 0;
}

assigning variable strings too an array with C

The goal of my code is to have the user, put in any amount of students as an integer and then have the program ask over and over to set a name too every integer (student)
I've been trying so many different things and I've been working on this without using any outside help for hours but I just couldn't figure this out. (if its something obvious, please don't get supermad, I'm only a beginner)
#include <cs50.h>
#include <string.h>
#include <stdio.h>
int main (void)
{
printf("How many students are there? ");
int amount = atoi(GetString());
printf("amount = %i\n", amount);
char *names[amount];
for(int i = 0; i < amount; i++)
{
printf("Enter the ellement #%d :", i +1);
scanf("%s", names[i]);
}
for (int i = 0; i == 0;)
{
printf("Acces student: ");
string search = GetString();
int searchnr = atoi(search);
printf("Student #%d is %s\n", searchnr, names[searchnr]);
}
}
>
}
The obvious solution:
for (int i = 0; i < amount; i++) {
printf("Enter element #%d: ", i + 1);
names[i] = GetString();
}
As to the second loop: it's an infinite loop. What is the terminating condition? You need to put that into the condition of the for loop else it will never terminate.
If your intent is getting an infinite loop, then a more readable, less confusing, more idiomatic solution is
while (1) {
// ...
}
or
for (;;) {
// ...
}
You need to reserve space for those strings:
char *names[amount];
char s[100];
for(int i = 0; i < amount; i++)
{
printf("Enter the ellement #%d :", i +1);
scanf("%s", s);
names[i] = strdup(s);
}
or
char *names[amount];
char s[100];
size_t len;
for(int i = 0; i < amount; i++)
{
printf("Enter the ellement #%d :", i +1);
scanf("%s", s);
len = strlen(s);
names[i] = malloc(len + 1);
strcpy(names[i], s);
}
And this for loop:
for (int i = 0; i == 0;)
does nothing, what do you want to do? (if you want to loop forever you can use for(;;))
Using malloc
char temp[50];
for(int i = 0; i < amount; i++)
{
printf("Enter the ellement #%d :", i +1);
scanf("%s", temp);
names[i]=malloc(strlen(temp)+1);
strcpy(names[i],temp);
}
Using strdup
char temp[50];
for(int i = 0; i < amount; i++)
{
printf("Enter the ellement #%d :", i +1);
scanf("%s", temp);
names[i] = strdup(temp);
}
All your answers were great guys, but this was the final solution:
#include <cs50.h>
#include <string.h>
#include <stdio.h>
int main (void)
{
printf("How many students are there? ");
int amount = atoi(GetString());
char *names[amount];
for(int i = 0; i < amount; i++)
{
printf("Enter the ellement #%d :", i +1);
names[i + 1] = GetString();
}
for (int i = 0; i == 0;)
{
printf("Acces student: ");
int search = atoi(GetString());
printf("Student #%d is %s\n", search, names[search]);
}
}
and I know I have an infinite loop there, that was just temporary so I don't have to rerun the command all the time.

program crashing using 2D dynamic string array in c

I am having a problem with this code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
int num=0;
printf("Enter number of entries: ");
scanf_s("%d", &num);
char **firstname=NULL;
char **lastname=NULL;
float *score=NULL;
int i;
firstname = malloc(num * (sizeof(char*)));
for (i = 0; i < num; i++)
{
firstname[i] = malloc(21);
}
lastname = malloc(num * (sizeof(char*)));
for (i = 0; i < num; i++)
{
lastname[i] = malloc(21);
}
score = ((float*)malloc(num* (sizeof(float))));
for (i = 1; i <= num; i++)
{
printf("Enter the first name of entry %d: \n", i);
scanf_s("%s", firstname[i], 21);
printf("Enter the last name of entry %d: \n", i);
scanf_s("%s", lastname[i], 21);
printf("Enter the score of entry %d: \n", i);
scanf_s("%f", score[i]);
}
for (i = 0; i < num; ++i)
{
printf("%s, %s, %f", firstname[i], lastname[i], score[i]);
}
return 0;
}
I have edited the code with the suggested changes, and now it prints random characters and a random value for the first and last name, as well as the score. the code also crashes if there is more than one iteration of input (after asking for the score of the first entry, it crashes before asking for the first name of the second entry.)

Reading in and recording a number in C

This is a homework problem. I have a C program that takes user input for a number of people's first names, last names, and ages. Right now it works and prints out the names to the console correctly, but it is not printing out the right ages, and I can't figure out what I'm doing wrong. Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int choice;
int i = 0;
int x,k,l;
fputs("How many people would you like to add? ", stdout);
scanf(" %d", &choice);
fflush(stdout);
int ch;
while((ch = getchar()) != EOF && ch != '\n');
if (ch == EOF)
{
}
char firstName[choice][20];
char lastName[choice][20];
int age[choice][3];
char first[20];
char last[20];
int a[3];
for (x = 0; x < choice; x++)
{
for (l = 0; l < 3; l++)
{
age[x][l] = 0;
a[l] = 0;
}
}
while(i < choice)
{
printf("Enter the first name of person ");
printf(" %d", i);
printf(": ");
fgets(first, 20, stdin);
for (k = 0; k < 20; k++)
{
firstName[i][k] = first[k];
}
i++;
}
i = 0;
while(i < choice)
{
printf("Enter the last name of person ");
printf(" %d", i);
printf(": ");
fgets(last, 20, stdin);
for (k = 0; k < 20; k++)
{
lastName[i][k] = last[k];
}
i++;
}
i = 0;
while(i < choice)
{
fputs("Enter the age of person ", stdout);
printf(" %d", i);
printf(": ");
scanf(" %d", &a);
fflush(stdout);
for (l = 0; l < 3; l++)
{
age[i][l] = a[l];
}
i++;
}
int sh;
while((sh = getchar()) != EOF && sh != '\n');
if (sh == EOF)
{
}
for (x = 0; x < choice; x++)
{
printf("First name ");
printf(": ");
printf("%s ", firstName[x]);
printf("\n");
printf("Last name ");
printf(": ");
printf("%s ", lastName[x]);
printf("\n");
printf("Age ");
printf(": ");
printf("%d ", &age[x]);
printf("\n");
}
return 0;
}
If you copy/paste this code it will run, but the age outputted will be incorrect. Can anyone tell me why this is? Thank you!
scanf(" %d", &a);
That should be:
scanf(" %d", &a[0]);
And the printf should be printf("%d", age[x][0]);
You want to read into the first element of the array, not the entire array. You want to print out the first element of the array, not the address of the array.
A better solution would probably be not to make age an array of 3 at all. Each person only has one age. The changes would be:
int age[choice];
int a;
scanf(" %d", &a);
age[choice] = a;
printf("%d ", age[x]);

Resources