How to add more than one user input to an array? - c++

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.

Related

How do I store data in arrays from input file?

I am asked to write a program that grades students' answers to multiple-choice questions. The key and the students’ answers are stored in a file.
In the input file, there are repetitions of the following:
A name in a line followed by 15 answers, one per line (1 A, 2 D etc.)
I don't know how to store input data in two separate arrays: Key[14] and StudentAnswers[14]. For example, if the name is "Key", the following 15 lines are supposed to be stored into Key[14] array, and StudentAnswers[14] if otherwise.
The following is mainline, and any suggestions will be greatly appreciated!
#include <iostream>
#include <fstream>
#include <string>
int main()
{
const int MAX = 15;
std::ifstream InputFile;
std::string Name;
int QuestionNumber;
char Answer;
char Key[MAX];
char StudentAnswer[MAX];
char Mark[MAX];
while (! InputFile.eof())
{
std::getline(InputFile, Name);
std::cout << Name << "\n";
if (Name == "zzz")
break; // Read answers wether key or students' answers
for (int i = 0; i < MAX; ++i)
{
// If the name is key, store these in Key array
// else store them in StudentAnswer array
InputFile >> QuestionNumber >> Answer;
std::cout << QuestionNumber << " " << Answer << "\n";
}
// If the name is not key, then grade it
// To grade it, go thru whole array compare Key[i] w/ StudentAnswer[i]
// if same set Mark[i] = ' '
// else set Mark[i] = 'X';
// Print result
}
std::string Junk;
std::getline(InputFile, Junk);
}
InputFile.close();
OutputFile.close();
}

Reading several types of data into arrays

I am having a tough time figuring out the process of reading text files into the program. Down in the get_answer_key_array, I am trying to read and put only the top line of the text file into an array.
The text file looks something like this:
ABDBCBDBABABCBABCB
Bob Bobby adcad abcbd bacb
Every text file tested in this program will have the answer key on the first line. Every line after the first line will have the persons first name, space, last name, space, grades and missing grades will be replaced by a "-" when I get to it.
I am currently working on obtaining the first line and putting it into the answer key array.
I know that once I am done with the first line I can put the persons first name, last name, and answers into three separate parallel arrays. I am having trouble coming up with the right way to check for that first new line so I can get the answer key.
Alright so now I have changed my get_answer_key_array to obtain all of the arrays I will need. Currently I am trying to get the top line (the answer key) into the first array of answer_key[]. I have tried to implement the getline function but am trying to figure out how to only get the top line. Is it possible to keep my eof() loop yet stop at the first endline to transferthe data of the first line into the array? Also my
answer_key[i] = key; needs changed to something else I bet!
I should also mention once I figure out how to get the top line into an array, I want to use this process to get the rest of the data (names and answers) into their own separate arrays via the following workflow:
in_stream >> first_name[i] >> last_name[i] >> answers[i];
while(!in_stream.eof() ) {
i++;
in_stream >> first_name[i] >> last_name[i] >> answers[i];
}
in_stream.close();
START OF PROGRAM BELOW
void get_input_file(ifstream &in_stream); //gets the text file name from the user
void get_arrays(ifstream &in_stream, int answer_key[], string first_name[], string last_name[], int answers[], int &count); //brings the data from text file into all of the parallel arrays
//void score_grader(int &target, string first_name[], string last_name[], int answers[], int &count, int &score);
//void letter_grade(int &score, int &letter_grade);
//void student_report(int &target, string first_name[], string last_name[], int answers []);
int main()
{
ifstream in_stream;
int answer_key[30], count = 0, score = 0; //initializing the answer key array up to 30 answers
string first_name[20]; //initializing the first name array
string last_name[20]; //initializing the last name array
int answers[30]; //initializing the answers array
cout << "Welcome to the Test Grader." << endl; //welcome message
get_input_file(in_stream); //function call to get the file name
get_arrays(in_stream, answer_key, first_name, last_name, answers, count); //function call to create the arrays
}
void get_input_file(ifstream &in_stream) {
string file_name; //initializing the file name string
do {
cout << "Enter the file name you would like to import the data from: " << endl; //asks user to input name of file
cin >> file_name; //user types name of file
in_stream.open(file_name.c_str()); //program opens the stream
if(in_stream.fail()) {
cout << "Error finding file, try again.\n"; //if failed, asks user for file name again
continue; //continues back to the do loop
}
break;
} while(true);
cout << "File Obtained: " << file_name << endl; //alerts user of file success with printed name
}
void get_arrays(ifstream &in_stream, int answer_key[], string first_name[], string last_name[], int answers[],
int &count) {
int i = 0;
string key; //This will be the storage variable for the first line of text file
if (in_stream.is_open() ) { //if the stream is open
getline(in_stream, key);
cout << "Testing: " << key << endl;
while(!in_stream.eof() ) {
i++;
in_stream >> first_name[i] >> last_name[i] >> answers[i];
}
}
cout << first_name[1] << " " << last_name[1] << " " << answers[1] << endl;
in_stream.close();
}
You can simply read the first line this way
void get_answer_key_array(ifstream &in_stream, char *answer_key, int &count) {
in_stream >> answer_key;
count = strlen(answer_key);
}
The answer_key array must be of type char.
And the endline character is '\n' not '/n'

How to read spaced string with get line() from a file?

I want to read a name like "Penelope Pasaft" all together from a file and save it to a variable "person". I have understood that I have to use the get line(file, person). But I have a problem doing it because I want also to read other variables before.
Imagine a .txt like:
1
+546343864246
Penelope Pasaft
So here is the code:
typedef struct {
string number; //I use string because it is an alphanumeric cellphone number
string person;
int identifier;
} cellphone;
ifstream entry;
entry.open(fileName.c_str());
cellphone c[10];
int j=0;
if(entry)
{
cout << "The file has been successfully opened\n\n";
while(!entry.eof())
{
entry >> c[j].identifier >> c[j].number;
getline(entry,c[j].person);
cout << "Start: " << c[j].identifier << "\nNumber: " <<
c[j].number << "\nPerson: " << c[j].person << endl << endl;
j++;
}
}
Well the problem I have it's that it doesn't seem to print or save me any data to the variable c[j].person
Problem is that your input file has empty lines in it.
If you use cin >> only, it will work OK because >> operator skips blank chars (but stops at blank chars, as you noted: can't have it all)
On the other hand, getline will read the line, even if it's blank.
I propose the following standalone code slightly modified from yours: note the loop until end of file or non-blank line.
(note: it there are spaces only in the line, it will fail)
I also replaced array by a vector, resized on the fly (more C++-ish)
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
using namespace std;
typedef struct {
string number; //I use string because it is an alphanumeric cellphone number
string person;
int identifier;
} cellphone;
int main()
{
ifstream entry;
string fileName = "file.txt";
entry.open(fileName.c_str());
vector<cellphone> c;
cellphone current;
int j=0;
if(entry)
{
cout << "The file has been successfully opened\n\n";
while(!entry.eof())
{
entry >> current.identifier >> current.number;
while(!entry.eof())
{
getline(entry,current.person);
if (current.person!="") break; // stops if non-blank line
}
c.push_back(current);
cout << "Start: " << c[j].identifier << "\nNumber: " << c[j].number << "\nPerson: " << c[j].person <<endl<<endl;
j++;
}
}
return 0;
}
output:
The file has been successfully opened
Start: 1
Number: +546343864246
Person: Penelope Pasaft

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

Text file parsing C++

I have been trying to parse through a text file in c++ to read the numbers that are contained within the file. The number of integers on each line and the number of lines is not know. When all the integers are read they will save that integer followed by a ',' and the running total of that line. This will then be outputted to a file chosen by the user. The code I have written is as follows:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
int i=0,b = 0,num = 100;
int *s1;
string myfilename, mystring, filename;
cout << "Enter the name of the file to open:" << endl;
cin >> myfilename;
cout << "Enter the name of the output file" << endl;
cin >> filename;
ifstream inFile;
ofstream outFile("C:\\Users\\Aidan Howie\\Documents\\University\\Second Year\\C++\\" + filename + ".txt");
inFile.open("C:\\Users\\Aidan Howie\\Documents\\University\\Second Year\\C++\\" + myfilename + ".txt");
if (!inFile)
{
cout << "Cannot open file" << endl;
return -1;
}
while (!inFile.eof())
{
s1 = new int[num];
for (i = 0; i < s1; i++)
{
cout << i << "," << (i + b) / s1;
b = i+b;
cout << endl;
}
}
inFile.close();
system("PAUSE");
}
However receive the error:
error C2446: '<' : no conversion from 'int *' to 'int'
Can anyone explain how to fix this and whether there is an easier way for me to read the unknown integers on the file
s1 is a pointer to an int, while i is an int. So essentially what you're doing is checking if 6 < 0x55ddab.
The right way to do it is: i < *s1
Also, don't forget to delete s1 before your while loop repeats.
Also, I'm just going to put a note that what you're doing makes no sense, nonetheless, using i < *s1 will fix your error.
s1 is an array of ints, which means that when you use the name s1 without an index, it is a pointer. Therefore, your comparison of i < s1 is asking if i is less than the address of s1, and that's not a valid comparison. Your line of code should look like this:
for (i = 0; i < num; i++)
Also, inFile.eof() isn't doing what you think it is. The only way you're going to get an EOF on inFile is if the user types ctrl+D. You should have the user enter some sentinel value to signal the end of input; for example, 0 or -1 or some other otherwise invalid value.