Converting the name of a file into a c-string - c++

I am trying to open a .dat file to use as an input for my program. The assignment says I need to convert the name I enter for the file name into c-string datatype so it can be read through the .open("") command. My program compiles but I'm sure I'm doing something wrong when I try to convert file name. I have looked around for people with similar problems but I've had no luck so any suggestions you can give me would be much appreciated!
Here is the function where I attempt to open the file, and the other function where I try to convert the file name.
int main()
{
ifstream fp;
string name[SIZE], filename;
int counter, idx = 0;
float rate[SIZE], sum[SIZE], gross[SIZE], with[SIZE], pay[SIZE], net[SIZE], hours[SIZE];
getfile(fp, filename);
readFile(fp, name, rate, hours);
pay[SIZE] = calcPay(rate, sum);
gross[SIZE] = calcGross(pay);
with[SIZE] = calcAmount(gross);
net[SIZE] = calcNet(gross, with);
output(name, rate, sum, with, gross, net, pay, SIZE);
return 0;
}
//Convert filename into C-string
string convert(ifstream &fp, string filename)
{
fp.open(filename.c_str());
return filename;
}
//Get file name from user.
void getfile(ifstream &fp, string filename)
{
cout <<" Enter the name of the file: ";
cin>>filename;
convert(fp, filename);
fp.open("filename");
if (!fp)
{
cout<<"Error opening file\n";
exit (1);
}
}

cout <<" Enter the name of the file: ";
cin>>filename;
convert(fp, filename);
fp.open("filename");
was probably meant to be (in case of present C++11 support):
cout << " Enter the name of the file: ";
cin >> filename;
fp.open(filename);
or (in C++03):
cout << " Enter the name of the file: ";
cin >> filename;
fp.open(filename.c_str());
Side note: Elements in an array are indexed from 0 to SIZE - 1 so when you declare:
float pay[SIZE];
then when you do:
pay[SIZE] = calcPay(rate, sum);
you are accessing memory "pass" the last element, which causes undefined behavior.

Related

Cannot open text file in Visual Studio Community 2017 v.15.7.6 - tried everything

I am trying to read coordinates from a text file to initialize a 2d array, stored here in a custom object called boolMatrix. However, I cannot for the life of me get Visual Studio to find my file, names data.txt. I have changed the directory, added the file in every way imaginable, and even tried using the file path. Nothing has worked. Here is the function that is supposed to initialize the boolMatrix object matrix1 to the values stored in data.txt:
void setMatrix(boolMatrix &matrix1) {
ifstream inFile;
string filename = "data.txt";
inFile.open(filename);
while (filename != "quit") {
if (inFile) {
int a, b;
while (inFile >> a >> b) {
matrix1.set(a, b, true);
}
inFile.close();
}
else {
cout << "Error, couldn't open file." << endl;
inFile.close();
cout << "Enter the name of the file (type ""quit"" to quit): ";
cin >> filename;
inFile.open(filename);
}
}
}

Am I passing parameters correctly?

I'm trying to get the function getFilename to prompt the user for which file to read and then pass that to the function readFile which calculates the numbers in the file and then (using displayAverage) display the average of the numbers in the file.
I'm new to coding and can't figure out why it doesn't seem to be using the readFile function... the program prompts the user for the file but after that it just inputs a blank line. Am I calling the functions & passing the parameters correctly?
void getFilename(char fileName[])
{
cout << "Please enter the filename: ";
cin >> fileName;
return;
}
float readFile(char fileName[])
{
cout.setf(ios::fixed);
cout.precision(0);
ifstream fin(fileName);
int sum = 0;
int numValue = 0;
float grades = 0;
float average= 0;
if (fin.fail())
{
cout << "Error opening file \"" << fileName << "\"";
return false;
}
while (!fin.eof())
{
fin >> grades;
sum += grades;
numValue++;
if (numValue != 10)
cout << "Error reading file \"" << fileName << "\"";
}
fin.close();
average = sum / 10;
return average;
}
void displayAverage(int average)
{
cout << average;
return;
}
int main()
{
char* fileName;
int average;
getFilename(fileName);
readFile(fileName);
displayAverage(average);
return 0;
}
Your program has undefined behaviour since fileName does not point to anything valid that can hold data.
Unless you are required to use an array of chars to hold the filename, use std::string for fileName.
std::string fileName;
If you are required to use an array of chars to hold the filename, use
char fileName[FILENAME_LENGTH];
Make sure FILENAME_LENGTH is large enough for your needs.

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'

C++ ask user for file name, if they enter nothing how do i correctly re-prompt

creating a program that will prompt user until the given file exist, so far if the file exist it re-prompts them. but when i prompt the user for a file name, and they decide to press enter all i get is white space until i enter characters. how would it be possible to re-promt when user decides to enter nothing.
while(fileName.empty())/*********************/
{
cout<<"Enter file name: ";
cin>> fileName;
}
^attempt of re-prompting when given an empty string^
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string line;
ifstream inData;
ofstream outData;
string fileName = " ";
char digit;
float num[1000];
float sum[10];
int num_count;
int i = 0;
float user_num,tot,result;
/*Program will ask user for file name, read the file
sum the first 3 numbers of the file, then will prompt
the user for a fourth number in which it will sum all
numbers and print the average*/
while(fileName.empty())/*********************/
{
cout<<"Enter file name: ";
cin>> fileName;
}
inData.open(fileName.c_str());
/*outData.open(fileName.c_str());*/
while(!inData.is_open())
{
cout<<"Please enter a valid file name or path: ";
cin>>fileName;
inData.open(fileName.c_str());
}
if (inData.is_open())
{
while (inData.good())
{
inData >> digit;
num[i] = digit - '0';
i++;
num_count = i - 1;
}
inData.close();
cout<<"Enter fourth number: ";
cin>> user_num;
num[3] = user_num;
for(int a = 0; a <= 3; a++)
{
tot += num[a];
}
result = tot/4.0;
cout<<"The average of the four numbers is: "<<result<<'\n';
}
return 0;
}
here is my test file
jim.txt
2 44 3
Try to use getline instead of operator<< like this;
while (fileName.empty())
{
cout << "Enter file name: ";
char c[255];
cin.getline(c, 255);
fileName = string(c);
}
ps: Just noticed comment from #DawidPi with the same suggestion :)
Your while loop with checking emptiness will not be executed (even a single time) as you initialized fileName with " " (so it's not empty). Use do...while() or simply do not initialize std::string (there is no need for it.)

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.