Disclosure: I am a student right now, so if you see any bad habits in my code, feel free to point them out. I have questions about both the ofstream and ifstream portions of my code.
In the ofstream, the user can create their own shopping list and name it (which will end up being the file name). Once their list is created, the file will save with the data.
Here my question: How do I automatically assign a file type to a file a user named? Here is my current code for it:
void createList(double price[100], double quantity[100], string item[100], double tax, int list_size) {
ofstream saved_list;
string listname;
string fileApplicator = ".txt";
cout << "What would you like to save this list as?: ";
getline(cin, listname.append(fileApplicator));
saved_list.open(listname.c_str());
As for the ofstream part of my code, I want the user to be able to select which file they want read based on the name of the file.
Here's my question: When I run the code, the file fails to open every time. I have a current file saved as safeway.txt but it will not open when I attempt it. Here is the code for it:
void reviewList(void) {
ifstream saved_list;
string listname;
string fileApplicator = ".txt";
char viewAnother = 'Y';
do {
cout << "Which list would like to open: ";
getline(cin, listname.append(fileApplicator));
saved_list.open(listname.c_str());
if (saved_list.is_open()) {
......//other code
}
cout << "Would you like to view a different list (Y/N): ";
cin >> viewAnother;
viewAnother = toupper(viewAnother);
if (viewAnother == 'N')
break;
}
else {
cout << "List not found. Please try again.\n";
}
} while (viewAnother == 'Y');
}
Solution to this problem:
getline(cin,listname.append(fileApplicator)); is the error. The append needs to be processed AFTER the getline, like this:
getline(cin,listname);
listname.append(fileApplicator);
This will allow the user to not only name a file and have it automatically saved as the programmer's desired file type but will also automatically select the desired file to be read without the user needing to enter the extension (at least on Windows OS's). I.E.: User can enter "Filename" rather than "Filename.txt".
Thank you #user4581301 and #drescherjm for helping to solve this issue!
I am a young programmer who is trying to learn c++. i have a working csv.file. but i want to search for a specific number assigned to the name and then displays the name of what i'm looking for. i have the file here:
1,Bulbasaur,grass
2,Ivysaur, grass
3,Venusaur, grass
4,Charmander, fire
5,Charmeleon, fire
6,Charizard, fire
7,Squirtle, water
8,Wartortle, water
9,Blastoise, water
Code
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream ip("pokedex.csv");
string pokedexnum[9];
string pokemonName[9];
string pokemonType[9];
cout<<"please enter a pokemon number:"<<" ";
cin>>pokemonType[0];
while (ip.good()){
getline( ip, pokedexnum[0]);
getline( ip, pokemonName[0]);
getline( ip, pokemonType[0]);
}
cout<<"the pokemon that is:"<< " "<<pokedexnum[0]<< "is the pokemon called:"<< pokemonName[0];
ifstream close("pokedex.csv");
return 0;
}
when it runs
please enter a pokemon number: 1
the pokemon that is: is the pokemon called:8,Wartortle, water
could you please point out what i am doing wrong?
Among the issues in this code:
You're not using std::getline correctly for comma-separated data. The result is each pass is consuming three lines from your input file; not three values from each line.
You're also not using ip.good() correctly as a while-condition.
You're retaining your test value in the array, which will be overwritten on the first iteration pass, so it is lost.
You're ignoring potential IO failures with each std::getline invoke.
You're overwriting slot-0 in your arrays with each loop iteration.
Minor, ifstream close("pokedex.csv"); clearly isn't doing what you think it is. That just creates another fstream object called close on the given file name.
The later may be intentional for now, but clearly broken in the near future.
In reality, you don't need arrays for any of this. All you're doing is reading lines, and seem to want to test the input number against that of the CSV data first column, reporting the line that you find, then ending this.
So do that:
Read the input value to search for.
Open the file for scanning.
Enumerate the file one line at a time.
For each line from (3), use a string stream to break the line into the comma separated values.
Test the id value against the input from (1). If the same, report the result and break the loop; you're done.
The result is something like this:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cstdlib>
int main()
{
std::cout<<"please enter a pokemon number: ";
long num;
if (std::cin >> num && num > 0)
{
std::ifstream ip("pokedex.csv");
std::string line;
while (std::getline(ip, line))
{
std::istringstream iss(line);
std::string id, name, skill;
if (std::getline(iss, id, ',') &&
std::getline(iss, name, ',') &&
std::getline(iss, skill))
{
char *endp = nullptr;
long n = std::strtol(id.c_str(), &endp, 10);
if (id.c_str() != endp && n == num)
{
std::cout << "The pokemon that is: " << num << " is called: " << name << '\n';
break;
}
}
}
}
}
Admittedly untested, but it should work.
Whether you want to store the items in arrays at this point is entirely up to you, but it isn't needed to solve the somewhat abstract problem you seem to be attempting, namely finding the matching line and reporting the name from said-same. If you still want to store them in arrays, I suggest you craft a structure to do so, something like:
struct Pokemon
{
int id;
std::string name;
std::string skill;
};
and have a single array of those, rather than three arbitrary arrays that must be kept in sync.
Four issues jump out at me:
You store the user's input into pokemonType, but then also use pokemonType for reading data from your CSV file. The file input is going to overwrite the user input.
Your file input loop always references index 0. All of the lines from your data file are going into element 0. That's the main reason that even if the user inputs 1, the output is from the last line of the data file.
Your file reading loop is structured like you want to put one part of each data line into a different array, but what you've written actually reads three lines on every iteration, storing those lines into the three different arrays.
This isn't affecting your output, but the code ifstream close("pokedex.csv"); is written like you want to close the file stream you opened, but I do believe what this line actually does is create a new ifstream called close, and opens pokedex.csv attached to it. In other words, it's just like your other line ifstream ip("pokedex.csv"); but with close as the variable name instead of ip.
You are going to want to look into something called "string tokenization". Start with some web searches, apply what you read about to your code, and of course if you hit another snag, post a new question here to Stack Overflow, showing (as you did here) what you tried and in what way it isn't working.
Elaborating on #3, here's what how your data file is being read:
at the end of the 1st iteration of the file-reading loop, ...
pokedexnum[0] is "1,Bulbasaur,grass"
pokemonName[0] is "2,Ivysaur, grass"
pokemonType[0] is "3,Venusaur, grass"
at the end of the 2nd iteration of the file-reading loop, ...
pokedexnum[0] is "4,Charmander, fire"
pokemonName[0] is "5,Charmeleon, fire"
pokemonType[0] is "6,Charizard, fire"
at the end of the 3rd iteration of the file-reading loop, ...
pokedexnum[0] is "7,Squirtle, water"
pokemonName[0] is "8,Wartortle, water"
pokemonType[0] is "9,Blastoise, water"
And that's why
<< "is the pokemon called:"<< pokemonName[0];
outputs
is the pokemon called:8,Wartortle, water
I have made a code in which data is taken from one whole file and only part of it is stored in the other file. But when I put it in loop it does not work has it should and I am having trouble locating the error can someone guide me where I am doing mistake.
Here is the things what my below written code does:
Takes user name from the user and creates the user name file then asks user if he wants to choice how many books from English book shelf he wants to choice.
NOW THE ERROR:
it does not take multiple inputs if user press 2 it only takes 1 input and copies one book no name to user file but does not do it for the next time
I MAY HAVE SOME CLUE MAYBE:
I think it maybe the get-line in using in the code, which may not be working for the second time the loop executes.
I have tried modifying my code in mostly each possible way I could, but I think may be I'm still new to programming field. So my logical thinking may be not so good. That is why I need little guidance only.
#include <fstream>
#include <iostream>
#include <cstring>
using namespace std;
string user;
int main()
{
cout<<"enter your name to create your Libaray file for book record\n";
getline(cin,user);
ofstream outFile(user.c_str(),ios::app); //user named file
string line;
ifstream inFile("English_book_shelf.txt"); //file with books name and
//number(labels)
int count,c;
cout<<"How many books do you want to buy?\n";
cin>>c;
for(int j=0;j<c;j++)
{
cout<<"Enter your choices:\n";
cin>>count;
while(count)
{
getline(inFile, line);
if (--count == 0)
{
outFile << line <<endl;
break;
}
}
}
}
I want my code to take multiple input from the user and store it in the user file.
Like if he want 3 books, the code should run copy 3 books from the book shelf file and copy it in the user file.
If he want 5 books, the code should run copy 5 books from the book shelf file and copy it in the user file and so own.
The line
if (--count == 0)
is the culprit. Simplify your code and you won't have to worry about such silly errors.
while(count >= 0)
{
getline(inFile, line);
outFile << line <<endl;
--count;
}
I am newbie.
I have got a school project that there is a header file and it has got 82 usernames. Like
char *usernames[] ={a1,a2,a3,.... a82};
char *passwords[] =[p1,p2,...p82);
And I have finished large amount of my project but still I couldn't write an usefull code for login stage.
My code has to do take username and then asking for password.
For this stage I think basicly that loop:
char *usernamecheck;
char *passwordcheck;
cout<<"Please login. \n Username\n ";
cin >> usernamecheck ;
for(int flag=0;flag<82;flag++)
{
if(usernamecheck==usernames[a]){
passwordcheck==password[a];
}
else {
}
}
cout<<"Please enter your password\n";
....
Then I will compare password taken from user and from header file.
I want to ask that point we didn't see that point on course. I have no idea how can I compare 2 char pointers. I tried to use as string but I have failed.
This:
char *usernamecheck;
...
cin >> usernamecheck ;
is going to be undefined behaviour. There is no memory associated with usernamecheck. You say:
I tried to use as string but i have failed.
So dont use old archaic, methods when there are shiny new c++ ones available:
std::string usernamecheck;
...
cin >> usernamecheck;
bool isUser = usernamecheck == username;
Done.
use std::string, its the bomb.
Live example.
So I'm working on a homework assignment for my CS162 class which requires me to make a program that allows the user to input their class plan for college. The user inputs classes they have taken, are currently taken, and/or plan on taking, with the categories of: department/class number, class name, term/year, whether or not the class is required for their major, and any additional comments. Then, the program is supposed to store this invermation with external data files so that the classes are stored and won't be lost. The program should be able to store up to 60 classes in memory.
I know how to create arrays of strucs and I know the basics behind external files, but I guess I'm having trouble combining the two (I'm a newbie here, so sorry if this is really basic!)
Here's what I have so far:
struct college_class
{
char dept_classnumber;
char class_name;
char term_year;
char is_required;
char comments;
char grade;
}
college_class[60]
int main()
{
int n;
char again;
for(n=0;n<60;n++)
{
do
{
cout<<"Enter department and class number (e.g. CS162): ";
getline (cin,college_class[n].dept_classnumber);
cout<<"Enter class name (e.g. Intro to Computer Science): ";
getline (cin,college_class[n].class_name);
cout<<"Enter the term and year the class was/will be taken: ";
getline (cin, college_class[n],term_year;
cout<<"Enter whether or not this class is required for your major: ";
getline (cin,college_class[n],is_required);
cout<<"Enter any additional comments here: ";
getline (cin, college_class[n],comments);
cout<<"Would you like to enter another class?(y/n)";
cin>>again;
}
while(again == 'y' || again == 'Y' && i<60)
}
Is this the right direction in terms of getting the user input? My other question is, how do you incorporate the external file into this so that everything the user inputs is stored into the file? Sorry if this is a little vague, and I'm obviously not looking for my homework to be done for me - I'm just looking for a little direction to get started here.
I know that writing on a text file looks like this, for example:
ofstream my file ("example");
if(myfile.is_open()))
{
myfile <<"blah blah blah. \n";
myfile.close();
}
...I'm just not sure how to make this work for arrays of structs.
There are multiple things wrong with you code.
First of all, you have to create a variable for your college_class array.
Eg.:
college_class myCollegeClass[60]
and use that when asking input
getline (cin, myCollegeClass[n].term_year;)
you accidentally used commas on some lines there, watch out for that
Furthermore, a char can only hold one character, which won't be enough if you want to hold the full class name, use strings in your struct.
struct college_class
{
string class_name;
...
}
You used a nested loop there, which will repeat your questions 60 times, regardless if you said you didn't want to input anything else.
I'd suggest
int i=0;
char again = 'y';
while(again != 'n' && again != 'N' && i<60)
{
...
i++
}
As for the file, after you have your inputs, just loop though your myCollegeClass array and write the data to the file. Eg.:
myfile << myCollegeClass[i].class_name;