Unable to print entire string after composing it from several partial strings - arrays

My code is unable to print the Full name, its just printing out the first name. I'm a little rookie in this. This is my output:
Here's the code
#include <stdio.h>
int main ()
{
int i, j, k;
char fName[15], mName[15], lName[15], name[45];
printf ("\nEnter the First name: ");
scanf ("%s", fName);
printf ("\nEnter the Middle name: ");
scanf ("%s", mName);
printf ("\nEnter the Last name: ");
scanf ("%s", lName);
for (i = 0; i < 15; i++) {
name[i] = fName[i];
if (fName[i] == '\0') {
i++;
break;
}
}
for (j = 0; j < 15; j++) {
name[i + j] = mName[j];
if (mName[j] == '\0') {
j++;
break;
}
}
for (k = 0; k < 15; k++) {
name[i + j + k] = lName[k];
if (lName[k] == '\0') {
k++;
break;
}
}
printf ("\nFull name is %s.", name);
return 0;
}

Break out of the copy loop when encountering a '\0' char. In your code, the '\0' is being copied to the output, which is then being interpreted as the end of string, and in your case at the end of the first name. However, for the last name, you need to include the \0 char.
#include <stdio.h>
int main()
{
int i, j, k;
char fName[15], mName[15], lName[15], name[45];
printf("\nEnter the First name: ");
scanf("%s", fName);
printf("\nEnter the Middle name: ");
scanf("%s", mName);
printf("\nEnter the Last name: ");
scanf("%s", lName);
for (i = 0; i < 15; i++)
{
if (fName[i] == '\0')
{
i++;
break;
}
name[i] = fName[i];
}
for (j = 0; j < 15; j++)
{
if (mName[j] == '\0')
{
j++;
break;
}
name[i + j] = mName[j];
}
for (k = 0; k < 15; k++)
{
name[i + j + k] = lName[k];
if (lName[k] == '\0')
{
k++;
break;
}
}
printf("\nFull name is %s.", name);
return 0;
}

In your code, you copy the null terminator of each string into the name array, hence the final contents is "Alexander\0Graham\0Bell". printf stops at the first null byte it finds in the string argument for %s so only the first name is output.
You should instead use a separate index for the source and destination arrays and set a space between the 3 parts of the name.
Note also that you should tell scanf() to stop reading after 14 bytes to avoid storing characters beyond the end of the arrays on overlong user input and test the return value to detect invalid input.
Here is a modified version:
#include <stdio.h>
int main() {
char fName[15], mName[15], lName[15], name[45];
int i, j;
printf("\nEnter the First name: ");
if (scanf("%14s", fName) != 1)
return 1;
printf("\nEnter the Middle name: ");
if (scanf("%14s", mName) != 1)
return 1;
printf("\nEnter the Last name: ");
if (scanf("%14s", lName) != 1)
return 1;
i = 0;
for (j = 0; fName[j] != '\0'; j++) {
name[i++] = fName[j];
}
name[i++] = ' ';
for (j = 0; mName[j] != '\0'; j++) {
name[i++] = mName[j];
}
name[i++] = ' ';
for (j = 0; lName[j] != '\0'; j++) {
name[i++] = lName[j];
}
name[i] = '\0';
printf("\nFull name is %s.", name);
return 0;
}
There is a simpler solution using string functions:
#include <stdio.h>
#include <string.h>
int main() {
char fName[15], mName[15], lName[15], name[45];
printf("\nEnter the First name: ");
if (scanf("%14s", fName) != 1)
return 1;
printf("\nEnter the Middle name: ");
if (scanf("%14s", mName) != 1)
return 1;
printf("\nEnter the Last name: ");
if (scanf("%14s", lName) != 1)
return 1;
strcpy(name, fName);
strcat(name, " ");
strcat(name, mName);
strcat(name, " ");
strcat(name, lName);
printf("\nFull name is %s.", name);
return 0;
}
And even simpler using just snprintf:
#include <stdio.h>
int main() {
char fName[15], mName[15], lName[15], name[45];
printf("\nEnter the First name: ");
if (scanf("%14s", fName) != 1)
return 1;
printf("\nEnter the Middle name: ");
if (scanf("%14s", mName) != 1)
return 1;
printf("\nEnter the Last name: ");
if (scanf("%14s", lName) != 1)
return 1;
snprintf(name, sizeof name, "%s %s %s", fName, mName, lName);
printf("\nFull name is %s.", name);
return 0;
}

Others have explained why your program didn't print the full name. Phillip Ngan suggested a correction, but it pastes the individual names together without spacing. To get the full name in the usual form, you just need to replace the line i++; in your code with
name[i++] = ' ';
and the line j++ with
name[i+j++] = ' ';
Of course, you could replace all the for loops with just
sprintf(name, "%s %s %s", fName, mName, lName);
And also of course you should note David C. Rankin's comment.

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;
}

Heap Corruption Detected after Normal block in C

I have a database application and after adding and deleteting some records i enter to case 6 to free memory and exit app. I know when I exit the program memory automatic gets free but I do this as teacher says. Same problem with heap corruption I get when delete a record and then i try to free the last record. Below you can find my program. I know it's a bit longer but after much days and hours i can't determine the problem. Below you will find my code.
#include <stdio.h>
#include <malloc.h>
#include <string.h>
typedef struct StudentDynamic
{
char* firstName;
char* lastName;
float grade;
}StudentDynamic;
void exportCSV(char *filename, StudentDynamic* pStudents, int nStudents)
{
printf("\n Creating %s.csv file. \n ", filename);
FILE *fp;
filename = strcat(filename, ".csv");
fp = fopen(filename, "wb+");
fprintf(fp, "Student No., First Name, Last Name, Grade");
for (int i = 0; i<nStudents; ++i)
{
fprintf(fp, "\n%d", i + 1);
fprintf(fp, ",%s ", pStudents[i].firstName);
fprintf(fp, ",%s ", pStudents[i].lastName);
fprintf(fp, ",%f ", pStudents[i].grade);
}
fclose(fp);
printf("\n File %s succesfully created!\n", filename);
}
void printStudents(StudentDynamic* pStudents, int nStudents)
{
printf("==========");
printf(" List of Students");
printf(" ========== \n");
for (int i = 0; i < nStudents; ++i)
{
printf("%d. %12s %12s %8.2f", i + 1,
pStudents[i].firstName,
pStudents[i].lastName,
pStudents[i].grade);
printf("\n");
}
}
void rewriteFile(StudentDynamic* pStudents, int nStudents)
{
for (int i = 0; i < nStudents - 1; ++i)
for (int j = i + 1; j < nStudents; ++j)
{
if (pStudents[i].grade > pStudents[j].grade)
{
StudentDynamic aux;
aux = pStudents[i];
pStudents[i] = pStudents[j];
pStudents[j] = aux;
}
}
FILE *rwF;
rwF = fopen("logfile.bin", "wb");
for (int i = 0; i<nStudents; ++i)
{
fprintf(rwF, "%s\n", pStudents[i].firstName);
fprintf(rwF, "%s\n", pStudents[i].lastName);
if (i + 1 == nStudents)
{
fprintf(rwF, "%f", pStudents[i].grade);
break;
}
fprintf(rwF, "%f\n", pStudents[i].grade);
}
fclose(rwF);
}
int main()
{
int nStudents, i = 0;
StudentDynamic* pStudents = NULL;
char auxfirstName[255], auxlastName[255];
float auxGrade, updGrade;
FILE *pFile;
pFile = fopen("logfile.bin", "rb");
if (pFile == NULL)
{
printf("Could not open file or is empty! Exiting...");
exit(2);
}
while (!feof(pFile) && pFile != " ")
{
pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic)*(i + 2));
fscanf(pFile, "%s", auxfirstName);
pStudents[i].firstName = (char*)malloc(strlen(auxfirstName) + 1);
strcpy(pStudents[i].firstName, auxfirstName);
fscanf(pFile, "%s", auxlastName);
pStudents[i].lastName = (char*)malloc(strlen(auxlastName) + 1);
strcpy(pStudents[i].lastName, auxlastName);
fscanf(pFile, "%f", &auxGrade);
pStudents[i].grade = auxGrade;
strcpy(auxfirstName, "");
strcpy(auxlastName, "");
auxGrade = 0;
i++;
}
nStudents = i;
for (int i = 0; i < nStudents - 1; ++i)
for (int j = i + 1; j < nStudents; ++j)
{
if (pStudents[i].grade > pStudents[j].grade)
{
StudentDynamic aux;
aux = pStudents[i];
pStudents[i] = pStudents[j];
pStudents[j] = aux;
}
}
fclose(pFile);
char choice;
printf("\t\t================== STUDENT DATABASE APPLICATION ==================");
printf("\n\n");
printf(" \n\t\t\t============================================");
printf("\n \t\t\t 1. Create Student");
printf("\n \t\t\t 2. Update Record");
printf("\n \t\t\t 3. Delete Record");
printf("\n \t\t\t 4. Export DB to CSV");
printf("\n \t\t\t 5. List Students");
printf("\n \t\t\t 6. Exit Program");
printf(" \n\t\t\t============================================");
printf("\n\n");
printf(" Select Your Choice : ");
getch();
while (1)
{
choice = getchar();
switch (choice)
{
case '1':
nStudents++;
pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic) * (nStudents + 1));
printf("Details of the new student:\n");
printf("First name: ");
scanf("%s", auxfirstName);
pStudents[nStudents - 1].firstName = (char*)malloc(strlen(auxfirstName) + 1);
strcpy(pStudents[nStudents - 1].firstName, auxfirstName);
printf("Last Name: ");
scanf("%s", auxlastName);
pStudents[nStudents - 1].lastName = (char*)malloc(strlen(auxlastName) + 1);
strcpy(pStudents[nStudents - 1].lastName, auxlastName);
printf("Grade: ");
scanf("%f", &auxGrade);
pStudents[nStudents - 1].grade = auxGrade;
i++;
rewriteFile(pStudents, nStudents);
printf("\n Enter Another Choice : ");
break;
case '2':
int idtoUpdate;
printf("Update Records for student number: ");
scanf("%d", &idtoUpdate);
idtoUpdate = idtoUpdate - 1;
if (idtoUpdate>nStudents)
printf("Your number is bigger than number of Students. Enter a correct number.");
else
{
int auxI = idtoUpdate;
printf("\n");
printf("Change details for student number %d. \n", auxI + 1);
printf("type 1 for Yes / type 0 for Next step\n");
int changeChoice = 0, changeCount;
printf("Want to change First name?:");
scanf("%d", &changeChoice);
changeCount = 0;
if (changeChoice == 1)
{
changeCount++;
printf("Change First name: ");
scanf("%s", auxfirstName);
pStudents[auxI].firstName = (char*)malloc(strlen(auxfirstName) + 1);
strcpy(pStudents[auxI].firstName, auxfirstName);
}
changeChoice = 0;
printf("Want to change Last name?:");
scanf("%d", &changeChoice);
if (changeChoice == 1)
{
changeCount++;
printf("Change Last Name: ");
scanf("%s", auxlastName);
pStudents[auxI].lastName = (char*)malloc(strlen(auxlastName) + 1);
strcpy(pStudents[auxI].lastName, auxlastName);
}
changeChoice = 0;
printf("Want to change the Grade?:");
scanf("%d", &changeChoice);
if (changeChoice == 1)
{
updGrade = 0;
changeCount++;
printf("Change Grade: ");
scanf(" %f", &updGrade);
pStudents[auxI].grade = updGrade;
}
if (changeCount != 0)
rewriteFile(pStudents, nStudents);
}
printf("\n Enter Another Choice : ");
break;
case '3':
int idtoDelete;
printf("Delete Records for student number: ");
scanf("%d", &idtoDelete);
idtoDelete = idtoDelete - 1;
if (idtoDelete>nStudents)
printf("Your number is bigger than number of Students. Enter a correct number.");
else
{
for (int i = idtoDelete; i < nStudents - 1; ++i)
{
strcpy(pStudents[i].firstName, pStudents[i + 1].firstName);
strcpy(pStudents[i].lastName, pStudents[i + 1].lastName);
pStudents[i].grade = pStudents[i + 1].grade;
}
free(pStudents[nStudents-1].firstName);
free(pStudents[nStudents - 1].lastName);
nStudents--;
rewriteFile(pStudents, nStudents);
}
printf("\n Enter Another Choice : ");
break;
case '4':
char str[10];
printf("\n Enter the filename (max. 10 characters): ");
scanf("%s", str);
exportCSV(str, pStudents, nStudents);
printf("\n Enter Another Choice : ");
break;
case '5':
printf("\n");
for (int i = 0; i < nStudents - 1; ++i)
for (int j = i + 1; j < nStudents; ++j)
{
if (pStudents[i].grade > pStudents[j].grade)
{
StudentDynamic aux;
aux = pStudents[i];
pStudents[i] = pStudents[j];
pStudents[j] = aux;
}
}
printStudents(pStudents, nStudents);
printf("\n Enter Another Choice : ");
break;
case '6':
for (int i = 0; i < nStudents-1; ++i)
{
free(pStudents[i].firstName);
free(pStudents[i].lastName);
}
free(pStudents);
printf("\n");
printf("\t\t Thank you for using my application.");
printf("\n\n");
exit(0);
}
}
return 0;
}
In one place when you allocate space for an extra record, you use:
pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic)*(i + 2));
I think you are creating one too many records there, should be i + 1
Later on in the code you use
pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic) * (nStudents + 1));
and that appears correct. Since it is the last student record where you have the problem, then this is the issue, when reading in the file you have an extra record at the end. You have an extra record at the end of the array within nothing in it.
When you are deleting a record, you may be copying a long student name into a short buffer.
firstname was allocated so that it was just long enough to fit the students name.
When you delete a record, the next student's name, which could be longer, is copied into the short buffer, running over the end, and destroying the heap
strcpy(pStudents[i].firstName, pStudents[i + 1].firstName); //copy many characters
strcpy(pStudents[i].lastName, pStudents[i + 1].lastName); //into short buffers
Rather than using string copy, you could just free the old names, and reassign the pointers.
free(pStudents[i].firstName);
pStudents[i].firstName = pStudents[i + 1].firstName;
Also, when you change student names, it looks like you allocate more memory, but don't free the old memory

I can't read the second string, no matter how many getchar i insert

This program need to read two strings, this two strings will be passed to the "confirm" function, they will be read and the the function will have to find a word in common.
But in the main i cant read the "string2" string! No matter how many getchar i insert.
#include <stdio.h>
#include <string.h>
void confirm(char string1[],char string2[]){
char word[20];
char w_aux[20];
int i, j, k, l, m;
int len1, len2;
int find;
i = 0;
len1 = strlen(string1);
len2 = strlen(string2);
while (i < len1){
j = 0;
while ((string1[i] != ' ') && (i < len1)){
word[j] = string1[i];
i++;
j++;
}
word[j] = '\0';
k = 0;
find = 0;
while((k < len2) && (find == 0)){
l = 0;
while ((string2[k] != ' ') && (k < len2)){
w_aux[l] = string2[k];
k++;
l++;
}
w_aux[l] = '\0';
if (j == l){
m = 0;
while((word[m] == w_aux[m]) && (m<j)){
m++;
}
if (m == j){
find = 1;
}
}
k++;
}
i++;
}
printf("%s\n", word);
}
int main (){
char string1[20];
char string2[20];
printf("Type the first text: \n");
scanf("%[^\n]s", string1);
printf("Type the second text: \n");
scanf("%[^\n]s", string2);
getchar();
confirm(string1, string2);
return 0;
}
Use getchar after input of string 1 for \n:
printf("Type the first text: \n");
scanf("%[^\n]", string1);
getchar(); //here
printf("Type the second text: \n");
scanf("%[^\n]", string2);
Just change the format specifier to "%19[^\n]*c", it will take the trailing '\n' character away.

Program errors due to strcmp and strcpy in C

No matter how I edit my program there seems to be overflow errors and mismatching type errors. Can someone help me to make this run without errors.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int choice;
int i;
int j;
char type;
int amount;
int don_count = 0;
int req_count = 0;
int flag;
char donations_inv_type[100][20];
int donations_amount[100];
char requests_inv_type[100][20];
int req_amount[100];
printf("Welcome to the Food Bank Program\n\n 1. Add a donation\n 2. Add a request\n 3. Fulfill a request\n 4. Print status report\n 5. Exit\n\nEnter your choice: ");
scanf("%d", &choice);
while (choice != 5) {
if (choice == 1) {
printf("\nEnter inventory type: ");
scanf("%s", &type);
printf("Enter the amount: ");
scanf("%d", &amount);
printf("\nDonation Added!\n\n");
flag = -99;
for (i = 0; i < don_count; i++) {
if (strcmp(donations_inv_type[i], type) == 0)
flag = i;
}
if (flag == -99) {
strcpy(donations_inv_type[i], type);
donations_amount[i] = amount;
don_count++;
}
else
donations_amount[flag] += amount;
printf("Donation Added!\n");
printf("Press any key to continue . . .\n\n");
}
else if (choice == 2) {
printf("\nEnter inventory type: ");
scanf("%s", &type);
printf("Enter the amount: ");
scanf("%d", &amount);
strcpy(requests_inv_type[req_count], type);
req_amount[req_count] = amount;
req_count++;
}
else if (choice == 3) {
printf("\n\n-------- Fulfilling Requests--------");
flag = -99;
for (i = 0; i < don_count; i++) {
if (strcmp(donations_inv_type[i], requests_inv_type[0]) == 0)
flag = i;
}
if (flag == -99)
printf("Cannot be Fulfilled\n\n");
else if (donations_amount[flag] > req_amount[0]) {
donations_amount[flag] -= req_amount[0];
printf("Request Fulfilled");
req_amount[0] = 0;
}
else if (donations_amount[flag] == req_amount[0]) {
printf("Request Fulfilled");
for (i = flag; i < don_count; i++) {
strcpy(donations_inv_type[i], donations_inv_type[i + 1]);
strcpy(donations_amount[i], donations_amount[i + 1]);
}
don_count--;
for (i = flag; i < req_count; i++) {
strcpy(requests_inv_type[i], requests_inv_type[i + 1]);
strcpy(req_amount[i], req_amount[i + 1]);
}
req_count--;
}
else if (donations_amount[flag] < req_amount[0]) {
printf("Partially Fulfilled");
req_amount[0] -= donations_amount[flag];
for (i = flag; i < don_count; i++) {
strcpy(donations_inv_type[i], donations_inv_type[i + 1]);
strcpy(donations_amount[i], donations_amount[i + 1]);
don_count--;
}
}
}
else if (choice == 4) {
printf("Printing the Donations Table\n\n");
for (i = 0; i < don_count; i++) {
printf("%s %d", donations_inv_type[i], donations_amount[i]);
}
printf("Printing the Requests Table\n\n");
for (i = 0; i < req_count; i++) {
printf("%s %d", requests_inv_type[i], req_amount[i]);
}
}
printf("Welcome to the Food Bank Program\n\n 1. Add a donation\n 2. Add a request\n 3. Fulfill a request\n 4. Print status report\n 5. Exit\n\nEnter your choice: ");
}
}
Any help is greatly appreciated and I would love an explanation as to what I did wrong so that I can learn and not make the same mistakes next time.
Declare type as character array.
char type[50];
Remove & in scanf(). You should not use & while reading string.
scanf("%s", &type); ==> scanf("%s", type);
^
Here you want to copy integers not strings
strcpy(donations_amount[i], donations_amount[i + 1]);
strcpy(req_amount[i], req_amount[i + 1]);
Modify like this
donations_amount[i]=donations_amount[i + 1];
req_amount[i]= req_amount[i + 1];
Instead of char type you need char type[100]
Error in your code:
if (strcmp(donations_inv_type[i], type) == 0)
// ^^^^ should be char*
Note: Functions strcmp() and strcpy() should be passed \0 nul-terminated array of char (or say string).
Your scanf should look like scanf("%s", type);

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