Hello I am wondering what the most efficient way would be to read a .csv file and store each comma separated item into its own array or variable. I can only use #include <iostream>. I was thinking about maybe using .getLine(), but all i would know is the delimeter and value to store since there is no <fstream> allowed. That being said does anyone know how I could go about this? Thanks in advance!
This is the layout of the file. The first line indicates the umber of rows to be read.
input file
3
2014,Computer Science,Utah,1568,44.9
2014,Marketing,Michigan,23745,983
215,Business Management, Idaho,256,674
code:
int year;
char* major = new char[40];//cant be longer than 40 characters
char* state = new char[40];
int enrolled;
int rate;
char p;//for cin.get characters possibly
cin>>rows
for(int i = 0; i <= rows; i++){
HMMMMM?
}
You can use cin.getline() function which also accepts a delimiter. As for storing the entire csv record, you can define a structure which stores all the fields.
#include <iostream>
#include <cstring>
using namespace std;
typedef struct temp_struct {
char major[40];
char state[40];
float rate;
int year;
int enrolled;
} RECORD;
int main() {
int rows;
cin >> rows;
RECORD r[rows];
char temp[100];
for(int i = 0; i < rows; i++) {
cin.getline(temp, 100, ',');
r[i].year = atoi(temp);
cin.getline(temp, 100, ',');
strcpy(r[i].major, temp);
cin.getline(temp, 100, ',');
strcpy(r[i].state,temp);
cin.getline(temp, 100, ',');
r[i].enrolled = atoi(temp);
cin.getline(temp, 100);
r[i].rate = atof(temp);
cout << r[i].year << " " << r[i].major << " " << r[i].state << " ";
cout << r[i].enrolled << " " << r[i].rate << endl;
}
return 0;
}
For delimiters, the first four delimiters would be , and since the last value rate has no , following it rather there's a \n, no delimiter is specified in the cin.getline() (since default delimiter is \n itself).
I have tested it; here's the link https://ideone.com/ycht1b
Related
Write and test a program that prompts the user to input a file name and a string to test for. Search the file for every occurrence of the specified string – when the string is found, display the line that contains it. When all occurrences of the string have been found display the number of times the string appeared in the file. Hint: You may use string member function find().
Here's my code, as I stated it works with some sentences but not all, it doesn't seem to have anything to do with the length either as if I repeat a line I know works, it won't run into any errors, can someone explain?
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <cctype>
using namespace std;
void find_common_words(string, int);
vector<string> words;
int main(){
vector<string> line;
string input;
char filename[50];
ifstream inputFile;
cout << "Enter File Name:" << endl;
cin.getline(filename, 50);
inputFile.open(filename);
//TESTING IF FILE IS OPEN
if (!inputFile.is_open()){
cout << "File Wasn't Opened!" << endl;
return 0;
}
while (getline(inputFile, input)){
line.push_back(input);
}
int size_of_array = static_cast<int>(line.size());
for (int i = 0; i < size_of_array; i++){
istringstream iss(line[i]);
int word_number = 0;
do {
string word;
iss >> word;
words.push_back(word);
word_number++;
} while (iss);
}
string commonword;
cout << "Enter a word to search for (without punctuation)" << endl;
cin >> commonword;
int size_of_array2 = static_cast<int>(words.size());
find_common_words(commonword, size_of_array2);
return 0;
}
void find_common_words(string search, int sizeofarray2) {
//CONVERSION TO STRING WITHOUT PUNCTUATION
for (int i = 0; i < sizeofarray2; i++){
string temp_string = words[i];
for (int j = 0, len = temp_string.size(); j < len; j++){
if (ispunct(temp_string[j])){
temp_string.erase(j--, 1);
len = temp_string.size();
}
}
words[i] = temp_string;
}
//SEARCHING FOR SAME WORDS
int line_number = 1;
int words_found = 0;
for (int i = 0; i < sizeofarray2; i++){
if (search == words[i]){
cout << search << " Was found on line " << line_number << endl;
words_found++;
}
if (words[i].length() == 0){
line_number++;
}
}
cout << line_number - 1 << " lines checked, " << words_found << " matches " << endl;
}
Heres my input file (randomly generated):
It's a very big deal.
Carl won the spelling bee and got a trophy!
Why is your cat so big?
Do you have a big bowl I can borrow?
It's a big company.
Penguins live in the Antarctica.
Don’t be silly, you're going to the game!
What are you talking about?
He threw up in the trash can!
You're so ratchet!
But she is a good caretaker.
Tom is looking for a bigger house to live in.
I get an error with Debug Assertion
Expression c> = -1 && c < = 255
I debugged the program and WhozCraig is right. In your input text in the line
Don’t be silly, you're going to the game!
In the word "Don’t", you do not have the normal apostrophe as you have in the word "It's" or "you're"
This special character is encoded as -110 in temp_string. In the description of std::ispunct you can read:
The behavior is undefined if the value of ch is not representable as unsigned char and is not equal to EOF.
-110 does not fit and causes a debug assertion error. If you cast it to unsigned char like WhozCraig proposed, it will work.
You can also fix your input file.
A very interesting and subtle error . . .
I was taught that you have to use gets(str) to input a string and not cin. However I can use cin just fine in the program below. Can someone tell me if you can use cin or not. Sorry for my bad English. The program lets you insert 5 names and then print those names to the screen.
Here's the code:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char **p = new char *[5];
for (int i = 0; i < 5; i++)
{
*(p + i) = new char[255];
} //make a 2 dimensional array of strings
for (int i = 0; i < n; i++)
{
char n[255] = "";
cout << "insert names: ";
cin >> n; //how i can use cin here to insert the string to an array??
strcpy(p[i], n);
}
for (int i = 0; i < n; i++)
{
cout << p[i] << endl; //print the names
}
}
You can indeed use something like
std::string name;
std::cin >> name;
but the reading from the stream will stop on the first white space, so a name of the form "Bathsheba Everdene" will stop just after "Bathsheba".
An alternative is
std::string name;
std::getline(std::cin, name);
which will read the whole line.
This has advantages over using a char[] buffer, as you don't need to worry about the size of the buffer, and the std::string will take care of all the memory management for you.
Use ws (whitespace) in getline() like getline(cin>>ws, name);
If numeric input is before the string then due to whitespace the first string input will be ignored. Therefore use ws like getline(cin>>ws, name);
#include <iostream>
using namespace std;
main(){
int id=0;
string name, address;
cout <<"Id? "; cin>>id;
cout <<"Name? ";
getline(cin>>ws, name);
cout <<"Address? ";
getline(cin>>ws, address);
cout <<"\nName: " <<name <<"\nAddress: " <<address;
}
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.
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.
I'm trying to collect information from a textfile which contains names of organisations (without spaces) and floating integers. I want to store this information in an array structure.
The problem I'm having so far is collecting the information. Here is a sample of the textfile:
CBA 12.3 4.5 7.5 2.9 4.1
TLS 3.9 1 8.6 12.8 4.9
I can have up to 128 different numbers for each organisation, and up to 200 organisations in the textfile.
This is what my structure looks like so far:
struct callCentre
{
char name[256];
float data[20];
};
My main:
int main()
{
callCentre aCentre[10];
getdata(aCentre);
calcdata(aCentre);
printdata(aCentre);
return 0;
}
And the getdata function:
void getdata(callCentre aCentre[])
{
ifstream ins;
char dataset[20];
cout << "Enter the name of the data file: ";
cin >> dataset;
ins.open(dataset);
if(ins.good())
{
while(ins.good())
{
ins >> aCentre[c].name;
for(int i = 0; i < MAX; i++)
{
ins >> aCentre[c].data[i];
if(ins == '\n')
break;
}
c++;
}
}
else
{
cout << "Data files couldnt be found." << endl;
}
ins.close();
}
What I'm trying to achieve in my getdata function is this: store the organisation name first into the structure, then read each float into the data array until the program detects a newline byte. However, so far my check for the newline byte isn't working.
Assume that variables c and MAX are already defined.
How should I go about this properly?
The >> operator treats whitespace as a delimiter, and that includes newlines, so it just eats those and you never see them.
You need to read lines and then chop the lines up. The following bit of hackery illustrates the basic idea:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string line;
while( getline( cin, line ) ) {
istringstream is( line );
string cs;
is >> cs;
double vals[10];
int i = 0;
while( is >> vals[i] ) {
i++;
}
cout << "CS: " << cs;
for ( int j = 0; j < i; j++ ) {
cout << " " << vals[j];
}
cout << endl;
}
}
char byte = ins.peek();
Or
if(ins.peek() == '\n') break;
(Edit): You'll want to also check for an eof after your peek(), because some files may not have a ending newline.
I'd like to point out that you might want to consider using a vector<callCentre> instead of a static array. If your input file length exceeds the capacity of the array, you'll walk all over the stack.
I would read the file, one line after another and parse each line individually for the values:
std::string line;
while (std::getline(ins, line)) {
std::istringstream sline(line);
sline >> aCentre[c].name;
int i = 0;
while (sline >> aCentre[c].data[i])
i++;
c++;
}