|
|
|||||||||
|
|||||||||
| |||||||||
|
|
|
| |||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
Reading a file into a vector - c++
i have to make a c++ program which has a struct declared and makes a vector of that struct then allows the user to enter a file name and reads the data from that file into the program however i am running into to problems figuring out how to get the program to work here is what i have so far....
Code:
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
struct OrderRecord
{
int part_num;
double unit_price;
int quantity;
char description[15];
};
void read_file(char name[15],
vector<OrderRecord> &order)
{
fstream file(name, ios::in);
OrderRecord entry;
do
{
file.getline(entry.part_num, 6, '-');
file.getline(entry.unit_price, 5, '-');
file.getline(entry.quantity, 6, '-');
file.getline(entry.description, 15, '-');
order.push_back(entry);
}while(!file.eof());
}
int main(int argc, char *argv[])
{
vector<OrderRecord> order;
char name[15];
char choice;
do
{
cout << "\n1. Enter a file name to read from" << endl;
cout << "2. Print the Order Record" << endl;
cout << "Q. Quit" << endl;
cin >> choice;
switch(choice)
{
case '1':
cout << "Please enter the name of a file: " << endl;
cin >> name;
read_file(name, order);
break;
case '2':
//print_order(order);
break;
case 'q':
choice = 'Q';
case 'Q':
break;
default:
cout << "Invalid Choice" << endl;
}
}while(choice != 'Q');
system("PAUSE");
return EXIT_SUCCESS;
}
samples input would be a file like..... 123456-2.25-10-widgets 987654-17.25-20-sprockets any help would be appreciated |
|
#2
|
|||
|
|||
|
the only thing i am getting errors with is the file.getlines im not sure how to get those to work the way i need
|
|
#3
|
||||
|
||||
|
The getline function requires a char * as its first parameter. part_num and quantity are ints and unit_price is a double.
__________________
Physics is like sex. Sure, it may give some practical results, but that's not why we do it. ~ Richard Feynman How To Ask Questions The Smart Way by Eric S. Raymond |
|
#4
|
|||
|
|||
|
so then how would i get it to read everything in properly?
|
|
#5
|
||||
|
||||
|
getline means get a line of text. So get a line of text. Then parse that line to extract your data.
|
|
#6
|
|||
|
|||
|
then what would i need to put as the first arguement for the getline? and then after that how would i parse the data like i need and would i still need a - between every piece of info
|
|
#7
|
||||
|
||||
|
The first argument of getline is a char*. That means it expects a C-style string. That means you need to give it the name of the char array that you want that string to go into. Think maybe that might be what you should give it?
After that you just identify which characters in that string belong to what fields, then extract them and convert them to the appropriate data types for your struct's fields. BTW, if this is a C++ assignment that has you using vectors, shouldn't you also be using the basic string class instead of C-style strings? Though that still wouldn't change the need to feed getline a C-style string. |
|
#8
|
||||
|
||||
|
There's another form of getline designed for the string class. You'll need to include <string>, of course.
string::getline (input stream, target string, delimiters);
__________________
Antiquis temporibus, nati tibi similes in rupibus ventosissimis exponebantur ad necem. unoPolitically Incorrect DaWei on Pointers Grumpy on Exceptions |
|
#9
|
|||
|
|||
|
ok i got it compiling now but when i run it i type in the file name and it sits there for a second and then it close the window because of an error. here is my code
Code:
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
struct OrderRecord
{
int part_num;
double unit_price;
int quantity;
char description[15];
};
void read_file(char name[15],
vector<OrderRecord> &order)
{
fstream file(name, ios::in);
char part[6];
char price[5];
char quant[6];
char desc[15];
OrderRecord entry;
do
{
file.getline(part, 6, '-');
file.getline(price, 5, '-');
file.getline(quant, 6, '-');
file.getline(entry.description, 15, '-');
entry.part_num = atoi(part);
entry.unit_price = atof(price);
entry.quantity = atoi(quant);
order.push_back(entry);
}while(!file.eof());
}
void print_order(vector<OrderRecord> &order)
{
double subtotal = 0.0;
double total = 0.0;
cout << "\n\nItem\tDescription\tPrice\tQuantity\tSubtotal" << endl;
vector<OrderRecord>::iterator iter;
for(iter = order.begin();iter < order.end(); iter++)
{
subtotal = iter->unit_price * iter->quantity;
total += subtotal;
cout << iter->part_num << "\t" << iter->description << "\t" << iter->unit_price
<< "\t" << iter->quantity << "\t" << subtotal << endl;
}
cout << "-------------------------------------------------------" << endl;
cout << "Invoice Total: " << total << endl;
}
int main(int argc, char *argv[])
{
vector<OrderRecord> order;
char name[15];
char choice;
do
{
cout << "\n1. Enter a file name to read from" << endl;
cout << "2. Print the Order Record" << endl;
cout << "Q. Quit" << endl;
cin >> choice;
switch(choice)
{
case '1':
cout << "Please enter the name of a file: " << endl;
cin >> name;
read_file(name, order);
break;
case '2':
print_order(order);
break;
case 'q':
choice = 'Q';
case 'Q':
break;
default:
cout << "Invalid Choice" << endl;
}
}while(choice != 'Q');
system("PAUSE");
return EXIT_SUCCESS;
}
and here is what the input file looks like which is name lab4.txt 123456-2.75-25-widgets- 248567-7.25-15-sprockets- 452684-19.00-30-motherboard- 412685-1.50.-100-bolts- 751425-3.75-50-screws- any suggestions? |
|
#10
|
||||
|
||||
|
So what is the error that it gives you? My crystal ball is in the shop and you'd have to get within arm's length for me to perform a mind-meld.
Though I noticed here: Code:
fstream file(name, ios::in);
char part[6];
char price[5];
char quant[6];
char desc[15];
OrderRecord entry;
do
{
file.getline(part, 6, '-');
file.getline(price, 5, '-');
file.getline(quant, 6, '-');
file.getline(entry.description, 15, '-');
You're trying to squeeze 7- and 6-character sequences into 6- and 5-character buffers. That just will not do! When working with C-style strings, you must declare your buffers to be big enough to hold the string that you intend to store in it. That must include one more character space for the null-terminator. Remember, a string that's six characters long will take up seven bytes in memory. PS Why are you calling the getline() method each time? getline() reads in an entire line, at least up to the count you give it. Since all the fields for a given item are on a single line, why do you keep skipping to the next lines before you're even done with that item? As we have advised you already, do one getline() to read in a single item, then extract that item's data out of its fields. Last edited by dwise1_aol : February 7th, 2008 at 03:15 PM. |
|
#11
|
|||
|
|||
|
New Info
Hi,
did you get an answer to your question? I am trying to do the same thing you are without luck..help me. Quote:
|
|
#12
|
||||
|
||||
|
You should start your own thread, though you might reference this one by link if it seems appropriate. You should also show YOUR code; showing his does nothing for us. Further, no need to quote the whole thing - we have scroll bars!!!!1111oneeleven.
Be sure and read the "How to Post" thread before posting code, so you'll know to put it in [code] tags. |
|
#13
|
|||
|
|||
|
eclipse150GT, I think you are kind of on the right path but I think you are expecting too much from the getline function. The getline function reads a whole line from the file. After you have read the whole line you then need to parse it yourself.
Code:
vector<char *> dataFromFile;
char *cstr;
if(file.is_open())
{
do
{
cstr = (char *)malloc(256);
file.getline(cstr, 256);
dataFromFile.push_back(cstr);
}while(!file.eof());
cout << "File successfully read" << endl;
}
else
cout << "Failed to open file" << endl;
The above code would read all the data from your text file. You will now have a vector that contains the five lines from lab4.txt. The entries in the vector will now contain the following lines: 123456-2.75-25-widgets- 248567-7.25-15-sprockets- 452684-19.00-30-motherboard- 412685-1.50.-100-bolts- 751425-3.75-50-screws Obviously you can't just use this data yet as it is not suitable for your purposes. What you need to do next is tokenize each line to get at the individual pieces of data in the string. Luckily there's a function which you can use to do this called strtok. An example of how to do this is below: Code:
vector<char *> tokens; //store all the tokens in this vector
char *pChar;
pChar = strtok(dataFromFile[0], "-");
while (pChar != NULL)
{
tokens.push_back(pChar);
pChar = strtok (NULL, "-");
}
//now that you have divided the first string into
//different parts you can convert them to the appropiate
//data and store them in entry
entry.part_num = atoi(tokens[0]);
entry.unit_price = atof(tokens[1]);
entry.quantity = atoi(tokens[2]);
strcpy(entry.description, tokens[3]);
As it happens I recently posted a thread about tokenizing[URL = "http://forums.devshed.com/c-programming-42/splitting-up-a-string-608721.html">here.[/URL]. You should read the thread to get a better understanding of what you are doing. Just so it makes more sense the whole function is here: Code:
void read_file(char name[15], vector<OrderRecord> &order)
{
fstream file(name, ios::in);
OrderRecord entry;
vector<char *> dataFromFile;
char *cstr;
if(file.is_open())
{
do
{
cstr = (char *)malloc(256);
file.getline(cstr, 256);
dataFromFile.push_back(cstr);
}while(!file.eof());
cout << "File successfully read" << endl;
}
else
cout << "Failed to open file" << endl;
vector<char *> tokens;
char *pChar;
for(int i = 0; i < dataFromFile.size(); i++)
{
pChar = strtok(dataFromFile[i], "-");
while (pChar != NULL)
{
tokens.push_back(pChar);
pChar = strtok (NULL, "-");
}
entry.part_num = atoi(tokens[0]);
entry.unit_price = atof(tokens[1]);
entry.quantity = atoi(tokens[2]);
strcpy(entry.description, tokens[3]);
tokens.clear();
order.push_back(entry);
}
//free the memory allocated earlier
for(int i = 0; i < dataFromFile.size(); i++)
{
free(dataFromFile[i]);
}
//close the file
file.close();
}
You should be aware of this from the other thread and consider adding this to be more complete: Quote:
Also on my ide(Visual C++ 2005 express edition) I get warnings that strtok is deprecated. You might need to find the more updated version of this function or write one yourself. |
|
#14
|
||||
|
||||
|
Strtok is fine, despite its warts. I would suggest, however, since this is C++, that string streams might represent a better approach.
|
|
#15
|
||||
|
||||
|
Be warned that strtok() alters the string that is passed to it. If you don't want this, try using strsep(). Since you're using C++, use a stringstream instead, or you could write a tokenizer in a few lines of code. Google for C++ tokenizer for help.
__________________
Up the Irons What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home. "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest Down with Sharon Osbourne Puzzle of the Month solved by Keath and KevinADC, superior perl programmers of the month |
![]() |
| Viewing: Dev Shed Forums > Programming Languages > C Programming > Reading a file into a vector - c++ |
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|
|
|
|