I'm trying to have a string only work if it matches an int in the list.
Code
int Keys[] = { 23454563, 1262352, 634261253, 152352 };
string key;
int main()
{
cout << ("Please Enter Key: ");
cin >> key;
if (key = Keys)
{
//Activate Code
}
else
{
//Don't activate
}
}
I've tried searching around and I can't find any valid methods. I did try
if (sscanf(key.c_str(), "%d", &Keys) == 1)
^this works, but any number works and that isn't what I'm looking for.
hmm. First, I don't know why you have to input a 'string' instead of an 'int'. Also, why do you make 'key' a global variable? Just put it inside 'main'. Moreover, 'Keys' is an array and you can't compare a variable with an array.You have to search through the array using a loop.
My prefer answer
#include <iostream>
int main()
{
constexpr int Keys[] { 23454563, 1262352, 634261253, 152352 };
int key;
bool isNumberMatched {false};
std::cout << ("Please Enter Key: ");
std::cin >> key;
for (auto number : Keys) //Search through Keys array
{
if (key == number)
isNumberMatched = true;
break;
}
if (isNumberMatched)
//Activate Code
else
//Don't activate
}
Related
I am writing a C++ program for homework, and it needs to count the characters in a char arr[n] string. However, my counter keeps returning the wrong values. I have looked through other answers to similar questions, however, they are not specific to C++ and none of the answers explain the value I am getting.
#include<iostream>
using namespace std;
#include<string.h>
#include <stdlib.h>
class Counter
{
public:
char word[20];
int totChar{ 0 };
void setWord(char word)
{
this->word[20] = word;
}
void setCount(int totChar)
{
this->totChar = totChar;
}
int getLength()
{
return totChar;
}
void charCount()
{
int n = 0;
for (int i = 0; word[i] != '\0'; i++) {
if (word[i] != '\0')
{
n++;
}
}
setCount(n);
}
};
int main()
{
char text[20];
cout << "Enter the string:" << endl;
cin >> text;
Logic input;
input.setWord(text[20]);
input.charCount();
// input.resetWord();
cout << input.getLength();
}
So it seems you haven't figured out how arrays and C strings work in C++ yet.
void setWord(const char* word)
{
strcpy(this->word, word);
}
and
Logic input;
input.setWord(text);
Your code is a bit weird, I guess you are just experimenting, but I think those two changes should make it work.
I am quite new to c++ programming and data structures and really need some help. I am working on an assignment where I have a text file with 100 lines and on each line there is an item, a status(for sale or wanted), and a price. I need to go through the text file and add lines to an array of structs and as I add lines I need to compare the new information with the previously submitted information. If there is a line that is wanted and has a price higher than a previously input item that is for sale then the item would be removed from the struct and the array of structs shifted.
The place that I am having trouble is in actually shifting all the structs once a line that satisfies the condition is found.
My issue is that when I try to shift the array of structs using the second for loop nothing happens and I just get null structs and nothing seems to move.
Please if you guys can offer any help it would be greatly appreciated.
Below is the code of the text file and my current code.
#include<iostream>
#include<fstream>
#include <string>
#include <algorithm>
#include <sstream>
using namespace std;
struct items
{
string type;
int status;
int price;
} itemArray [100];
int main(int argc, char *argv[]) {
int x = -1;
//int chickenCount = 0;
int counter = 0;
int itemsSold = 0;
int itemsRemoved = 0;
int itemsForSale = 0;
int itemsWanted = 0;
string itemType;
int itemStatus = 0;
int itemPrice = 0;
int match = 0;
ifstream myReadFile( "messageBoard.txt" ) ;
std::string line;
//char output[100];
if (myReadFile.is_open()) {
while (!myReadFile.eof()) {
getline(myReadFile,line); // Saves the line in STRING.
line.erase(std::remove(line.begin(), line.end(), ' '), line.end());
//cout<<line<<endl; // Prints our STRING.
x++;
std::string input = line;
std::istringstream ss(input);
std::string token;
while(std::getline(ss, token, ',')) {
counter++;
//std::cout << token << '\n';
if (counter>3){
counter =1;
}
//cout << x << endl;
if (counter == 1){
itemType = token;
//cout<< itemType<<endl;
}
if (counter == 2){
if (token == "forsale"){
itemStatus = 1;
//itemsForSale++;
}
if (token == "wanted"){
itemStatus = 0;
//itemsWanted++;
}
//cout<< itemStatus<<endl;
}
if (counter == 3){
itemPrice = atoi(token.c_str());
//cout<< itemPrice<<endl;
}
//cout<<"yo"<<endl;
}
if (x >= 0){
for (int i = 0; i<100;i++){
if (itemArray[i].type == itemType){
//cout<<itemType<<endl;
if(itemArray[i].status != itemStatus){
if (itemArray[i].status == 1){
if(itemPrice>=itemArray[i].price){
itemsSold++;
match =1;
//itemArray[i].type = "sold";
for (int j=i; j<100-1;j++){
//cout<<j<<endl;
itemArray[j].type = itemArray[j+1].type;
itemArray[j].status = itemArray[j+1].status;
itemArray[j].price = itemArray[j+1].price;
}
i =i-1;
break;
}
}
if (itemArray[i].status == 0){
if(itemArray[i].price>=itemPrice){
itemsSold++;
match = 1;
//itemArray[i].type = "sold";
for (int j=i; j<100-1;j++){
//cout<<j<<endl;
itemArray[j].type = itemArray[j+1].type;
itemArray[j].status = itemArray[j+1].status;
itemArray[j].price = itemArray[j+1].price;
}
i=i-1;
break;
}
}
}
}
}
}
if (counter == 3 && match == 0){
itemArray[(x)].type = itemType;
itemArray[(x)].status = itemStatus;
itemArray[(x)].price = itemPrice;
}
match = 0;
// cout << itemArray[x].type << " " << itemArray[x].status<<" "<<itemArray[x].price<<endl;
}
for(int i=0;i<100;i++){
cout<<itemArray[i].type<< " "<<itemArray[i].status<<" "<<itemArray[i].price<<endl;
}
//cout<<itemArray[1].price<<endl;
cout << itemsSold<<endl;
}
myReadFile.close();
return 0;
}
text file: https://drive.google.com/file/d/0B8O3izVcHJBzem0wMzA3VHoxNk0/view?usp=sharing
Thanks for the help
I see several issues in the code, but without being able to test it, I think the main problem is that you always insert new elements at position 'x' which correspond to the currently line read from the file, without taking into account any shift of elements done. You should insert the new element at the first empty slot (or just overwrite the old element instead of shifting everything).
An other issue is that you do not initialize the status and price in your array.
The best way would be to rewrite the code by using more standard C++ features, for example:
replace the items structure by a class with a constructor defining default values
use object copy (there is no need to copy a struct element by element)
use standard C++ containers like a list (see http://www.cplusplus.com/reference/list/list/) which has insert and erase methods
I'm beginner to C++ and I have implemented the following simple jump table, but was wondering if I'm doing it the right way. Is there anyway I can improve the following code?
The following code is using a dictionary (I'm from a C# background) to store functions' pointers.
#include <cstdio>
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
void Zero() { printf("Zero\n"); }
void One() { printf("One\n"); }
void Two() { printf("Two\n"); }
void Three() { printf("Three\n"); }
string prompt()
{
printf("Enter number from 0 to 3 or q to quit:\n");
string line;
getline(cin, line);
return line;
}
int main(int argc, const char * argv[]) {
unordered_map<string, void(*)()> map;
map["0"] = Zero;
map["1"] = One;
map["2"] = Two;
map["3"] = Three;
while (true) {
string c = prompt();
if (c == "q") break;
map[c]();
}
return 0;
}
How about a switch statement?
switch (c) {
case 0:
printf("Zero\n"); break;
case 1:
printf("One\n"); break;
case 2:
printf("Two\n"); break;
case 3:
printf("Three\n"); break;
default:
break;
}
There's not much you can do to make your code "faster" without going for the switch solution which breaks the original idea of having an array of functions. If you only gonna use 'characters' such as '0' => '9', 'a' => 'z' you could dodge the memory allocation needed for the string, and you could also initialize your map with an initializer_list, and you could also make such array const static if that's viable.
Here goes my "optimized" code if it helps.
inline char prompt() //this function will probably 900% be inlined even if you don't specify the inlike keyword
{
printf("Enter number from 0 to 3 or q to quit:\n");
char v;
while (!(std::cin >> v)); //Just to make sure we get valid input
return v;
}
int main()
{
static const std::unordered_map<char, void(*)()> mymap =
{
{ '0' , Zero },
{ '1' , One },
{ '2' , Two },
{ '3' , Three }
};
while(1)
{
auto it = mymap.find(prompt());
// Without this check, your program will crash if input is invalid.
if (it != mymap.end())
{
it->second();
break;
}
}
return 0;
}
Pleas provide more details for your case of efficiency. Do you mean memory/cpu cycles/pass-through?
According to your code:
it's not error prone (use auto it = map.find(key); function for searching and check output it != map.end() value, so no new elements will be created)
it's good enough for string key type
you case easily make more flexible by replacing function pointer with std::function<void()>
It terms of more low-level control you can you custom hash function and custom hash tables implementations.
On some data it may be usefull to consider std::map or sorted std::vector as an option.
As static lookup is fast, This will perform very good irrespective of compiler. Jump table differs from compiler to compiler. I would use following code, May be some people will object to this as global are bad. But before commenting, please evaluate this
string prompt()
{
printf("Enter number from 0 to 3 or q to quit:\n");
string line;
getline(cin, line);
return line;
}
enum Choice = {ZERO = 0, ONE, TWO, THREE};
static char *choice_str[] = {
"Zero",
"One",
"Two",
"Three"
};
int main(int argc, const char * argv[]) {
while (true) {
string c = prompt();
if (c == "q")
{
break;
}
else {
assert(atoi(c) >= Choice::ZERO && atoi(c) <=Choice::THREE);
printf("%s\n", choice_str[atoi(c)]);
}
}
I am having trouble with this program. I'm not so familiar with the functions strcpy and strcmp.
Can any professionals help me or give me some advice?
As others have stated, choose either C-style strings or C++ std::string.
I highly recommend not creating a separate function for searching the string array because passing arrays to functions is difficult for beginners.
Try something like:
#include <string>
#include <iostream>
#define MAX_NAMES 16
int main(void)
{
std::string name_container[MAX_NAMES];
unsigned int names_in_container = 0;
while (1)
{
std::string name_from_user;
std::cout << "Enter name: ";
if (!getline(std::cin, name_from_user))
{
break; // Exit from the "while" loop
}
// Search the name container for the name.
unsigned int array_slot = 0;
bool name_found = false;
for (array_slot = 0; array_slot < names_in_container; ++array_slot)
{
if (name_from_user == name_container[array_slot])
{
std::cout << "\nName exists in slot " << array_slot << "\n";
name_found = true;
}
}
if (!name_found)
{
if (array_slot >= MAX_NAMES)
{
std::cout << "Name container full, cannot add name.\n";
break;
}
else
{
name_container[names_in_container] = name_from_user;
++names_in_container;
}
}
}
}
Please recognize that you are comingling C++ string (std::string) and the C library strcpy and strcmp functions. They are two different things. You probably need to look at some of the methods available under the std::string class (.c_str, =, ==),
Here are a few comments, and suggestions,
void search (string sid[], //do you intend to pass a string sid, or an array of srings?
string name[], //do you intend to pass a string name, or an array of strings?
int No_of_data_input)
{
char id[100];
string input;
char namename[100];
//comments ignored/removed
//these two lines declare the function strcpy
char * strcpy ( char * namename, const char * name );
char * strcpy ( char * id, const char * sid );
//do you intend to copy name and sid instead?
//do you want: strcpy(namename, name[i].c_str() );
//do you want: strcpy(id, sid[i].c_str() );
//if so, you want to do this inside your loop on i, below,
int sameName=0;
int j=0;
cout<<"enter id or name";
getline(cin,input); //you probably want: cin >> input;
//do you intend to declare the function strcpy yet again?
char * strcpy ( char * inputinput, const char * input );
//or do you intend to copy input to some char[]?
//you probably want: strcpy( inputinput, input.c_str() );
//you probably want number of elements in sid[] or name[]?
for(int i=0;i<4;i++){
//you probably want sid[i] here
if ((strcmp(inputinput,id[i])==0) || (strcmp(inputinput,name[i])==0)){
//you could rewrite this as:
//if( (input == id[i]) || (input == name[i]) ){
sameName++;
j=i;
} //do us a favor
} //make the ending braces clearer
cout<<sameName;
if (sameName==0)
cout<<"No student found: ";
else if (sameName==1)
cout<<"student found: "<<name[j]<<endl<<id[j];
else if (sameName>1)
cout<<"More than one student found,please enter id";
}
Do you want (or need) to comingle std::string and strcpy, strcmp?
Editing your code, you might want to just use std::string,
void search (string sid[], //do you intend to pass an array of srings?
string name[], //do you intend to pass an array of strings?
int count)
{
string input;
int same=0;
int j=0;
cout<<"enter id or name";
cin >> input;
//you probably want number of elements in sid[] or name[]?
for(int i=0;i<count;++i){
if( (input == sid[i]) || (input == name[i]) ){
++same;
j=i;
}
}
cout<<"same: "<<same<<endl;
if (same==0)
cout<<"No student found: "<<endl;
else if (same==1)
cout<<"student found: "<<name[j]<<","<<id[j]<<endl;
else if (same>1)
cout<<"More than one student found,please enter id"<<endl;
}
Maybe you could use a vector of strings? Then you could use an iterator on the vector.
You may have more success if you define a student record (containing sid and name), and pass a vector of student records. Then use an iterator over that vector -- read about vector and iterators.
I tried to use,
if(isalpha(card[i].name))
...
but it says that i can't use it with char type here is my code:
This is the struct:
struct firm {
unsigned egn;
char name[80];
char lastname[80];
char department[80];
unsigned salary;
}card[100];
This is the function where i want to make the check if only letters then to continue:
void enter()
{
int i, n;
char temp[80];
do{
cout<<"Enter how many workers you want to add: ";cin>>n;
}while(!(n>0 && n<101));
for(i=top;i<n;i++)
{/*ЕГН + проверка*/
cout<<"Enter EGN: ";do{
cin>>temp;
if((strlen(temp)!=10))
cout<<"Enter EGN: ";
}while(strlen(temp)!=10);
card[i].egn = (unsigned) atoi (temp);
/*Име Фамилия*/
cout<<"Enter name(only letters): ";cin>>card[i].name;
cout<<"Enter lastname(only letters): ";cin>>card[i].lastname;
cout<<"Enter department: ";cin>>card[i].department;
cout<<"Enter salary: ";cin>>temp;
card[i].salary = (unsigned) atoi (temp);
}
}
When i try to use this kind of code:
cout<<"Enter name(only letters): ";do{
cin>>card[i].name;
if(isalpha(card[i].name))
.....;
and it says that i can't use char in int (isalpha uses int? )
You need to loop over every character of the string, isalpha() only tests a single character.
You cannot use isalpha on an entire char array, only on individual characters. To check that every character in a char array is alphabetical, you can use the std::all_of algorithm:
auto name_begin = std::begin(card[i].name);
auto name_end = std::end(card[i].name);
bool name_alpha = std::all_of(name_begin, std::find(name_begin, name_end, '\0'), std::isalpha);
if (name_alpha) {
std::cout << "It's alphabetical!" << std::endl;
}
If you're using a compiler without the necessary C++11 support, you can do:
char* name_begin = card[i].name;
bool name_alpha = std::all_of(name_begin, name_begin+std::strlen(name_begin), std::isalpha);
if (name_alpha) {
std::cout << "It's alphabetical!" << std::endl;
}
Then the boring way without using the standard library algorithms:
bool name_alpha = true;
for (char* character = card[i].name; *character != '\0'; character++) {
if (!std::isalpha(*character)) {
name_alpha = false;
break;
}
}
if (name_alpha) {
std::cout << "It's alphabetical!" << std::endl;
}
The problem is that name is itself an array of chars, so you need to test each each element something like this:
.....
cout<<"Enter name(only letters): ";do{
cin>>card[i].name;
bool bIsAlpha = true;
for (int j = 0; j < strlen(card[i].name); ++j)
{
if(!isalpha(card[i].name[j]))
{
bIsAlpha = false;
break;
}
}
if (bIsAlpha)
{
.....;
}