comparision strings from struct in if statement - c++

I wrote a c++ code and used struct, I want to compare two string in struct type.but error occures:
#include <iostream>
using namespace std;
#define NumOfStudents 2
#define NumOfCourses 3
struct Student{
int stdnum, FieldCode, age;
double average, marks, res[NumOfCourses];
char Fname[20], Lname[20], cmp[20];
};
int main(){
struct Student students[NumOfStudents];
int i, j;
// char cmp[20];
cout << "\t **********************************************************************\n";
cout << "\t *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*\n";
cout << "\t *+ FIRST-NAME || LAST-NAME || STUDENT-NUMBER || FIELD-CODE || AGE +*\n";
cout << "\t *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*\n";
cout << "\t **********************************************************************\n";
for(i=0; i<NumOfStudents; i++){
cout << "STUDENT #" << i+1 << ": ";
cin >> students[i].Fname >> students[i].Lname >> students[i].stdnum >> students[i].FieldCode >> students[i].age;
}
cout << "what student do you want?[Enter family]\n";
cin >> students[j].cmp;
for(i=0; i<NumOfStudents; i++){
if(students[j].cmp == students[j].Lname){ //The error occurs here
for(j=0; j<NumOfCourses; j++){
cout << "\nCOURCE #" << j+1 << ": ";
cin >> students[j].marks;
}
}
else
cout << "The Student with name " << students[j].cmp << " doesn't exist!!!";
}
return 0;
}
In the code I commented place the error occurred...
thank you

Of course this comparison
if(students[j].cmp == students[j].stdnum){
is invalid because data member cmp has type char[20] and stdnum has type int. It is not clear what you are going to compare.
EDIT: I see you updated your post and wrote
if(students[j].cmp == students[j].Lname){
However this statement is also invalid because arrays have no the comparison operator. In this condition the both arrays are converted to pointers to their first elements and the pointers are compared. So the condition will be equal always to false. Instead you have to use strandard C function strcmp
if( std::strcmp( students[j].cmp, students[j].Lname ) == 0 ){
It would be simpler if you would use std::string instead of character arrays. You need to include header <string>
In this case the structure will look the following way
struct Student{
int stdnum, FieldCode, age;
double average, marks, res[NumOfCourses];
string Fname, Lname, cmp;
};
and you could use the comparison operator
if( students[j].cmp == students[j].Lname ){

This should do the trick for you.
if(strcmp(students[i].cmp, students[i].Lname) == 0)

If you are sure about using char string, you should use strcmp function to compare them.
(http://www.cplusplus.com/reference/cstring/strcmp/)

You are using a variable j which has no value assigned to it. Because of that, you are accessing an unknown member in the array, probably something off the array's boundaries (an index larger than NumOfStudents).
I think you want if(students[i].cmp == students[i].stdnum){ instead of if(students[j].cmp == students[j].stdnum){, still, it should be noted that you are comparing two char arrays, which does not have your intended effect of comparing the two strings. It will probably compare the position of the arrays in the memory(will always evaluate to false). Instead use strcmp, and use commands from the <cstring> library when dealing with cstrings (char arrays).
Or just save yourself the trouble and use the string class, which overloads the = operator and lets you compare two strings using =.

Related

Why is my variable not declared in the scope?

I'm working on an assignment right now and when run my code returns this error:
main.cpp:60:20: error: ‘dataArr’ was not declared in this scope
if(tolower(dataArr[i].last) == tolower(lastName))
I'm not quite sure what I'm missing here. If I could at least get it to run I'd appreciate it. Thanks.
I thought arrays were declared globally so i thought it wouldn't be an issue in my functions
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct Database
{
string first;
string last;
string ID;
string phoneNum;
};
void lastSearch(string);
void idSearch(string);
int main()
{
Database dataArr[100];
ifstream myFile("library_database.txt");
int count = 0;
while(!myFile.eof() && count < 100)
{
myFile >> dataArr[count].first >> dataArr[count].last >> dataArr[count].ID >> dataArr[count].phoneNum;
cout << dataArr[count].first << " " << dataArr[count].last << " " << dataArr[count].ID << " " << dataArr[count].phoneNum << endl;
count++;
}
int input;
string search;
cout << "Would you like to search by last name or member ID?\n1. Last Name\n2. ID\n> ";
cin >> input;
while(input != 1 || input != 2)
{
cout << "Enter a valid answer.\n> ";
cin >> input;
}
if(input == 1)
{
cout << "Enter last name: ";
cin >> search;
lastSearch(search);
}
if(input == 2)
{
cout << "Enter ID: ";
cin >> search;
idSearch(search);
}
return 0;
}
void lastSearch(string lastName)
{
int num = 0;
for(int i = 0; i < 100; i++)
{
if(tolower(dataArr[i].last) == tolower(lastName))
{
cout << dataArr[i].first << " " << dataArr[i].last << " " << dataArr[i].ID << " " << dataArr[i].phoneNum << endl
num++;
}
}
if(num == 0)
{
cout << "No match was found in the file.";
}
}
voidSearch was removed to allow this to be posted
To answer the title of your post: because it isn't.
You declare dataArr in main, but you are trying to use it in lastSearch, so lastSearch can't see it. But you can pass it in as a parameter, that's probably the easiest fix:
void lastSearch(const string lastName, const Database *dataArr) { ... }
and call it like this:
lastSearch (search, dataArr);
Note the use of const (get into the habit of doing that whenever you can) and that your array 'decays' to a pointer when you pass it as a parameter like this, so don't be tempted to use sizeof in lastSearch. If you need to know the number of elements in the array, pass that as a parameter too.
Or, better, use std::array instead of a C-style array and then the size of the array is available in lastSearch without the need to pass it in separately. If you do that, you probably want to pass it by const reference to avoid copying it every time you call the function.
Finally, it might be time to learn about std::vector. At the expense of a little more complexity (but not much), this would avoid the need to allocate a fixed size array. Again, for the same reason, pass it around by reference.
Some bedtime reading: The Definitive C++ Book Guide and List
Arrays are not declared globally, they are declared where you declare them :-)
In your case, you declare it at the top of main() so that is its scope, from point of declaration to end of main(). Trying to use it in lastSearch() is therefore invalid.
The easiest fix is probably just to move the declaration immediately before main() so that it is global. But the easiest things is often not the right thing.
You would be better off embracing C++ fully(1) and using something like std::vector, whose size isn't arbitrarily limited to 100 (for example) and which you could pass around quite easily, something like:
#include <iostream>
#include <vector>
void function(const std::vector<int> &vec) {
std::cout << vec.size() << ' ' << vec[0] << '\n'; // Output: 2 42
}
int main() {
std::vector<int> x;
x.push_back(42);
x.push_back(99);
function(x);
}
The main advantages with vectors are that:
you're not limited to a maximum of 100 items;
you don't have to pass around the actual count of items read separately as with a raw array or even a std::array (you don't do that in your code but I assure you, that's a problem).
the size of the vector is an integral property of the vector, available anywhere the vector is in scope.
(1) There's a variety of developers I like to call C+ developers. These are the people that, though they claim to be C++ developers, have never really embraced the C++ way of doing things, sticking to C style programming practices like non-smart pointers or normal arrays :-)
Some of those things may still have a place in modern C++ code but you should be circumspect in their use.

How to Pass a String in a function?

I have a function (int, string) in Main:
string word("HELLO");
int x = 0;
char choice;
swap(x, word);
I am trying, with no success, to pass into the following function:
void swap(int, string) {
int x = 0;
string word = "HELLO";
cout << "Would you like to change a letter? Please enter the letter
position. " << endl;
cin >> x;
if (x == 1) {
cout << "What do you want to change it to?" << endl;
cin >> word[0];
I keep getting this error:
Error C2664 'void std::swap(std::exception_ptr &,std::exception_ptr &) throw()': cannot convert argument 1 from 'int' to 'std::exception_ptr &'
What gives?
The main problem with your code is the indentation. Your code is not readable and mostly hard to comprehend it. Beautify it. Write nice, readable and a structured code. You can read more about indentation at the following link.
https://en.wikipedia.org/wiki/Indentation_style
The next thing is the function declaration. You do not declare your function before defining it. The function declaration should be top of the main function and definition of the function should be below the main function.
You can find more info about the function declaration at the following link:
http://en.cppreference.com/w/cpp/language/function
Since you are not using a char array to print out the string, it is useless to go through the string with a loop. Include the <string> library and start to work towards the string type. By passing the string variable inside std::cout is enough to print out the string.
Lastly, since you are trying to manipulate a string variable outside the main function, it is required that you are passing a reference parameter instead.
void myFunction(std::string& parameter);
This way, the original variable that exists inside the main or inside any other function will be altered. Without the reference, &, the value you are trying to modify will not be changed.
The following link demonstrates the use of reference.
http://www.learncpp.com/cpp-tutorial/73-passing-arguments-by-reference/
Please read my comments below of why some changes were applied. I made crafty changes to the change function. You are now eligible to work towards any
string type with any size.
#include <iostream>
#include <string> //When you are working on strings, use the string library.
using namespace std;
//Function declaration is very important. Have the declarations above main.
void change(string&);
int main() {
string word("HELLO");
char choice;
cout << "The word is : " << endl;
cout << word << endl;
//No need for the for loop to print out the string as
// we are working on a string and not a char array.
// for (int i = 0; i < word.length(); i++) {
// cout << word[i];
// }
change(word);
cout << "The new word is" << endl << word << endl;
cout << "Would you like to enter another change ? Enter Y or N ? " << endl;
cin >> choice;
if (choice == 'y' || choice == 'Y') {
change(word);
cout << word << endl;
}
else {
cout << "Good Bye" << endl;
}
system("pause");
return 0;
}
//When your datatype is to be modified outside the function, use the reference
//parameter type '&'.
//Without the reference type, your modified version of the type will only be modified
//inside that function.
//The original one will not be altered.
void change(string& word) {
/*
* size_t is simply unsigned int, to work towards manipulation and accessing
* of string types, use unsigned int or std::size_t
*/
size_t x = 0;
cout << "Would you like to change a letter? Please enter the letter position. " << endl;
cin >> x;
//Check to see if the inputted value is within the string length range.
if(x > 0 && x <= word.length())
cout << "What do you want to change it to?" << endl;
else{
cout << "The entered position is outside the string size range\n";
return; //Quit from the function if the condition is not met.
}
/*
* Instead of using if/else if statements,
* Just make a normal loop. Much simpler.
*/
for(size_t i = 0; i < word.length(); i++){
if((x-1) == i)
cin >> word[i];
}
}

how to store character variable into two dimensional character variable

I Want to store the value of user_uname and user_pwd to validuser[c][0] and validuser[c][1].Also string "normaluser" to validuser[c][2].
But it shows an error "cannot convert char * to char".This is my code:
char validuser[20][20];
int c;
char user_uname[20],user_pwd[20];
cout<<"\n Enter User Detail";
cout<<"\n enter Username:";
cin>>user_uname;
cout<<"\n Enter Password:";
cin>>user_pwd;
validuser[c][0] = user_uname;
validuser[c][1] = user_pwd;
validuser[c][2] = "normaluser";
c++;
Your validuser is an array of arrays or chars. You can only store single char in each spot, or you can use it as an array of "strings" (char arrays). If you definitely want to use C style strings, you should have a third dimension to do what you're trying, such as char validuser[20][3][20].
But since you are using C++, why not use std::vector<std::string> rather? And store usernames and passwords in a struct, not as consecutive strings. Using C++ strings and vectors will allow you to use any length of strings or any number of users without knowing the number beforehand or handling memory allocations yourself.
char validuser[20][20];
....
validuser[c][0] = user_uname;
The validuser[][] is a char so you are not OK to assign. In your code, you can use:
strncpy( &(validuser[c][0]), user_uname, 20 );
But why dont you use the std::vector or std::array? In most of the case, std::string provide good enough feature for you.
You must use string on this. Char only accept a single character, here is the modified code. Hope this helps :)
The First Dimension you only need 3 array because of the user name, password, and type. for the 2nd Dimension you can add as many as you want, I made it 3 so that it would accept 3 users.
#include<iostream>
#include<string>
using namespace std;
void main()
{
int pause;
string validuser[3][3];
int c = 0;
do
{
string user_uname, user_pwd;
cout << "\nEnter User Detail";
cout << "\nenter Username:";
cin >> user_uname;
cout << "Enter Password:";
cin >> user_pwd;
cout << endl;
validuser[c][0] = user_uname;
validuser[c][1] = user_pwd;
validuser[c][2] = "normal_user";
c++;
} while (c < 3);
c = 0;
do{
cout << validuser[c][0] << " " << validuser[c][1] << " " << validuser[c][2] << endl;
c++;
} while (c < 3);
cin >> pause;
}

C++ program to accept multiples inputs and put in an array using pointer

there's a problem facing me in this question :
"write a c++ console program to accept five
integers values from keyboard in one line separated by spaces . the program then stores the five values in an array using pointer . then print the elements of the array on the screen ."
I tried to make a string variable and accept 5 integers from user then convert it to integer but it doesn't work well because it doesn't take numbers after space .
any help guys ??
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
int main(){
string numbers;
getline(cin, numbers);
int arr[5];
int *ptr;
int values;
stringstream convert(numbers);
convert >> values;
cout << values;
}
It will only take one at a time, you need to add more calls to convert like so:
stringstream convert(numbers);
convert >> values;
cout << values;
convert >> values;
cout << " " << values;
convert >> values;
cout << " " << values;
The C++faq has a good section on this.
Without major modification, if you need to put the number directly into the array using a pointer, you can do this:
int *ptr = arr ;
convert >> *ptr++ ;
convert >> *ptr++;
convert >> *ptr++;
convert >> *ptr++;
convert >> *ptr++;
for( unsigned int i = 0; i < 5; ++i )
{
cout << arr[i] << " " ;
}
cout << std::endl ;
I successfully made it
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
int main(){
int arr[5];
string number;
cout << "Please enter 5 integers separeted with spaces " << endl;
getline(cin, number);
int *ptr = arr ;
stringstream convert(number);
convert >> *ptr++ ;
convert >> *ptr++;
convert >> *ptr++;
convert >> *ptr++;
convert >> *ptr++;
for( int i = 0; i < 5; ++i )
{
cout << arr[i] << " " ;
}
cout << std::endl ;
}
I the numbers variable is string you can search for first non space character using numbers.find_first_not_of(" "); and first space character by numbers.find_first_of(" "); then create a subset using substr(.....) now place the substr in another string variable. Now convert the substring to int. repeat the steps for number of times you need. i.e. place the whole code inside a while loop. Terminate the loop whenever numbers.find_first_of(" ");returns numbers.end()

How to compare 2 integers to see if they are equal?

How do I compare two integers in C++?
I have a user input ID (which is int) and then I have a Contact ID that is part of my Struct. The Contact ID is int also.
I need to compare to see if they are the same, to know that it exists.
I did something like this*:
if(user_input_id.compare(p->id)==0)
{
}
but I get an error message saying that expression must have class type.
*based on reading this page http://www.cplusplus.com/reference/string/string/compare/
The function you found is for comparing two std::strings. You don't have std::strings, you have ints. To test if two ints are equal, you just use == like so:
if (user_input_id == p->id) {
// ...
}
In fact, even if you had two std::strings, you'd most likely want to use == there too.
I am unsure what you mean, but IMHO
int k;
std::cin>>k;
if (k==p->id)
do_sth();
else
do_sth_else();
The point is you do not store input as string, but a int.
//simple program to compare
#include<iostream>
using namespace std;
typedef struct node {
int a;
}node;
int main() {
node p;
p.a = 5;
int a;
cin >> a;
if( p.a == a )
cout << "Equal" << endl;
else
cout << "Not Equal"<< endl;
return 0;
}
IF your struct's name is p and you have an integer in it called hello, you can do the following
int input;
cin << input;
if(input == p.hello){
cout << "the input is equal to p.hello" << endl;
}
else{
cout << "the input is not equal to p.hello" << endl;
}