Phone Number Lsit - c++

Write a simple telephone directory program in C++ that looks up phone numbers in a file containing a list of names and phone numbers. The user should be prompted to enter a first name and last name, and the program then outputs the corresponding number, or indicates that the name isn't in the directory. After each lookup, the program should ask the user whether they want to look up another number, and then either repeat the process or exit the program. The data on the file should be organized so that each line contains a first name, a last name, and a phone number, separated by blanks. You can return to the beginning of the file by closing it an opening it again.
I cant get the line
check = strstr(phoneDirectory, name);
to work strstr part keep giving the error: no instance of overloaded function "strstr" matches the argument list argument types.
Here a copy of my code:
#include <iostream>
#include <string>
#include <fstream>
#include <cstring>
using namespace std;
int arraySize();
int main()
{
const int SIZE = arraySize();
char *phoneDirectory;
int size=0;
char name; //name to look for
char *check = NULL;
bool find = false;
phoneDirectory = new char [SIZE];
ifstream phoneNumbers;
phoneNumbers.open("phoneNumbers.txt");
if (!phoneNumbers)
cout << "Error opening data file\n";
//looping throught the name file
else
{
for (int i = 0; i < SIZE; i++)
{
phoneNumbers >> phoneDirectory;
}
phoneNumbers.close(); //closes data file
}
phoneNumbers.close();
// Get a name or partial name to search for.
cout << "Enter a name or partial name to search for: ";
cin.getline(phoneDirectory, name);
cout << "\nHere are the results of the search: " << endl;
int entries = 0;
for (int i = 0; i < size; i++)
{
check = strstr(phoneDirectory, name);
if (check != NULL)
find = true;
}
if (!find)
cout << "No matches!" << endl;
delete [] phoneDirectory;
return 0;
}
int arraySize()
{
string phoneNum;
int size = 0;
ifstream phoneNumbers; // Input file stream object
// Open the data file.
phoneNumbers.open("phoneNumbers.txt");
if (!phoneNumbers)
cout << "Error opening data file\n";
//looping throught the name file
else
{
while (getline(phoneNumbers, phoneNum))
{
size++;
}
phoneNumbers.close(); //closes data file
}
return size;
}

Your name variable is a char. Should it be a char* instead?

Related

Read ASCII file, store in array, print

The task is as follows:
Create an ASCII text and a C++ program to read it. Print the Shipped date, part number, first name, last name, company name from the ASCII text.
I had to create my own ASCII text. I tested it, and was able to read it successfully. Now, I'm having trouble reading character by character and sending to an array so that I can filter out the data I don't want to display. I will show my ASCII text file followed by the code I'm using to read it.
04/12/11 D50625 74444 James Lehoff Rotech
04/12/11 D60752 75255 Janet Lezar Rotech
04/12/11 D40295 74477 Bill McHenry Rotech
04/12/11 D23745 74470 Diane Kaiser Rotech
04/12/11 D50892 75155 Helen Richardson NapTime
(I don't know why this format won't work...sorry...its not important for the task)
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
int main()
{
//initialize array
const int MAXROWS = 5;
const int MAXCOLS = 64;
int ship_array [MAXROWS][MAXCOLS];
int row,col;
string filename = "/Users/Jimmy/Desktop/shipped.txt";
string line;
ifstream inFile;
inFile.open(filename.c_str()); //opens ASCII file
if (inFile.fail()) //checks for successful open
{
cout << "\nThefile was not successfully opened"
<< "\n Please check that the file currently exists." << endl;
exit(1);
}
cout << "\nThe file has been successfully opened for reading.\n" << endl;
///////////code to read and output the data will go here///////////////////
cout << "Shipped Date Part Number First name Last Name Company Name";
//cycle through rows and columns//
row=0;
while(row<MAXROWS)
{
for (col=1; col<9; col++) // STORE SHIPPED DATE
{
ship_array[row][col] = get(filename.c_str());
cout << ship_array[row][col]; //DISPLAY SHIPPED DATE
}
for (col=22; col<27; col++) //STORE PART NUMBER
{
ship_array[row][col] = get(filename.c_str());
cout << ship_array[row][col]; //DISPLAY PART NUMBER
}
for (col=31; col<36; col++) // STORE FIRST NAME
{
ship_array[row][col] = get(filename.c_str());
cout << ship_array[row][col]; //DISPLAY FIRST NAME
}
for (col=39; col< 49; col++) // STORE LAST NAME
{
ship_array[row][col] = get(filename.c_str());
cout << ship_array[row][col]; //DISPLAY LAST NAME
}
for (col=51; col<65; col++) // STORE COMPANY NAME
{
ship_array[row][col] = get(filename.c_str());
cout << ship_array[row][col]; //DISPLAY COMPANY NAME
}
}
inFile.close();
return 0;
}
I KNOW the error is where I'm storing my values FROM the ASCII text to my array. I thought get() was for reading one character at a time but it doesn't work. Please point me in the right direction.
EDIT
I changed my code a bit. I tried something new. This gave me a few zeros. I didn't even bother going further down. My variables and initializations aren't right and I don't know why.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <string>
using namespace std;
int main()
{
//initialize array
const int MAXROWS = 5;
const int MAXCOLS = 64;
int ship_array [MAXROWS][MAXCOLS];
int row,col;
//initialize input stream
string ascii_data = "/Users/Jimmy/Desktop/shipped.txt";
ifstream data;
stringstream ss(ascii_data);
data.open(ascii_data.c_str()); //opens ASCII file
if (data.fail()) //checks for successful open
{
cout << "\nThefile was not successfully opened"
<< "\n Please check that the file currently exists." << endl;
exit(1);
}
cout << "\nThe file has been successfully opened for reading.\n" << endl;
cout << "Shipped Date Part Number First name Last Name Company Name" << endl;
//cycle through rows and columns//
row=0;
while(row<MAXROWS)
{
for (col=1; col<9; col++) // STORE SHIPPED DATE
{
ss >> ship_array[0][col];
cout << ship_array[row][col];//DISPLAY SHIPPED DATE
}
for (col=22; col<27; col++) //STORE PART NUMBER
{
ss >> ship_array[row][col]; //DISPLAY PART NUMBER
}
for (col=31; col<36; col++) // STORE FIRST NAME
{
ss >> ship_array[row][col]; //DISPLAY FIRST NAME
}
for (col=39; col< 49; col++) // STORE LAST NAME
{
ss >> ship_array[row][col]; //DISPLAY LAST NAME
}
for (col=51; col<65; col++) // STORE COMPANY NAME
{
ss >> ship_array[row][col]; //DISPLAY COMPANY NAME
}
row++;
}
data.close();
return 0;
}

Store 2D array row in parallel array

I'm a beginner to C++, in my homework i have to save a row from a 2D array based on the inputted username and password. The saved row is to be a reference as to where the user info can be found in the 2D array. I haven't been able to figure out how to save the specific row to an integer. The whole code is displayed and the function to preform the task is called validateUser.
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <iomanip>
using namespace std;
void showAll(string theAccounts[5][7]);
void sortInput(string theAccounts[5][7]);
bool validateUser(string theAccounts[5][7], string username, string password, int &saveRow);
bool readFile(string theAccounts[5][7]);
int main()
{
//Declare Necessary Variables and 2D array to store data from input file.
string username;
string password;
string accountData[5][7] = { " " };
bool userGood;
bool fileGood;
//Call the readFile function and capture the returned value.
fileGood = readFile(accountData);
//Test if file was successfully read, if so continue with program else exit with error message
if (fileGood == false)
{
cout << "Error occurred...File Unread...Program Exiting" << endl;
}
else
{
cout << "\nFile Read Successfully...\n\n" << endl;
//Ask user to Enter User Name or Zero to Exit
cout << "Enter the following information or 0 to Exit...\n";
cout << "Please Enter Your User Name > ";
//Read in User Name
//If User Name read in is “zero” Exit program.
cin >> username;
if (username == "0")
{
return 0;
}
//Ask the user to Enter Their Password or Zero to Exit
cout << "Please Enter Your User Password > ";
//Read in User Password
//If User Password read in is “zero” Exit program
cin >> password;
if (password == "0")
{
return 0;
}
//Call the Validate User function and capture the returned value
//If returned value from the Validate User function is TRUE continue program to check access code if U or A
//If U – code appropriately
//If A – code appropriately
//Else if returned value Not Valid from the Validate User function, FALSE, output message username and password invalid
}
return 0;
}
void showAll(string theAccounts[5][7])
{
const int Rows = 5;
const int Columns = 7;
ifstream accountFile;
accountFile.open("AccountData.txt");
if (accountFile.is_open())
{
for (int i = 0; i < Rows; i++)
{
for (int j = 0; j < Columns; j++)
{
cout << setw(8) << theAccounts[i][j];
}
cout << endl;
}
}
accountFile.close();
}
void sortInput(string theAccounts[5][7])
{
}
bool validateUser(string theAccounts[5][7], string username, string password, int &saveRow)
{
bool passed = false;
//test for username and password match whats stored in theAccounts
for (int i = 0; i < 5; i++)
{
if (username == theAccounts[i][0] && password == theAccounts[i][3])
{
saveRow = theAccounts[i];
}
}
return passed;
}
bool readFile(string theAccounts[5][7])
{
bool fileRead;
const int Height = 5;
const int Width = 7;
ifstream inputFile; //an ifstream object – input file stream object
inputFile.open("AccountData.txt"); // the open member function opens the text file and links it with
// inputFile to read data from the AccountData.txt file
//input validation to see if file opened
//if opened, read strings into theAccounts array - reset fileRead to true
if (inputFile.is_open())
{
fileRead = true;
for (int i = 0; i < Height; i++)
{
for (int j = 0; j < Width; j++)
{
inputFile >> theAccounts[i][j];
}
}
}
else
{
fileRead = false;
}
inputFile.close();
return fileRead;
}
The .txt file contains:
bham#gnet.com Blake Ham squid62 1987 U Teacher
jdark#att.net Jim Dark gymrat32 1985 A Master
hgreen#lakes.net Hannah Green flower22 2007 U Apprentice
tsmith#dna.com Tom Smith tuna20 2000 U Teacher
jarrow#pnet.com James Arrow ahoy10 2005 U Apprentice
I haven't been able to figure out how to save the specific row to an
integer
In OP function, the specific row is simply i, so all we have to do is to assign it to the variable passed by reference, saveRow and return.
I will not comment the general design of this program as I don't know how much of it is part of the assignment, so I'll use the same interface and data structures OP used:
bool validateUser(string theAccounts[5][7], string username, string password, int &saveRow)
{
//test for username and password match whats stored in theAccounts
for (int i = 0; i < 5; i++)
{
if (username == theAccounts[i][0] && password == theAccounts[i][3])
{
// match found, "save" the right row and return
saveRow = i;
return true;
}
}
// there's no match
return false;
}
For cleaner and easier approach, You should use a combination of std::map and std::vector. std::map<Key, Value> is a container where Keys are all unique and can be of any type you desire. Also Values can be any type you want but can be duplicated. So, imagine it as std::map<Deepblue, information> is an element, another element would be std::map<FirstStep, information> and so on. No two identical keys can be found. Therefore, the Key will be a string and the Information is going to be a vector<string> container of strings.
The below code works and it populates all your data from the input file to the map. Follow the comments and you should see how it works:
#include <iostream>
#include <map>
#include <vector>
#include <fstream>
#include <string>
#include <sstream>
int main()
{
std::map<std::string, std::vector<std::string>> MyMap; // map that has a string key and a vector of strings as information
std::ifstream InFile; // to read from a text file
InFile.open("C:\\....\\input.txt");
if (InFile.fail()) // terminate if failed
{
std::cout << "File did not open correctly!";
return 0;
}
std::string OneLine;
std::vector<std::string> MyVector;
std::string MyKey;
std::vector<std::string> MyValue;
while(std::getline(InFile, OneLine)) // while "reading a whole line" is valid
{
//split the whole line on whitespaces and convert it to a vector of strings
std::stringstream ss(OneLine);
std::string item;
while (getline(ss, item, ' '))
MyVector.push_back(item);
// Now take the first word and set it as the key because it is the email, so it is the "ID" of every line/person
MyKey = MyVector[0];
// Now take the rest of the vector as Value
for (int i = 1; i < MyVector.size(); i++)
MyValue.push_back(MyVector[i]);
// Now add this [Key, Value] pair to the map
MyMap[MyKey] = MyValue;
}
system("pause");
return 0;
}
Now hoover your mouse on this variable to see how it is structured. And do some research on how to access a map write/read etc.

Writing and reading from the same file

This program takes in an input, write it on a file character by character, count the amount of characters entered, then at the end copy it to an array of characters. The program works just fine until we get to the following snippet file.getline(arr, inputLength);. It changes the .txt file data and returns only the first character of the original input.
Any ideas?
#include <iostream>
#include <fstream>
using namespace std;
int getLine(char *& arr);
int main() {
char * arr = NULL;
cout << "Write something: ";
getLine(arr);
return 0;
}
int getLine(char *& arr) {
fstream file("temp.txt");
char input = '\0'; //initialize
int inputLength = 0; //initialize
if (file.is_open()) {
while (input != '\n') { //while the end of this line is not reached
input = cin.get(); //get each single character
file << input; //write it on a .txt file
inputLength++; //count the number of characters entered
}
arr = new char[inputLength]; //dynamically allocate memory for this array
file.getline(arr, inputLength); //HERE IS THE PROBLEM!!! ***
cout << "Count : " << inputLength << endl; //test counter
cout << "Array : " << arr << endl; //test line copy
file.close();
return 1;
}
return 0;
}
I see at least two problems with this code.
1) std::fstream constructor, by default, will open an existing file. It will not create a new one. If temp.txt does not exist, is_open() will fail. This code should pass the appropriate value for the second parameter to std::fstreams constructor that specifies that either a new file needs to be created, or the existing file is created.
Related to this: if the file already exists, running this code will not truncate it, so the contents of the file from this program's previous run will have obvious unexpected results.
2) The intent of this code appears to be to read back in the contents temp.txt that were previously written to it. To do that correctly, after writing and before reading it is necessary to seek back to the beginning of the file. This part appears to be missing.
There is no need in dynamic allocation because the std library functions get confused with mixed arguments such as cstring and pointer to cstring.I tested this code in Visual Studio 2015 compiler. It works good. Make sure to include all of the needed libraries:
#include <iostream>
#include <fstream>
#include<cstring>
#include<string>
using namespace std;
void getLine();
int main() {
cout << "Write something: ";
// no need to pass a pointer to a cstring
getLine();
system("pause");
return 0;
}
void getLine() {
char input[100]; // this is a cstring with
//a safe const number of elements
int inputLength; //to extract length of the actual input
//this function requires cstring as a first argument
// and constant length as a second
cin.get(input, 100, '\n'); //get each single character
//cast streamsize into int
inputLength = static_cast<int>(cin.gcount());
//testing input
cout << "Input: \n";
for (int i = 0; i < inputLength; i++)
{
cout << input[i];
}
cout << endl;
char arr[100];
strcpy_s(arr, input);
cout << "Count : " << inputLength << endl; //test counter
cout << "Array : " << endl; //test line copy
for (int i = 0; i < inputLength; i++)
{
cout << arr[i];
}
cout << endl;
// write cstring to a file
ofstream file;
file.open("temp.txt", ios::out);
if (file.is_open())
{
//write only what was entered in input
for (int i = 0; i < inputLength; i++)
file << arr[i];
file.close();
}
else cout << "Unable to open file";
}

std::out_of_range at memory location error at getline

I'm very new to c++ there is a good bit of code here, so im going to do my best to condense it to the problem area. when I try to get user input using getline im getting this error. Since i don't expect spaces in the file names(i made the files)i use cin << which worked fine, but then got the same error when trying to read the file. the code is as follows
// includes here
using namespace std;
//other prototypes here
string getUserDataFromFile(vector<int>&, int&, string);
int main()
{
vector<int> numbers;
numbers.reserve(50);
int numberOfElements = 0;
int number = 0;
int numToFind = 0;
int numberPosition = -1;
int useFile = 0;
string filename = "";
string fileReadMessage = "";
string output = "";
string outFilename = "";
cout << "Would you like to load the data from a file?(1 for yes 0 for no)";
cin >> useFile;
cin.ignore(INT_MAX, '\n');
//get user data for manual input
if(useFile == 0)
{
//code here for manual input(works fine)...
}
//get userdata for file input
else
{
cout << "Please Enter the file path to be opened" << endl;
//fixed after adding cin.ignore(INT_MAX, '\n');
//see next function for another problem
getline(cin, filename);
fileReadMessage = getUserDataFromFile(numbers, numToFind, filename);
}
//some code to get data for output
return 0;
}
//function to get user data from file
//#param v(vector<int>&) - vector of integers.
//#param numToFind(int&) - the number we are looking for
//#param filename(string) - the filename of the file with data
//#return message(string) - a message containing errors or success.
string getUserDataFromFile(vector<int>& v, int& numToFind, string filename)
{
string message = "File Accepted";
string line = "";
int numOfElements = 0;
int count = 0;
ifstream fileToRead(filename.c_str());
//using 'cin >>' in main, the program runs till here then breaks
//if message is a file, extract message from file
if (fileToRead.is_open())
{
while (getline(fileToRead,line))
{
//code to do stuff with file contents here
}
fileToRead.close();
}
else
{
message = "Unable to open file.";
}
return message;
}
I left a couple of comments in the trouble areas and left out most of the code that i haven't had trouble with or haven't been able to test. Any help is appreciated. Thanks!
So my first issue was fixed by the addition of cin.ignore(INT_MAX, '\n'); any guesses on the next problem? its the line if (fileToRead.is_open()) in the next function
Add
cin.ignore();
before:
getline(cin, filename);
Otherwise, ENTER you typed after entering useFile will be read into filename.

How to add more than one user input to an array?

How can I add more than one string or user input to an array? I am trying to create a contact book that requires the user to add up to 10 contacts. I am trying to store them an an array or a txt file and then later I want to be able to use this input.
Here is my code. If what I'm trying to say is not clear, running the code will help.
#include <cstdlib>
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char *argv[])
{
// declare two variables;
char name[20];
int age;
string ans;
do {
// get user to input these;
cout << "What is your name: ";
cin >> name;
cout << "What is your age : ";
cin >> age;
cout<<"continue ";cin>>ans;
}while((ans == "y" || ans=="yes"));
// create output stream object for new file and call it fout
// use this to output data to the file "test.txt"
char filename[] = "test.txt";
ofstream fout(filename);
fout << name << "," << age << "\n"; // name, age to file
fout.close(); // close file
// output name and age : as originally entered
cout << "\n--------------------------------------------------------"
<< "\n name and age data as entered";
cout << "\n Your name is: " << name;
cout << "\n and your age is: " << age;
// output name and age : as taken from file
// first display the header
cout << "\n--------------------------------------------------------"
<< "\n name and age data from file"
<< "\n--------------------------------------------------------";
ifstream fin(filename);
char line[50];
fin.getline(line, 50);
char fname[20];
int count = 0;
do
{
fname[count] = line[count];
count++;
}
while (line[count] != ',');
fname[count] = '\0';
count++;
char fage_ch[10];
int fage_count = 0;
do
{
fage_ch[fage_count] = line[count];
fage_count++; count++;
}
while (line[count] != '\0');
fage_ch[fage_count] = '\0';
int fage_int = 0;
int total = 0;
char temp;
for (int i = 0; i < (fage_count); i++)
{
temp = fage_ch[i];
total = 10*total + atoi(&temp);
}
fage_int = total;
// display data
cout << "\n\n Your name is: " << fname;
cout << "\n and your age is: " << fage_int;
cout << "\n\n--------------------------------------------------------";
cout <<endl;
return EXIT_SUCCESS;
}
You would probably be better off using an array of structs instead of two seperate arrays to store the name & age for each entry. Then you can just loop through using strcpy to copy the input string from name into your struct's name. If you aren't comfortable with structs you could also use a couple of 2 dimensional arrays.
This looks like a homework assignment so I'm not going to post code, but for a basic algorithm to get you started (and hopefully simplify what you've got):
#define MAX_CONTACTS 10
#define MAX_NAME_LENGTH 20
// 2D array to store up to 10 names of max 20 character length
char nameVar[MAX_CONTACTS][MAX_NAME_LENGTH]
int ageVar[MAX_CONTACTS]
do until end of user input
read name into nameVar[index]
read age into ageVar[index]
index += 1
end loop
while contactCounter < index
ouput nameVar[contactCounter]
output age[contactCounter]
// you could also write to file in this loop if thats what you're trying to do
// using the fprintf function to write to an opened file
contactCounter += 1
end loop
Also, I'm not sure what you're trying to do with that atoi call, but it looks like it shouldn't be necessary. How atoi works is that it looks at the first character it is passed and it converts all of the digits until it encounters a non-digit character in the array. So if you have the char array c="123h" atoi would return 123. If you pass atoi "1h2" it will return 1.
Also you can use fprintf to print out both a char array and an int to a file.
So if you've got int i and char s[10] = "hello" and file stream you could print to stream like:
fprintf(stream, "my text to display: %s %i", s,i)
I hope that helps.