I have an assignment where I have to type in the amount of names I want to compare. Then I have to see if the first name printed is repeated in the names I printed. For example if I put in 5 Reagan, Bush, Reagan, Bush, Clinton it will print out "The first name was repeated" but if I put in Davis for either of the Reagans it would say no. I've attempted a for loop and if statements but I can't seem to find the correct output. I am using Dev C++ and here is what I have so far.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main () {
char curname[30], firstname[30];
int num, i, freq = 1;
printf("How many names do you want to enter?\n");
scanf("%d", &num);
printf("What is the first name?");
scanf("%s", firstname);
printf("Enter each of their names.\n");
for (i=0; i<num; i++) {
scanf("%s", curname);
if (i==0) {
strcmp(curname, firstname) != 0;
printf("The first name in the list was repeated.\n");
}
else if (strcmp(curname, firstname) == 1)
printf("The first name in the list was not repeated.\n");
}
system("pause");
return 0;
}
You need to do only one comparison and print your message based on the result of that comparison.
if (strcmp(curname, firstname) == 0 ) {
printf("The first name in the list was repeated.\n");
}
else {
printf("The first name in the list was not repeated.\n");
}
Its always worthwhile to be very clear on what the return value of any function call is, in this case strcmp.
you have to compare names, strcmpi is more appropriate (case insensitive comparison)
if (strcmpi(curname, firstname)==0)
printf("The first name in the list was repeated.\n");
else
printf("The first name in the list was not repeated.\n");
strcmp return value may be greater 0 or less then 0, so:
strcmp(curname, firstname) == 1
change to:
strcmp(curname, firstname) != 0
others: You did not record the names into a list, so you can not find the name if or not repeated.
So I have edited my program based on the suggestions. Here is what I have now. It will only give me the correct output if the name is entered as the last value. Thank you so much!! :)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main () {
char curname[30], firstname[30];
int num, i, freq = 1;
// Read in the number of students.
printf("How many names do you want to enter?\n");
scanf("%d", &num);
printf("What is the first name?\n");
scanf("%s", firstname);
printf("Enter each of their names.\n");
for (i=0; i<num; i++)
// Read the current name.
scanf("%s", curname);
// Always update the best seen for the first name.
if (strcmp(firstname, curname)== 0) {
printf("The first name in the list was repeated.\n"); }
else
printf("The first name in the list was not repeated.\n");
system("pause");
return 0;
}
Related
I'm working on a code that will take a single user input and split it into five substrings. Partway through, I discovered this error I got when calling the function Split_Input. I've never gotten this before and I feel like there's an easy solution, I just can't put my finger on it. Any help would be appreciated! Thank you in advance!
#include <iostream>
#include <string>
using namespace std;
//This function will take the user input and split it into five substrings
void Split_Input(string *database, int ROWS) {
//------USER INPUT----------
cout << "Enter your first name, last name, age, phone number, and email address. \n";
cout << "Make sure you separate each value with a comma!\n";
string info;
cin >> info;
//------GETTING THE SUBSTRINGS--------
//This value will count each comma and sort the substrings
int column_count = 0;
for (int i = 0; info[i] != '\0'; i++) {
if (info[i] == ',') {
column_count++;
continue;
}
//The i marks the array's position by reference
database[ROWS][column_count][&i] = info[i];
}
}
int main(void)
{
const int COLUMNS = 5, ROWS = 3, CHARS = 30;
string database[ROWS][COLUMNS][CHARS];
Split_Input(database, ROWS);
return 0;
}
The issue which you asked is the type incompability, and error is even tells you what you need to do. So into function Split_Input you need pass a std::string(*)[3][5][30] and you function call should look like this
Split_Input(&database[ROWS][COLUMNS][CHARS], ROWS);
I don't for what the heck you need adress in this line:
database[ROWS][column_count][&i] = info[i];
BTW, you can replace searching comma you can replace with string.find(',').
I understand it is your beginning with C++, so feel free to ask questions.
I am making an application for playing Dungeons & Dragons, just for fun, and I ran into a problem. I've written multiple printfs and somehow it stopped working. When it finishes the first calculation and when it has to move on to the next, then it stops. I have no idea why.
This is the code:
#include <stdio.h>
#include <stdlib.h>
#include <ctime>
#include <string>
int main(){
//variables
int dmgDice;
char entityName, dmgType;
int initiative, dmgBonus, damage, userAC, userHp;
//user input
printf("Type in your armor class: \n");
scanf("%d", &userAC);
printf("Type in your hit points : \n");
scanf("%d", &userHp);
printf("type in your initative: \n");
scanf("%d", &initiative);
printf("type in you damage bonus: \n");
scanf("%d", &dmgBonus);
printf("type in you damage type: \n");
scanf("%s", &dmgType);
printf("your damage dice: \n");
scanf("%d", &dmgDice);
printf("Entity you want to damage: \n");
scanf("%s", &entityName);
//d20 roll
srand((unsigned)time(0));
printf("d20 roll: \n");
int d20roll = (rand() % 20);
int SUM = d20roll + initiative;
printf("you have rolled SUM %d + %d = %d", d20roll, initiative, SUM);
if(d20roll > 14){
printf("\nYou've passed the enemies AC, now roll for damage!");
printf("\nYou did %d damage to the %s!", damage, entityName);
}
else{
printf("\nYou have missed, now %s attacks..", entityName);
int entityd20roll = (rand() % 20) + 1;
printf("\n%s passed your armor class, now it will roll for damage");
if(entityd20roll > userAC){
int edmg = (rand() % 12);
int hp = userHp - edmg;
if(hp < 0)
hp *= -1;
printf("\nhit points taken: \n");
printf("%s has dealt %d damge", entityName, edmg);
}
else{
printf("%s has missed you", entityName);
}
}
return 0;
}
Also, how can I create a memory file so the user doesn't have to type in everything over and over again?
I suggest including the library and trying the same thing with cout<< and cin>> because these commands work a little different.
So for example printf("Type in your armor class: \n");
becomes cout<<"Type in your armor class: "<<endl;
And scanf("%d", &userAC); becomes cin>>userAC;
And for your file saving system, I suggest you follow a class on file I/O like for example this video: https://www.youtube.com/watch?v=Iho2EdJgusQ.
You can then write all the user's options to a file and then read the information when the programs starts. This way the user's preferences will be kept.
I suggest (as #samu_242 already has done) to use the std::cout and std::cin commands for the inputs.
In your code, the printf
printf("\n%s passed your armor class, now it will roll for damage");
expects a string (%s), but you did not pass nothing. Moreover, maybe you had in mind to use array of chars, but you allocated memory for just one char:
char entityName, dmgType;
In this way, entityName will get only the first char that the user gives in input (e.g., if he/she types "Goblin" entityName will have only "G"). To declare an array of char, use
char entityName[N];
where N is the maximum length of the array. There are also ways to dynamically allocate memory, but my advise is to use the std::string.
I'm very new at C++, maintaining my M.Sc on Information Systems. I have my first C++ homework announced and have been working on it for a couple of days. The aim of the code is simply to read info from a text file and print it on screen, then make calculation on some of it and print results to a new text file. However when I build, it gives the error:
EXC_BAD_ACCESS (code=EXC_I386_GBFLT)
in the first fscanf in readInfo function.
I know the code I wrote is not completely efficient but I just want it to print on screen and on output file correctly. I would really appreciate if anyone help me to resolve this error. I am about to freak out...
#include <stdio.h>
typedef struct {
char id[10];
char name[40];
float midterm;
float final;
int attendance;
}Student;
void readInfo(Student studentList[], int *count)
{
FILE *fin=fopen("scores.txt","r");
char surname = '\0';
*count=0;
while(!feof(fin))
{
fscanf(fin,"%c %c %c %f %f %d",studentList[*count].id, studentList[*count].name, &surname, &studentList[*count].midterm, &studentList[*count].final, &studentList[*count].attendance);
strcpy(studentList[*count].name, studentList[*count].name);
strcat(studentList[*count].name, " ");
strcat(studentList[*count].name, &surname);
*count++;
}fclose(fin);
printf("%-7s%17s %5.1f %5.1f %-2d\n", studentList[*count].id, studentList[*count].name, studentList[*count].midterm, studentList[*count].final, studentList[*count].attendance);
}
float studentScore(float midterm, float final, int attendance)
{
float score;
int maxAttend=0;
char id[10];
char name[40];
char surname[40];
FILE *fin=fopen("scores.txt","r");
while(!feof(fin))
{
fscanf(fin,"%c %c %c %f %f %d",id, name, surname, &midterm, &final, &attendance);
if(attendance>maxAttend)
maxAttend=attendance;
}fclose(fin);
score=midterm*0.3+final*0.5+(maxAttend/20)*attendance;
return score;
}
float avgScore(Student studentList[])
{
float average;
int count;
int totalScore=0;
readInfo(studentList, &count);
for(int i=0; i<=count; i++)
{
totalScore+=studentScore(studentList[count].midterm, studentList[count].final, studentList[count].attendance);
}
average=totalScore/count;
return average;
}
void courseGradeOutput(Student studentList[])
{
FILE *fout=fopen("output.txt","w");
int count;
int pass=0;
float score;
char letterGrade[2];
float avg;
fprintf(fout,"\tId\tName, Surname = (Score, Letter)\n");
readInfo(studentList, &count);
for(int i=0; i<=count; i++)
{
score=studentScore(studentList[i].midterm, studentList[i].final, studentList[i].attendance);
if(score>=0 && score<=49)
{ letterGrade[0]={'F'};
letterGrade[1]={'F'};}
else if (score>=50 && score<=59)
{letterGrade[0]={'F'};
letterGrade[1]={'D'};}
else if (score>=60 && score<=64)
{letterGrade[0]={'D'};
letterGrade[1]={'D'};}
else if (score>=65 && score<=69)
{letterGrade[0]={'D'};
letterGrade[1]={'C'};}
else if (score>=70 && score<=74)
{letterGrade[0]={'C'};
letterGrade[1]={'C'};}
else if (score>=75 && score<=79)
{letterGrade[0]={'C'};
letterGrade[1]={'B'};}
else if (score>=80 && score<=84)
{letterGrade[0]={'B'};
letterGrade[1]={'B'};}
else if (score>=85 && score<=89)
{letterGrade[0]={'B'};
letterGrade[1]={'A'};}
else if (score>=90 && score<=100)
{letterGrade[0]={'A'};
letterGrade[1]={'A'};}
if(score>=60)
pass++;
fprintf(fout,"%7s %16s = ( %4.1f, %6s\n)", studentList[i].id, studentList[i].name, score, letterGrade);
}
avg=avgScore(studentList);
fprintf(fout,"\nSome statistics:\n\nClass Avg Score: %5.2f \n #Students: %11d \n #Passed Students: %4d \n #Failed Students: %4d",avg,count,pass,(count-pass));
fclose(fout);
}
int main()
{ Student studentList[100];
int count;
readInfo(studentList, &count);
courseGradeOutput(studentList);
}
Screenshot
The crash is most likely caused by either fscanf followed by strcpy and/or by your increment of count inside readInfo.
You write *count++, but this is equivalent to
count = count + 1;
*(count-1);
What you want is (*count)++.
The fscanf scans characters %c where you want to scan strings %s (for id and name). You also want to scan surname as a string, probably, but then you need to change surname to be a character array:
char surname[30];
*count=0;
while(!feof(fin))
{
fscanf(fin,"%s %s %s %f %f %d",studentList[*count].id, studentList[*count].name, surname, &studentList[*count].midterm, &studentList[*count].final, &studentList[*count].attendance);
strcat(studentList[*count].name, " ");
strcat(studentList[*count].name, surname);
(*count)++;
}
fclose(fin);
I also removed the first strcpy as you were copying from a buffer to itself, which is not allowed.
I haven't checked the other functions thoroughly, but I do notice that you do not use the result from your readInfo called from main when you do courseGradeOutput: this function calls readInfo again. You could modify it to take the read student records and the count, so you don't have to read the file again.
You might also want to improve scanf a bit to pass a width, such as %29s for name, to avoid overflowing the buffer when the name inside the file is too long; and the same for the other strings you scan. You should then also look at the return value of fscanf and only use the things you scanned when it succeeded in scanning every argument.
I seem to be having trouble with my array output when the input is from a textfile... Though the output is supposed to be a single character (A,B,C,D) the array outputs gibberish, symbols like #, ?, etc. when prompted. Any sort of help would be appreciated. The grade part of the program isn't calculating either, but I can figure that out myself. the program compiles and runs with the errors being:
29 46 C:\Users\Robert\Desktop\bob project\Proj1.cpp [Warning] deprecated
conversion from string constant to 'char*' [-Wwrite-strings]
and the same error for line 32
#include <iostream>
#include<cstdlib>
#include <iomanip>
#include <fstream>
using namespace std;
// Global constants
const int SIZE = 20; // The number of questions
const int numQuestions = 20;
// Function prototypes
void readFile(char filename[],char answers[], int SIZE);
void compareAnswers(char student[], char correct[], int SIZE, int & numMissed);
void displayTestResults(int numMissed, int SIZE);
int main()
{
// Number of questions missed.
int numMissed;
// Array to hold the correct answers
char correct[SIZE];
// Array to hold the student's answers
char student[SIZE];
//Read the correct answers.
readFile("CorrectAnswers.txt", correct, SIZE);
// Read the student's answers.
readFile("StudentAnswers.txt", student, SIZE);
// Compare the student's answers with the correct
// answers.
compareAnswers(student, correct, SIZE, numMissed);
// Display the test results.
displayTestResults(numMissed, SIZE);
system("PAUSE");
return 0;
}
// ********************************************************
// The readFile function reads the contents of an answer *
// file into an array. *
// ********************************************************
void readFile(char filename[], char values[], int SIZE)
{
fstream inFile;
// Open the file.
inFile.open(filename);
for (char i = 0; i < SIZE; i++)
{
inFile>>values[i];
inFile.close();
}
return;
}
// ********************************************************
// The compareAnswers function compares the elements of *
// the student array with the elements of the correct *
// array. For each student answer that is incorrect the *
// funcction increments a counter that keeps track of the *
// number of incorrect answers, making this available via *
// a call by reference argument. The function displays *
// the question number answered incorrectly along with *
// answer given by the student and the correct answer. *
// ********************************************************
void compareAnswers(char student[], char correct[],
int SIZE, int &numMissed)
{
// Initialize numMissed.
numMissed = 0;
cout<< "Checking the answers...\n";
// Step through the answer arrays comparing
// each answer.
for (char i = 0; i < SIZE; i++){
if(student[i] == correct[i])
{i++;}
else
{
numMissed++;
cout<<"I'm sorry, you had the wrong answer for "<<i + 1<<"."<<endl;
cout<<"Your answer was "<<student[i]<<".";
cout<<endl;
cout<<"The correct answer was "<<correct[i]<<".";
i++;
cin.ignore();
}
}
return;
}
// ********************************************************
// The displayTestResults function displays the test *
// statistics. *
// ********************************************************
void displayTestResults(int numMissed, int SIZE)
{
int temp;
// Calculate the number of correctly answered
// questions.
int correctlyAnswered = SIZE - numMissed;
// Calculate the numeric score correctly rounded to the nearest tenth of a percent.
temp == static_cast<int>(static_cast<double>(correctlyAnswered/SIZE*10+0.5));
// Display the number of correctly answered
// questions.
cout<<" The number of questions you got correct is:" <<correctlyAnswered;
// Display the percentage of correctly
// answered questions.
cout<<" The percentage of questions you got correct is:"<<temp;
//Display the letter grade on the exam.
cout<<endl<<endl;
if (temp >=93)
{cout<<"Your letter grade is an: A";}
else if(temp>=89)
{cout<<"Your letter grade is an: A-";}
else if(temp>=87)
{cout<<"Your letter grade is a: B+";}
else if(temp>=83)
{cout<<"Your letter grade is a: B";}
else if(temp>=79)
{cout<<"Your letter grade is a: B-";}
else if(temp>=77)
{cout<<"Your letter grade is a: C+";}
else if(temp>=73)
{cout<<"Your letter grade is a: C";}
else if(temp>=69)
{cout<<"Your letter grade is a: C-";}
else if(temp>=67)
{cout<<"Your letter grade is a: D+";}
else if(temp>=63)
{cout<<"Your letter grade is a: D";}
else if(temp>=57)
{cout<<"Your letter grade is a: D-";}
else
{cout<<"Your letter grade is a: F"<<endl;}
return;
`enter code here`}
To silence the warnings, the function should be declared as:
void readFile(const char *filename, char *answers, int SIZE)
It's complaining because you're passing a string literal, which is constant, to a function that doesn't declare the argument as const.
To solve the gibberish, change the body of the for loop to:
if(student[i] != correct[i]) {
numMissed++;
cout<<"I'm sorry, you had the wrong answer for "<<i + 1<<"."<<endl;
cout<<"Your answer was "<<student[i]<<".";
cout<<endl;
cout<<"The correct answer was "<<correct[i]<<".";
cin.ignore();
}
You don't need to do i++ inside the loop, it's already being done in the loop header.
Basically the purpose of this program is to read up to 100 names from file, sort with a bubblesort, and then search for a entered name by binary search.
All seems to be working except when I enter a name that is in the list, nothing happens, I'm just prompted to enter a name again.
Say a name in the list in Elvis Presley. I am prompted to enter a name. I type in Elvis Presley. I SHOULD recieve Elvis Presley is your friend. Not happening. Any help appreciated.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void bubblesort(string[], const int);
void search(string[], const int);
int sub = 0;
int main()
{
const int maxsize = 100;
string friendArray[maxsize];
ifstream friends;
friends.open("myFriends.dat");
while (sub < maxsize && getline(friends, friendArray[sub]))
sub++;
bubblesort(friendArray, sub);
search(friendArray, maxsize);
system("pause");
return 0;
}
void bubblesort(string *array, const int size)
{
bool swap;
string temp;
do
{
swap = false;
for (int count = 1; count < (size - 1); count++)
{
if(array[count-1] >array[count])
{
temp = array[count-1];
array[count-1] = array[count];
array[count] = temp;
swap = true;
}
}
}
while(swap);
}
void search(string *array, int size)
{
int first = 0;
int last = size - 1;
int middle;
string name;
bool friends = false;
do
{
cout<<"Please enter a name or END to terminate:";
cin>>name;
}
while(!friends && first <= last && name != "END");
{
middle = (first + last) / 2;
if (array[middle] == name)
{
friends = true;
cout<<array[middle]<<" is my friend."<<endl;
}
else if (array[middle] > name)
last = middle - 1;
else
last = middle + 1;
}
}
In your search() function, the do { } while; { } construct is flawed. It will compile but it doesn't do what you want. I made a few changes and rearranged your code so it makes more sense.
void search(string *array, int size)
{
string name;
for (;;)
{
cout<<"Please enter a name or END to terminate:";
getline(cin, name);
if (name == "END") break;
int first = 0;
int last = size - 1;
bool friends = false;
while (!friends && first <= last)
{
int middle = (first + last) / 2;
if (array[middle] == name)
{
friends = true;
cout<<array[middle]<<" is my friend."<<endl;
}
else if (array[middle] > name)
last = middle - 1;
else
first = middle + 1;
}
}
}
int main () // test the search() function
{
string array[] = { "bird", "cat", "dog", "horse", "loon", "zebra" };
search(array, 6);
}
SO, is this too much homework help? Should I delete this?
I find it interesting that you set last in both cases where you don't find a match.
The first thing you should do is think about what that means, nudge, nudge, wink, wink :-)
You should also pass the number of used elements to search as well, rather than the size of the array (since you may not be using the full array).
I suppose that
search(friendArray, maxsize);
should be
search(friendArray, sub);
Binary search's input condition is that the searched-in array is sorted. Your array looks like this:
Aaron Burr
Bill Cosby
Celine Dion
...
Zachary Taylor
""
""
""
""
etc.
Since an empty string is not less than a non-empty string, friendArray[0..maxsize] is not sorted, while the array friendArray[0..sub] is.
EDIT: I also just noticed that your binary search algorithm is flawed. Look again at your source material (text book, wikipedia, whatever). Isn't first supposed to be updated inside your loop?
Operator >> reads formatted data from the stream, i.e. discards white spaces. When you say cin >> name; and enter "Elvis Presley", only "Elvis" get stored in name.
What you need is getline(cin, name);
Think what will happen if the length of your friends array would be 3. If I'm not mistaken there will be a problem.
Also it is recommended to use safer data types, like vector<string> for example, then you do not need to care about too much data in the input file. Also your life will get easier in the search function, since you can use iterators and do not need to pass the size of the array.
Take a look at what people say in the other answers about cin.
This is one do-whie loop:
do
{
cout<<"Please enter a name or END to terminate:";
cin>>name;
}
while(!friends && first <= last && name != "END");
The code will basically loop forever (friends will never be true and first will never be > last), prompting you for a name until you either kill the program or type in "END".
This:
{
middle = (first + last) / 2;
if (array[middle] == name)
{
friends = true;
cout<<array[middle]<<" is my friend."<<endl;
}
else if (array[middle] > name)
last = middle - 1;
else
last = middle + 1;
}
will not get a chance to execute until the loop condition is false (in this case, until you type in "END").
You say that all seems to be working except when you entered a name to be searched. Actually , you stepped into point.There is a mistake in your binary search code. And the first answer in this topic is toward this way.
If array is used in binary search , it must be split into two parts in each stage of search.
For example in a stage if current part is marked as follows : first - middle - last on the next stage the parts will be either between first - middle-1 or middle+1 - last.
So
else if (array[middle] > name)
last = middle - 1;
else
last = middle + 1;
must be
else if (array[middle] > name)
last = middle - 1;
else
first = middle + 1;
You have an off-by-one error in your sort.
The problem is in function search. move the } after cin>>name to the end of the function to look like:
void search(string *array, int size)
{
int first = 0;
int last = size - 1;
int middle;
string name;
bool friends = false;
do
{
cout<<"Please enter a name or END to terminate:";
cin>>name;
while(!friends && first <= last && name != "END");
{
middle = (first + last) / 2;
if (array[middle] == name)
{
friends = true;
cout<<array[middle]<<" is my friend."<<endl;
}
else if (array[middle] > name)
last = middle - 1;
else
last = middle + 1;
}
}
}