Reading a text file and saving every line as a string (C++) - c++

I have a little question. I'm currently doing a school assignment in c++ and the task is to have something similar to a small library, where the user can ask to look at a book and then the program will print out the release year, author, how many pages etc etc. The assignment is focused on vectors and arrays, but I thought a smart way of doing it could be to have the release years in a text file and then save those years in an array. When I first it, everything was saved in characters, (meaning "1","8","8","5"), when I'd actually like it to save every line in the text document as a string in the array, or something similar (like this: "1885",). I couldn't really figure out how to split them up into strings then. I then talked a bit to a friend and this is where I am with my code now, it's not really working and at the moment I have no idea how I am supposed to solve it. Main problem is I don't know how to read and save every line in the text document as a string, however I am grateful for any help that would make me be able to print out a single year from the text document, in any other way.
This is what my code looks like:
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <istream>
using namespace std;
void book();
void readFile(int input);
void oddEven();
void stringLiner();
void factorial();
int main()
{
int input;
while (input != 0)
{
cout << "Hello. Welcome to the first, truly big, assignment in this programming course." << endl;
cout << "Which part do you wish to access?" << endl;
cout << "1. Book program" << endl;
cout << "2. 2 arrays - One EVEN ~ One ODD" << endl;
cout << "3. The one at a time string" << endl;
cout << "4. Factorial array" << endl;
cout << "0. Exit " << endl;
cin >> input;
switch (input)
{
case 1:
book();
break;
}
}
}
void book() //This is the function used to do the book thing
{
cout << string( 100, '\n' );
int input;
string year[5] = {"1883"/*Treasure Island*/ }; //Array for the years the books were written
string author[5] = {"Robert Louis Stevenson"/*Treasure Island*/, "yollo"}; //Array for the authors
string pages[5] = {"304"/*Treasure Island*/,"420" }; //Array for the number of pages
string books[5] = {"Treasure Island", "Swagolo" }; //Array for the name of the books
cout << "You have chosen to look at books." << endl;
cout << "These are the books in the library. Pick one to see what year it was written in, what author wrote it and how many pages it contains. " << endl;
cout << "These are the books in the library: " << endl;
for (int i = 0; i<5; i++) //Loop to display all the books + what number to press to access them.
{
cout << i+1 << " " << books[i] << endl;
};
cout << "Please type a number to look at that book. " << endl;
cin >> input;
int TresIsl = input-1;
switch (input) //Switch case to chose which book to look at.
{
case 1: //Info about Treasure Island
cout << "This is " << books[TresIsl] << " and this is some info. " << endl << endl;
cout << books[TresIsl] << " was released in " ;
readFile(input);
cout << " and it was written by " << author[TresIsl] << ". ";
cout << "This book contains " << pages[TresIsl] << " pages. " << endl;
break;
case 2:
cout << "This is " << books[TresIsl] << " and this is some info. " << endl << endl;
cout << books[TresIsl] << " was released in " ;
readFile(input);
cout << " and it was written by " << author[TresIsl] << ". ";
cout << "This book contains " << pages[TresIsl] << " pages. " << endl;
break;
}
}
void readFile(int input)
{
ifstream file("year.txt");
int numlines = 0;
int numMaxLines = 5;
vector<string> lines (numMaxLines);
while(numlines < numMaxLines && !file.eof())
{
getline(file, lines);
numlines++;
}
cout << lines[input];
}
The other void functions are for other tasks in this assignment which I didn't include now, I just copy pasted the code where they were included. Also please don't mind the slightly childish stuff in the code.
Also I am very sorry if this breaks any rules for the forum or something similar. I tried to find another topic like this for c++, but I couldn't find anything helpful.

It's not clear what exactly your problem is, but assuming that you want to read a file line-by-line and get a vector of those lines, something like this would do it:
std::vector<std::string> readLines(const std::string& filename)
{
std::vector<std::string> lines;
std::ifstream input(filename);
std::string line;
while (std::getline(input, line))
{
lines.push_back(line);
}
return lines;
}

if any one's still got a question, a friend and me discussed it and he helped me a bit, and we got a code that works in my case at least, so I thought I'd show it to you:
void readFile(int input)
{
ifstream file("year.txt");
string in;
vector<string> lines;
if (file.is_open())
{
while ( getline (file, in) )
{
lines.push_back(in);
}
cout << in;
}
file.close();
cout<<lines[input-1]<<endl;
}
The cout in the end I guess is unnecessary in some cases, but this worked for me and my homework. Thanks for everyone's help anyways.

Related

issues with getline overload function

I am having issues with cin.getline(). When I put it into the below program, it is giving an error:
no instance of overload function (ect) matches the argument list
I am also having an issue with my variable nx. The compiler says that it cannot be a constant, but I'm not sure how it is.
Here is my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
//create a class for one book
class Book
{
//member variables
public:
string title;
string author;
int year;
//function to print the book details
void print()
{
cout << "Title: " << title << endl;
cout << "Authot: " << author << endl;
cout << "Year: " << year << endl;
}
};
int main()
{
std::string filename, temp;
//prompt the user to enter the file name
cout << "Enter filename: ";
cin >> filename;
//open the file
fstream file;
file.open(filename.c_str());
int nx;
//read the first line of the file to know the number of books
file >> nx;
//move to the next line of the file
std::cin.getline(file, temp);
//allocate an array of n Book
Book books[nx];
//read the data for n books from the file
for (int i = 0; i < nx; i++)
{
//read file and initialize the books array
std::cin.getline(file, books[i].title);
std::cin.getline(file, books[i].author);
file >> books[i].year;
//move to the next line of the file
getline(file, temp);
}
//Display the output
cout << "Books found: " << nx << endl;
for (int i = 0; i < nx; i++)
{
cout << "\nBook " << i + 1 << ":" << endl;
cout << "Title: " << books[i].title << endl;
cout << "Author: " << books[i].author << endl;
cout << "Year: " << books[i].year << endl;
}
}
The 2-parameter std::cin.getline() method does not take a std::fstream or a std::string as parameters. It takes a char* and a std::streamsize instead, as it is meant to fill a char[] buffer. To fill a std::string from a stream, you need to use the standalone std::getline() function instead, eg:
std::getline(file, temp);
...
std::getline(file, books[i].title);
...
As for the "constant" error relating to your nx variable, the problem is on this line:
Book books[nx];
You are trying to declare a fixed-sized array using a size that is not known until runtime. You can't do that in standard C++, an array's size must be known at compile-time instead. Otherwise, you have to use new[] or std::vector to allocate the array dynamically at runtime instead, eg:
Book* books = new Book[nx];
...
delete[] books;
Or:
#include <vector>
std::vector<Book> books(nx);
Demo
On a side note:
When you want to discard content from an istream up to the next '\n' character, you can use the stream's ignore() method instead of std::getline(), that way you are not wasting memory unnecessarily for an unused std::string, eg:
#include <limits>
//move to the next line of the file
//std::getline(file, temp);
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Also, you have defined a print() method in Book, but you are not actually using it. Your final display loop can do this instead:
//Display the output
cout << "Books found: " << nx << endl;
for (int i = 0; i < nx; i++)
{
cout << "\nBook " << i + 1 << ":" << endl;
/*
cout << "Title: " << books[i].title << endl;
cout << "Author: " << books[i].author << endl;
cout << "Year: " << books[i].year << endl;
*/
books[i].print();
}

Searching for artist name and song from a file in C++

I have written some code for the search function in C++ to find artist name and song. My code doesn't seem to work. A message displays that the artist and song is found and then the menu repeats itself infinite times.
My full program code is as below.
#include "Music.h"
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
void Music::menu()
{
int input;
do {
cout << "Select an option from the menu" << endl;
cout << "1. Display records" << endl;
cout << "2. Search for records" << endl;
cout << "3. Writing records to a file" << endl;
cin >> input;
switch (input) {
case 1:
displayfile();
break;
case 2:
searchrecords();
break;
case 3:
writefile();
break;
default:
cout << "Invalid option entered. Try again" << endl;
menu();
}
} while (input != 4);
}
void Music::displayfile()
{
string line;
ifstream myfile;
myfile.open("Music.txt");
if (myfile.is_open()) {
while (getline(myfile, line)) {
cout << line << endl;
}
myfile.close();
}
else {
cout << "Unable to open file" << endl;
}
}
void Music::writefile()
{
ofstream write;
write.open("Music.txt", ofstream::app);
if (write.is_open()) {
cin.ignore();
cout << "Enter a title of song to the playlist" << endl;
cin.getline(title, 255).get();
write << " " << title;
cout << "Enter the artist of the song to playlist" << endl;
cin.getline(artist, 255).get();
write << " " << artist;
cout << "Enter the year of the song" << endl;
cin >> year;
write << "" << year;
cout << "Enter the duration of the song" << endl;
cin >> duration;
write << " " << duration;
cout << "Writing to a file is successful" << endl;
}
else {
cout << "File couldn't be open" << endl;
}
write.close();
displayfile();
}
bool Music::searchrecords()
{
bool found = true;
string search;
string line;
ifstream myfile;
myfile.open("Music.txt");
cout << "Enter the artist you want to search for: " << endl;
getline(cin, search).get();
cout << "Enter for the song you want to search for: " << endl;
getline(cin, search).get();
if (myfile.is_open()) {
while (!myfile.eof()) {
if (found) {
cout << "The artist is found" << search << endl;
cout << "The song is found" << search << endl;
return found;
}
else {
cout << "The artist is not found" << endl;
return false;
}
getline(myfile, line);
myfile.close();
displayfile();
}
}
}
Appreciate it if you could help me as I am stuck on what to do.
You have bool found = true; right in the beginning of Music::searchrecords function, so the first iteration of looking through file immediately returns.
You do getline(cin, search).get(); twice in a row, while apparently you want to read in two different string variables, one for artist, one for song
You do a loop with this if on each iteration
if (found) {
cout << "The artist is found" << search << endl;
cout << "The song is found" << search << endl;
return found;
}
else {
cout << "The artist is not found" << endl;
return false;
}
In both cases you terminate your function by calling return, so the very first iteration of looking through file returns from function (you don't read the file completely)
You call
myfile.close();
displayfile();
on each iteration, so even if you hadn't had your if right above, then your program would crash anyway, because you close file inside the loop that's iterating over it.
You don't compare line to check if you indeed found your song
In total, your program doesn't work at all, and StackOverflow isn't a forum to completely write the entire program instead of you. So you better use a debugger in your IDE to see what your program does step by step, or take a piece of paper and a pen to write down how you would accomplish your task

(C++) Goto statement not working. Beginner [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm making a USD to MXN converter and I want to have it work both ways. The if statement works (tryed cout << "test"; and it worked) but it wont work when I replace it with the goto statement.
#include "stdafx.h"
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int user;
int u, m;
cout << "US/MXN Converter" << endl;
cout << "1 US = 12.99 MXN (6/12/2014)" << endl;
cout << endl;
cout << "What Way to convert" << endl;
cout << "[1] US to MXN" << endl;
cout << "[2] MXN to US" << endl;
cout << "Selection: ";
cin >> user;
if (user == 1)
{
goto USTMXN;
}
else
{
goto MXNTUS;
}
USTMXN:
cout << "Enter the amount of US Dollars to Convert" << endl;
cout << "Amount: ";
cin >> u;
m = u * 12.99;
cout << endl;
cout << "MXN Pesos: " << m << endl;
goto END;
MXNTUS:
int mm, uu;
cout << "Enter the amount of Pesos to Convert" << endl;
cout << "Amount: ";
cin >> mm;
uu = mm / 12.99;
cout << endl;
cout << "US Dollars: " << m << endl;
goto END;
END:
system("PAUSE");
return EXIT_SUCCESS;
}
One of the most fundamental things we have to do as programmers is to learn to break problems into smaller problems. You are actually running into a whole series of problems.
I'm going to show you how to solve your problem. You may want to book mark this answer, because I'm pre-empting some problems you're going to run into a few steps down the line and preparing you - if you pay attention - to solve them on your own ;)
Let's start by stripping down your code.
Live demo here: http://ideone.com/aUCtmM
#include <iostream>
int main()
{
std::cout << "Enter a number: ";
int i;
std::cin >> i;
std::cout << "Enter a second number: ";
int j;
std::cin >> j;
std::cout << "i = '" << i << "', j = '" << j << "'\n";
}
What are we checking here? We're checking that we can ask the user two questions. That works fine.
Next is your use of goto, which I strongly recommend you do not use. It would be better to use a function. I'll demonstrate with your goto case here first:
#include <iostream>
int main()
{
int choice;
std::cout << "Enter choice 1 or 2: ";
std::cin >> choice;
if ( choice == 1 )
goto CHOSE1;
else if ( choice == 2 )
goto CHOSE2;
else {
std::cout << "It was a simple enough question!\n";
goto END;
}
CHOSE1:
std::cout << "Chose 1\n";
goto END;
CHOSE2:
std::cout << "Chose 2\n";
goto END;
END:
std::cout << "Here we are at end\n";
}
live demo: http://ideone.com/1ElcV8
So goto isn't the problem.
That leaves your use of variables. You've really mixed things up nastily by having a second set of variables (mm, uu). Not only do you not need to have these, you're doing something very naughty in that these variables only exist inside one scope and not the other. You can "get away" with this but it will come back to haunt you later on.
The difference in your two main streams of code is the variable names. The second conversion case looks like this:
MXNTUS:
int mm, uu;
cout << "Enter the amount of Pesos to Convert" << endl;
cout << "Amount: ";
cin >> mm;
uu = mm / 12.99;
cout << endl;
cout << "US Dollars: " << m << endl;
goto END;
The problem here is that you have - accidentally - used the variable "m" in your output. It's what we call uninitialized.
cout << "US Dollars: " << m << endl;
That m in the middle should be mm.
Your compiler should actually be warning you about this. If it's not, and you're just setting out learning, you should figure out how to increase the compiler warning level.
It would be better to make a function to do the conversions; you could make one function for each direction, but I've made a function that handles both cases:
#include <iostream>
static const double US_TO_MXN = 12.99;
static const char DATA_DATE[] = "6/12/2014";
void convert(const char* from, const char* to, double exchange)
{
std::cout << "Enter the number of " << from << " to convert to " << to << ".\n"
"Amount: ";
int original;
std::cin >> original;
std::cout << to << ": " << (original * exchange) << '\n';
}
int main() // this is valid since C++2003
{
std::cout << "US/MXN Converter\n"
"1 US = " << US_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"\n";
int choice = 0;
// Here's a better demonstration of goto
GET_CHOICE:
std::cout << "Which conversion do you want to perform?\n"
"[1] US to MXN\n"
"[2] MXN to US\n"
"Selection: ";
std::cin >> choice;
if (choice == 1)
convert("US Dollars", "Pesos", US_TO_MXN);
else if (choice == 2)
convert("Pesos", "US Dollars", 1 / US_TO_MXN);
else {
std::cerr << "Invalid choice. Please try again.\n";
goto GET_CHOICE;
}
// this also serves to demonstrate that goto is bad because
// it's not obvious from the above that you have a loop.
}
ideone live demo: http://ideone.com/qwpRtQ
With this, we could go on to clean things up a whole bunch and extend it:
#include <iostream>
using std::cin;
using std::cout;
static const double USD_TO_MXN = 12.99;
static const double GBP_TO_MXN = 22.03;
static const char DATA_DATE[] = "6/12/2014";
void convert(const char* from, const char* to, double exchange)
{
cout << "Enter the number of " << from << " to convert to " << to << ".\n"
"Amount: ";
int original;
cin >> original;
cout << '\n' << original << ' ' << from << " gives " << int(original * exchange) << ' ' << to << ".\n";
}
int main() // this is valid since C++2003
{
cout << "Foreign Currency Converter\n"
"1 USD = " << USD_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"1 GBP = " << GBP_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"\n";
for ( ; ; ) { // continuous loop
cout << "Which conversion do you want to perform?\n"
"[1] USD to MXN\n"
"[2] MXN to USD\n"
"[3] GBP to MXN\n"
"[4] MXN to GBP\n"
"[0] Quit\n"
"Selection: ";
int choice = -1;
cin >> choice;
cout << '\n';
switch (choice) {
case 0:
return 0; // return from main
case 1:
convert("US Dollars", "Pesos", USD_TO_MXN);
break;
case 2:
convert("Pesos", "US Dollars", 1 / USD_TO_MXN);
break;
case 3:
convert("British Pounds", "Pesos", GBP_TO_MXN);
break;
case 4:
convert("Pesos", "British Pounds", 1 / GBP_TO_MXN);
break;
default:
cout << "Invalid selection. Try again.\n";
}
}
}
http://ideone.com/iCXrpU
There is a lot more room for improvement with this, but I hope it helps you on your way.
---- EDIT ----
A late tip: It appears you're using visual studio, based on the system("PAUSE"). Instead of having to add to your code, just use Debug -> Start Without Debugging or press Ctrl-F5. It'll do the pause for you automatically :)
---- EDIT 2 ----
Some "how did you do that" points.
cout << '\n' << original << ' ' << from << " gives " << int(original * exchange) << ' ' << to << ".\n";
I very carefully didn't do the using namespace std;, when you start using more C++ that directive will become the bane of your existence. It's best not to get used to it, and only let yourself start using it later on when you're a lot more comfortable with C++ programming and more importantly debugging odd compile errors.
But by adding using std::cout and using std::cin I saved myself a lot of typing without creating a minefield of function/variable names that I have to avoid.,
What does the line do then:
cout << '\n' << original << ' ' << from << " gives " << int(original * exchange) << ' ' << to << ".\n";
The '\n' is a single character, a carriage return. It's more efficient to do this than std::endl because std::endl has to go poke the output system and force a write; it's not just the end-of-line character, it actually terminates the line, if you will.
int(original * exchange)
This is a C++ feature that confuses C programmers. I'm actually creating a "temporary" integer with the result of original * exchange as parameters.
int i = 0;
int i(0);
both are equivalent, and some programmers suggest it is better to get into the habit of using the second mechanism so that you understand what happens when you later run into something called the "most vexing parse" :)
convert("Pesos", "British Pounds", 1 / GBP_TO_MXN)
The 1 / x "invert"s the value.
cout << "Foreign Currency Converter\n"
"1 USD = " << USD_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"1 GBP = " << GBP_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"\n";
This is likely to be confusing. I'm mixing metaphors with this and I'm a little ashamed of it, but it reads nicely. Again, employ the concept of breaking problems up into smaller problems.
cout << "Hello " "world" << '\n';
(note: "\n" and '\n' are different: "\n" is actually a string whereas '\n' is literally just the carriage return character)
This would print
Hello world
When C++ sees two string literals separated by whitespace (or comments) like this, it concatenates them, so it actually passes "Hello world" to cout.
So you could rewrite this chunk of code as
cout << "Foreign Currency Converter\n1 USD = ";
cout << USD_TO_MXN;
cout << " MXN (";
cout << DATA_DATE;
cout << ")\n1 GBP = ";
cout << GBP_TO_MXN;
cout << " MXN (";
cout << DATA_DATE;
cout << ")\n\n";
The << is what we call "semantic sugar". When you write
cout << i;
the compiler is translating this into
cout.operator<<(i);
This odd-looking function call returns cout. So when you write
cout << i << j;
it's actually translating it to
(cout.operator<<(i)).operator<<(j);
the expression in parenthesis (cout.operator<<(i)) returns cout, so it becomes
cout.operator<<(i); // get cout back to use on next line
cout.operator<<(j);
Main's fingerprint
int main()
int main(int argc, const char* argv[])
Both are legal. The first is perfectly acceptable C or C++. The second is only useful when you plan to capture "command line arguments".
Lastly, in main
return 0;
Remember that main is specified as returning int. The C and C++ standards make a special case for main that say its the only function where it's not an error not to return anything, in which case the program's "exit code" could be anything.
Usually its best to return something. In C and C++ "0" is considered "false" while anything else (anything that is not-zero) is "true". So C and C++ programs have a convention of returning an error code of 0 (false, no error) to indicate the program was successful or exited without problems, or anything else to indicate (e.g. 1, 2 ... 255) as an error.
Using a "return" from main will end the program.
Try to change youre code for sth like this. Using goto label is not recommended.
Main idea of switch statement :
int option;
cin >> option
switch(option)
{
case 1: // executed if option == 1
{
... code to be executed ...
break;
}
case 99: //executed id option == 99
{
... code to be executed
break;
}
default: // if non of above value was passed to option
{
// ...code...
break;
}
}
Its only example.
int main(int argc, char *argv[])
{
int user;
int u, m;
cout << "US/MXN Converter" << endl;
cout << "1 US = 12.99 MXN (6/12/2014)" << endl;
cout << endl;
cout << "What Way to convert" << endl;
cout << "[1] US to MXN" << endl;
cout << "[2] MXN to US" << endl;
cout << "Selection: ";
cin >> user;
switch(user )
{
case 1 :
{
//USTMXN:
cout << "Enter the amount of US Dollars to Convert" << endl;
cout << "Amount: ";
cin >> u;
m = u * 12.99;
cout << endl;
cout << "MXN Pesos: " << m << endl;
break;
}
}
default :
{
//MXNTUS:
int mm, uu;
cout << "Enter the amount of Pesos to Convert" << endl;
cout << "Amount: ";
cin >> mm;
uu = mm / 12.99;
cout << endl;
cout << "US Dollars: " << m << endl;
break;
}
}
system("PAUSE");
return EXIT_SUCCESS;
}

outFile C++ not writing to output text

Down below is my incomplete program. I am having problems with writing to a text file. For example I want to write the number of snow days to a text file, but nothing shows up in the textfile when I debug in VS 2010. It does display my info and name, but nothing else works. It wont write anything after that. its NOT writing to a text file.
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
const string INFORMATION = "College Class";
const string MY_NAME = "Tom Hangler";
int main(void)
{
ofstream outFile;
int numberOfSnowDays;
int greatestSnowDay;
int dayNumber;
double amounttOfSnow;
outFile.open("Ex1Out.txt");
outFile << setw(51) << INFORMATION << endl << setw(48) << MY_NAME << endl;
cout << "Please enter num of days it snowed: " << endl;
cin >> numberOfSnowDays;
outFile << setw(10) << "Number of days of snow is: " << setw(10) << numberOfSnowDays;
int index;
//Problem 1 for-loop
for (index = 0; index < numberOfSnowDays; index++)
{
cout << "Enter day: " << endl;
cin >> dayNumber;
cout << "Enter amount of snow: " << endl;
cin >> amountOfSnow;
};
return 0;
}
here is what my output displays:
College Class (centered)
Tom Hangler (centered)
If i try to write anything after this, Nothing is written ever to the output file. And the output text file IS in my VS project that contains my .cpp file. I added the text file to project.
Try closing the stream at the end of the function, it looks like the data isn't getting flushed.
outFile.close();
Your code compiles and works on gcc 4.4.5 (apart from typo in amounttOfSnow).
Is it possible that you are looking at an old Ex1Out.txt file ?
Its most likely created in the Release or Debug subdirectory in your project, not where the .cpp files are.
in your for loop, you only collect the amount of snow, but you don't write it to the text file.
Do you want to do something like this?
...
for (index = 0; index < numberOfSnowDays; index++)
{
cout << "Enter day: " << endl;
cin >> dayNumber;
cout << "Enter amount of snow: " << endl;
cin >> amountOfSnow;
// next line is new:
outFile << "Day#: "<< dayNumber << ", snow: "<< amountOfSnow<<endl;
};
outFile.close()
...

C++ doesn't convert string from data

I want to write a little program which should be used in supermarkets. everything is fictitious and it's only for learning purposes.
However, The tool generate a new data for every new article. in the data there are 2 lines, the name and the prise.
The data is named as the article number of the product. So the user enter a articlenumber and the tool looks for a data with this number, if it found it, it reads the 2 lines and initiates the variables.
But for some reasons it does not convert and copy the strings correctly.
here is the part which loads the data.
int ware::load()
{
string inhalt;
cout << "please insert article number" << endl;
cin >> articlenumber;
productname.open(articlenumber, ios::in);
if (!productname.is_open())
{
cout << "can't find the product." << endl;
return 1;
}
if (productname.is_open())
{
while (!productname.eof())
{
getline(productname, inhalt);
strcpy(name,inhalt.c_str());
getline(productname, inhalt);
price = atoi (inhalt.c_str());
cout << inhalt << endl;
}
warenname.close();
}
cout << endl << endl <<
"number: " << inhalt <<
" preis: " << price <<
" name: " << name <<
endl << endl; //this is a test and will be deleted in the final
}
hope you can help me!
Here is the class:
class ware{
private:
char articlenumber[9];
char name[20];
int price;
fstream warennamefstream;
ifstream warenname;
public:
void newarticle(); //this to make a new product.
void scan(); //this to 'scan' a product (entering the article number ;D)
void output(); //later to output a bill
int load(); //load the datas.
};
hope everything is fine now.
First, you have a using namespace std; somewhere in your code. This occasionally leads to subtle bugs. Delete it. ( Using std Namespace )
int ware::load()
{
string inhalt;
cout << "please insert article number" << endl;
cin >> articlenumber;
The type of articlenumber is incorrect. Declare it std::string, not char[]. ( What is a buffer overflow and how do I cause one? )
productname.open(articlenumber, ios::in);
There is no reason to have an ifstream lying around waiting to be used. Also, there is no point in providing ios::in -- it is the default. Just use the one-argument form of the ifstream constructor.
if (!productname.is_open())
{
cout << "can't find the product." << endl;
return 1;
}
Don't bother checking to see if the file opened. Your users don't care if the file was present or not, they care whether the file was present AND you retrieved the essential data.
if (productname.is_open())
{
while (!productname.eof())
{
getline(productname, inhalt);
strcpy(name,inhalt.c_str());
getline(productname, inhalt);
price = atoi (inhalt.c_str());
cout << inhalt << endl;
}
warenname.close();
}
This loop is just wrong.
Never invoke eof(). It doesn't do what you think it does, and will cause bugs.
Why is this a loop? Aren't there only two lines in the file?
There is no point in calling close. Just let the file close when the istream goes out of scope.
Why is warename different than productname?
Don't store your data in char[]. This is the 21st century. Use std::string.
.
cout << endl << endl <<
"number: " << inhalt <<
" preis: " << price <<
" name: " << name <<
endl << endl; //this is a test and will be deleted in the final
Never use endl when you mean to say '\n'. Each of those endl manipulators invokes flush, which can be very expensive. ( What is the C++ iostream endl fiasco? )
You forgot to return a value.
Try this instead:
int ware::load()
{
// This declaration should be local
std::string articlenumber;
cout << "please insert article number" << endl;
cin >> articlenumber;
// This declaration should be local
std::ifstream productname(articlenumber.c_str());
// These declarations can be class members:
std::string name;
int price;
std::string number;
if(getline(productname, name) &&
productname>>price &&
productname>>number)
{
cout << "\n\n" <<
"number: " number <<
" preis: " << price <<
" name: " << name <<
"\n\n"; //this is a test and will be deleted in the final
return 0;
} else {
cout << "can't find the product." << endl;
return 1;
}
}