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();
}
Related
in my program I am attempting to input characters from a .txt file and assign them to a 2D Char array to form a Maze. The expected outcome of this code is:
xxxxxxx
xA...Bx
xxxxxxx
However I am instead warned that Column is greater than size (defined as 30) when I believe it should be 0 at the start of every loop. No matter what Column is equal to Size and im not sure why. I've included the code below. I am beginner programmer so if you have any advice could you please make it as simple as possible.
Many thanks,
Ben
#include<fstream>
#include<iostream>
#include<string>
#include <vector>
//Maze Size
#define SIZE 30
using namespace std;
void readMaze(string fileName);
void inputMaze();
int main()
{
inputMaze();
}
void readMaze(string fileName)
{
int rows;
int columns = 0;
//vector<vector<char>> maze;
char maze[SIZE][SIZE];
ifstream input(fileName);
char data;
while (input.get(data)) //While loop used to store each individual data to the string.
{
for (int rows = 0; rows < 20; rows++)
{
columns = 0;
while (data != '\n')
{
if (rows > SIZE)
{
cout << "ROWS GREATER THAN SIZE";
break;
}
else if (columns > SIZE)
{
cout << "COLUMNS GREATER THAN SIZE";
break;
}
else
{
maze[rows][columns] = data;
columns++;
data = input.get();
}
}
data = input.get();
}
}
cout << "The Maze being solved is: " << endl;
cout << maze << endl;
input.close();
}
void inputMaze()
{
string userinput;
cout << "Plese input a .txt file name" << endl;
cin >> userinput; //User inputs the name of a .txt file --> goes to readMaze()
readMaze(userinput);
}
rows is used uninitialized in readMaze so the program has undefined behavior. Also, cout << maze << endl; makes the program have undefined behavior by reading out of bounds.
Consider making maze a std::vector<std::vector<char>> or even a std::vector<std::string> to make it simpler.
Example:
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
std::vector<std::string> readMaze(std::istream& input) {
std::vector<std::string> maze;
std::string line;
while(std::getline(input, line)) { // read a complete line at a time
maze.push_back(line); // and save it in the vector
}
return maze;
}
void inputMaze() {
std::string userinput;
std::cout << "Plese input a .txt file name\n";
if(std::cin >> userinput) {
std::ifstream is(userinput);
if(is) {
auto maze = readMaze(is);
std::cout << "The Maze being solved is:\n";
std::copy(maze.begin(), maze.end(),
std::ostream_iterator<std::string>(std::cout, "\n"));
}
// the file will be closed automatically when "is" goes out of scope
}
}
int main() {
inputMaze();
}
I wrote a code to populate an array from a file
and then use that array to compare it with the user input
The program should ask the user to enter a name or partial name to search for in the
array
here is the code:
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;
int main()
{
bool found = false;
const int arraySize = 35;
const int length = 100;
char contacts[arraySize][length];
int count = 0; // Loop counter variable
ifstream inputFile; // Input file stream object
inputFile.open("input.txt"); // Open the file.
// Read the numbers from the file into the array.
// After this loop executes, the count variable will hold
// the number of values that were stored in the array.
while (count < arraySize && inputFile >> contacts[count])
count++;
// Close the file.
inputFile.close();
char search[length];
char *fileContact = nullptr;
int index;
cout << "To search for your contact's number \nplease enter a name or partial name of the person.\n";
cin.getline(search, length);
for (index = 0; index < arraySize; index++)
{
fileContact = strstr(contacts[index], search);
if (fileContact != nullptr)
{
cout << contacts[index] << endl;
found = true;
}
}
if (!found) cout << "Sorry, No matches were found!";
return 0;
}
and the names in the file are
"Alejandra Cruz, 555-1223"
"Joe Looney, 555-0097"
"Geri Palmer, 555-8787"
"Li Chen, 555-1212"
"Holly Gaddis, 555-8878"
"Sam Wiggins, 555-0998"
"Bob Kain, 555-8712"
"Tim Haynes, 555-7676"
"Warren Gaddis, 555-9037"
"Jean James, 555-4939"
"Ron Palmer, 555-2783"
so the code works, but the problem is
when I write Alejandra for example
the output is: "Alejandra
the output is supposed to show the full name and the number:
"Alejandra Cruz, 555-1223"
does anyone know how to fix this?
thanks!!
When you use
inputFile >> contacts[count]
Leading whitespace characters are discarded.
Non-whitespace characters are read into contants[count].
Reading stops when a whitespace character is encountered.
That explains your output.
You need to use istream::get instead.
while (count < arraySize && inputFile.get(contacts[count], length) )
count++;
In response to OP's comment
The above should all the lines of the file up to arraySize number of lines.
You could add some debugging output to troubleshoot the problem.
while (count < arraySize && inputFile.get(contacts[count], length) )
{
std::cout << "Read " << count+1 << "-th line.\n" << "\t" << contants[count] << "\n";
count++;
}
Let's say I have a text file:
83 71 69 97Joines, William B.
100 85 88 85Henry, Jackson Q.
And I want to store each number in an array of ints, and each full-name into an array of strings (a full name would be Joines, William B for example).
What would be the best way, because I debated whether using while (inputFile >> line) or while (getline(inputFile, line)) would be better. I don't know if it would be easier to read them one word at a time or read them one line at a time. My main problem will be splitting the 97Joines, William B. to 97 and Joines, William B. which I don't understand how to do in C++.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main() {
int counter = 0;
int scores[40];
string names[10];
string filename, line;
ifstream inputFile;
cout << "Please enter the location of the file:\n";
cin >> filename;
inputFile.open(filename);
while (inputFile >> line) {
// if line is numeric values only, do scores[counter] = line;
// if it is alphabet characters only, do names[counter] = line;
//if it is both, find a way to split it // <----- need help figuring out how to do this!
}
inputFile.close();
}
You need to #include <cstdlib> for strtol I am sure there are better ways to do this but this is the only way I know and this is only for 97joines, and 85Henry,
string word; // to get joines,
string str; // for 97
string numword;
inputFile >> numword;
for(int k = 0; k < numword.length(); k++)
{
if(isdigit(numword[k]))
{
str = str + numword[k];
}
else
{
word = word + numword[k];
}
}
int num = strtol(str.c_str(), NULL, 0);
You can, given the file structure you have shown, read it like this:
int a, b, c, d;
std::string name;
for (int i = 0; i < 2; ++i)
{
// read the numbers
inputFile >> a >> b >> c >> d;
// read the name
std::getline(inputFile, name);
// do stuff with the data... we just print it now
std::cout << a << " " << b << " " << c << " " << d << " " << name << std::endl;
}
Since the numbers are space separated it is easy to just use the stream operator. Furthermore, since the name is the last part we can just use std::getline which will read the rest of the line and store it in the variable name.
You can try it here, using std::cin.
I'm currently trying to program a word counting program in C++ and am running into difficulties getting it to parse through a string and separate words from one another. In addition to this I am having a hard time getting the word count for unique words to increment each time the word repeats. My findWord() and DistinctWords() functions are most likely the issues from what I can tell. Perhaps you will see something I do not though in the others, as for the aforementioned functions I have no clue as to what's messing up in them. These are the directions provided by my instructor:
Create a program which will count and report on the number of occurrences of distinct, case insensitive words in a text file.
The program should have a loop that:
1.Prompts the user to enter a file name. Terminates the loop and the program if the user presses the Enter key only.
2.Verifies that a file with the name entered exists. If the file does not exist, display an appropriate message and return to step 1.
3.Reads and displays the contents of the file.
4.Displays a count of the distinct words in the file.
5.Displays a sorted list of each of the distinct words in the file and the number of occurrences of each word. Sort the list in descending order by word count, ascending order by word.
I am pretty stuck right now and my assignment is due at midnight. Help would certainly be greatly appreciated. Thank you for your time. Here is the code I have, I will also copy paste an example test text file after it:
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream> // Needed to use files
#include <vector>
#include <algorithm> // Needed for sort from standard libraries
using namespace std;
struct WordCount{
string word; // Word
int count; // Occurence #
void iCount(){ count++; }
WordCount(string s){ word = s; count = 1;}
};
// Function prototypes
string InputText(); // Get user file name and get text from said file
string Normalize(string); // Convert string to lowercase and remove punctuation
vector<WordCount> DistinctWords(string); // Sorted vector of word count structures
bool findWord(string, vector<WordCount>); // Linear search for word in vector of structures
void DisplayResults(vector<WordCount>); // Display results
// Main
int main(int argc, char** argv) {
// Program Title
cout << "Lab 9 - Text File Word Counter\n";
cout << "-------------------------------\n\n";
// Input text from file
string buffer = InputText();
while (buffer != ""){
// Title for text file reading
cout << "\nThis is the text string read from the file\n";
cout << "-------------------------------------------\n";
cout << buffer << endl << endl;
// Build vector of words and counts
vector<WordCount> words = DistinctWords(buffer);
// Display results
cout << "There are " << words.size() << " unique words in the above text." << endl;
cout << "--------------------------------------------" << endl << endl;
DisplayResults(words);
buffer = InputText();
}
return 0;
}
/***********************************************
InputText() -
Gets user file name and gets text from the file.
************************************************/
string InputText(){
string fileName;
ifstream inputFile; // Input file stream object
string str; // Temporary string
string text; // Text file string
cout << "File name? ";
getline(cin, fileName);
// Case to terminate the program for enter key
if (fileName.empty()){ exit(0);}
// Open file
inputFile.open(fileName);
if (!inputFile){
cout << "Error opening data file\n";
cout << "File name? "; cin >> fileName;
}
else{
while (!inputFile.eof()){
getline(inputFile, str);
text += str;
}
}
inputFile.close(); return text;
}
/****************************************************
Normalize(string) -
Converts string to lowercase and removes punctuation.
*****************************************************/
string Normalize(string s){
// Initialize variables
string nString;
char c;
// Make all text lowercase
for (int i = 0; i < s.length(); i++){
c = s[i];
c = tolower(c);
nString += c;
}
// Remove punctuation
for (int i = 0; i < nString.length(); i++){
if (ispunct(nString[i]))
nString.erase(i, 1);
}
// Return converted string
return nString;
}
/******************************************
vector<WordCount> DistinctWords(string) -
Sorts vector of word count structures.
*******************************************/
vector<WordCount> DistinctWords(string s){
vector<WordCount> words; // Initialize vector for words
string nString = Normalize(s); // Convert passed string to lowercase and remove punctuation
// Parse string
istringstream iss(nString);
while(iss >> nString){
string n; // Intialize temporary string
iss >> n; // Put word in n
if (findWord(n, words) == true){ continue; } // Check to verify that there is no preexisting occurence of the word passed
else{
WordCount tempO(n); // Make structure object with n
words.push_back(tempO); // Push structure object into words vector
}
}
return words;
}
/*********************************************
bool findWord(string, vector<WordCount>) -
Linear search for word in vector of structures
**********************************************/
bool findWord(string s, vector<WordCount> words){
// Search through vector
for (auto r : words){
if (r.word == s){ // Increment count of object if found again
r.iCount(); return true;
}
else // Go back to main function if not found
return false;
}
}
/***********************************************
void DisplayResults(vector<WordCount>) -
Displays results.
************************************************/
void DisplayResults(vector<WordCount> words){
// TROUBLESHOOT FIRST ERASE THIS AFTER!!!!!
cout << "Word" << setw(20) << "Count\n";
cout << "-----------------------\n";
for (auto &r : words){
cout << setw(6) << left << r.word;
cout << setw(15) << right << r.count << endl;
}
}
It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to heaven, we were all going direct the other way - in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.
This is the example display he provided for this particular test file
You almost had it!
You just forgot to pass the 'words' vector by reference instead of by copy.
Also I included a custom comparator for the sort at the end.
#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>
#include <fstream> // Needed to use files
#include <vector>
#include <algorithm> // Needed for sort from standard libraries
using namespace std;
struct WordCount{
string word; // Word
int count; // Occurence #
void iCount(){ count++; }
WordCount(string s){ word = s; count = 1;}
};
struct {
bool operator()(const WordCount& a, const WordCount& b)
{
if (a.count < b.count)
return false;
else if (a.count > b.count)
return true;
else{
if (a.word < b.word)
return true;
else
return false;
}
}
} CompareWordCount;
// Function prototypes
string InputText(); // Get user file name and get text from said file
string Normalize(string); // Convert string to lowercase and remove punctuation
vector<WordCount> DistinctWords(string); // Sorted vector of word count structures
bool findWord(string, vector<WordCount>&); // Linear search for word in vector of structures
void DisplayResults(vector<WordCount>); // Display results
// Main
int main(int argc, char** argv) {
// Program Title
cout << "Lab 9 - Text File Word Counter\n";
cout << "-------------------------------\n\n";
// Input text from file
string buffer = InputText();
while (buffer != ""){
// Title for text file reading
cout << "\nThis is the text string read from the file\n";
cout << "-------------------------------------------\n";
cout << buffer << endl << endl;
// Build vector of words and counts
vector<WordCount> words = DistinctWords(buffer);
// Display results
cout << "There are " << words.size() << " unique words in the above text." << endl;
cout << "--------------------------------------------" << endl << endl;
DisplayResults(words);
buffer = InputText();
buffer = "";
}
return 0;
}
/***********************************************
InputText() -
Gets user file name and gets text from the file.
************************************************/
string InputText(){
string fileName;
ifstream inputFile; // Input file stream object
string str; // Temporary string
string text; // Text file string
cout << "File name? ";
getline(cin, fileName);
// Case to terminate the program for enter key
if (fileName.empty()){ exit(0);}
// Open file
inputFile.open(fileName);
if (!inputFile){
cout << "Error opening data file\n";
cout << "File name? "; cin >> fileName;
}
else{
while (!inputFile.eof()){
getline(inputFile, str);
text += str;
}
}
inputFile.close(); return text;
}
/****************************************************
Normalize(string) -
Converts string to lowercase and removes punctuation.
*****************************************************/
string Normalize(string s){
// Initialize variables
string nString;
char c;
// Make all text lowercase
for (int i = 0; i < s.length(); i++){
c = s[i];
c = tolower(c);
if (isalpha(c) || isblank(c))
nString += c;
}
// Return converted string
return nString;
}
/******************************************
vector<WordCount> DistinctWords(string) -
Sorts vector of word count structures.
*******************************************/
vector<WordCount> DistinctWords(string s){
vector<WordCount> words; // Initialize vector for words
string nString = Normalize(s); // Convert passed string to lowercase and remove punctuation
// Parse string
istringstream iss(nString);
string n; // Intialize temporary string
while(iss >> n){
if (findWord(n, words) == true){ continue; } // Check to verify that there is no preexisting occurence of the word passed
else{
WordCount tempO(n); // Make structure object with n
words.push_back(tempO); // Push structure object into words vector
}
}
return words;
}
/*********************************************
bool findWord(string, vector<WordCount>) -
Linear search for word in vector of structures
**********************************************/
bool findWord(string s, vector<WordCount>& words){
// Search through vector
for (auto& r : words){
if (r.word.compare(s) == 0){ // Increment count of object if found again
r.iCount(); return true;
}
}
}
/***********************************************
void DisplayResults(vector<WordCount>) -
Displays results.
************************************************/
void DisplayResults(vector<WordCount> words){
// TROUBLESHOOT FIRST ERASE THIS AFTER!!!!!
cout << "Word" << setw(20) << "Count\n";
cout << "-----------------------\n";
sort(words.begin(), words.end(),CompareWordCount);
for (auto &r : words){
cout << setw(6) << left << r.word;
cout << setw(15) << right << r.count << endl;
}
}
Consider using map for word count task
int main()
{
map<string, int> wordCount;
vector<string> inputWords = {"some", "test", "stuff", "test",
"stuff"}; //read from file instead
for(auto& s: inputWords)
wordCount[s]++; //wordCount itself
for(auto& entry: wordCount) //print all words and assosiated counts
cout << entry.first << " " << entry.second <<endl;
cout <<wordCount.size() <<endl; //thats number of distinct words
}
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.