c++ readfile with varying element amounts per line? - c++

if I have a file like this, say called file.txt
20
25 97
97 5
How would i properly read it given that the second column has missing the second element in the first row?I attempted this
int main()
{
ifstream readFile;
string filename;
cout << "Please enter file name and extention: " << endl;
cin >> filename;
readFile.open(filename);
int row = 0;
int column = 0;
while (readFile >> row >> column)
{
//does something
}
However I get segmenation fault

I would like using std::getline to read lines and std::stringstream to parse the lines.
#include <iostream>
#include <fstream>
#include <sstream>
int main(void) {
std::string filename;
std::string line;
std::ifstream readFile;
std::cout << "Please enter file name and extention: " << std::endl;
std::cin >> filename;
readFile.open(filename);
if (!readFile) {
std::cout << "open error\n";
return 1;
}
while (std::getline(readFile, line)) {
std::stringstream ss(line);
int row = 0, column = 0;
if (ss >> row >> column) {
std::cout << "row = " << row << ", column = " << column << '\n';
} else {
std::cout << "invalid line\n";
}
}
readFile.close();
return 0;
}
Another version (also print partial line):
#include <iostream>
#include <fstream>
#include <sstream>
int main(void) {
std::string filename;
std::string line;
std::ifstream readFile;
std::cout << "Please enter file name and extention: " << std::endl;
std::cin >> filename;
readFile.open(filename);
if (!readFile) {
std::cout << "open error\n";
return 1;
}
while (std::getline(readFile, line)) {
std::stringstream ss(line);
int row = 0, column = 0;
bool row_valid = false, column_valid = false;
if (ss >> row) row_valid = true;
if (ss >> column) column_valid = true;
std::cout << "row = ";
if (row_valid) std::cout << row; else std::cout << "(none)";
std::cout << ", column = ";
if (column_valid) std::cout << column; else std::cout << "(none)";
std::cout << '\n';
}
readFile.close();
return 0;
}
Yet another version (support lines with 3 integers and more):
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
int main(void) {
std::string filename;
std::string line;
std::ifstream readFile;
std::cout << "Please enter file name and extention: " << std::endl;
std::cin >> filename;
readFile.open(filename);
if (!readFile) {
std::cout << "open error\n";
return 1;
}
while (std::getline(readFile, line)) {
std::stringstream ss(line);
std::vector<int> lineInts;
int data;
while (ss >> data) lineInts.push_back(data);
std::cout << lineInts.size() << " elements:";
for (int d : lineInts) std::cout << ' ' << d;
std::cout << '\n';
}
readFile.close();
return 0;
}

Related

Trying to run a count so I know when the last row of data is written so I can output a ']' instead of a ','

I want my output file to look like this:
However, no matter what I try, it looks like this:
I can't get my comma condition to work for the output. I've tried to use eof, counts, etc but I'm not really sure where to go.
I've tried looking at other posts, but I either can't find one linked, or I don't actually understand it.
#include <iostream>
#include <fstream> //ofstream declared in this header file
#include <string>
#include <sstream>
#include <vector>
using namespace std;
//Creates Structure For Columns
struct InputFile
{
string Date;
string Value;
string SignalStrength;
string Voltage;
};
int main()
{
ifstream input;
string Row;
string Column;
int count = 0;
int count2 = 0;
//Stores Data From Structure As Vector
vector<InputFile> InputDataStored;
input.open("Temperature.csv");
if (input.fail())
{
cerr << "File does not exist. Exiting" << endl; //cerr is cout for errors
return 1; //This could be used as an error code
}
if (!input)
{
cerr << "File could not be opened." << endl;
}
while (getline(input, Row)) //Remove top line output from sensor data when opened in Notepad
{
getline(input, Row); // read an entire row and store it in a string variable 'line'
stringstream ss{ Row }; // used for breaking words
vector<string> Columns; // creates a temporary vector of strings
while (getline(ss, Column, ',')) // read an entire row and store it in a string variable 'column'
{
Columns.push_back(Column); // add all the data of a row to the temporary vector
count++;
}
//InputFile t{}; // convert string to struct types
InputFile t;
if (Row.empty())
continue; // if it is a blank row, ignore it
else
t.Date = Columns[1];
t.Value = Columns[2];
t.SignalStrength = Columns[4];
t.Voltage = Columns[5];
InputDataStored.push_back(t); // add all the data of the new row to a vector
count2++;
cout << t.Date << " " << t.Value << " " << t.SignalStrength << " " << t.Voltage << endl;
}
input.close();
ofstream output;
output.open("SensorData.json");
if (!output)
{
cerr << "File could not be opened." << endl;
}
int JSONcount = 0;
output << "[";
for (InputFile t : InputDataStored)
{
JSONcount++;
output << "{" << endl;
output << "\"Date\": \"" << t.Date << "\"" << endl;
output << "\"Temperature\": " << t.Value << endl;
output << "\"Signal_strength\": " << t.SignalStrength << endl;
output << "\"Voltage\": " << t.Voltage << endl;
if (count2 >= JSONcount)
output << "}]" << endl;
else
output << "}," << endl;
}
output << JSONcount << endl;
output << count << endl;
output << count2;
output.close();
}
There are multiple mistakes in your code. Try something more like this instead:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
struct InputFile
{
string Date;
string Value;
string SignalStrength;
string Voltage;
};
int main()
{
vector<InputFile> InputDataStored;
string Line, Column;
int count = 0, count2 = 0;
ifstream input("Temperature.csv");
if (!input)
{
cerr << "Input file could not be opened. Exiting" << endl;
return 1;
}
getline(input, Line); //Remove top line output from sensor data when opened in Notepad
while (getline(input, Line)) // read an entire row and store it in a string variable 'line'
{
istringstream iss{ Line };
if (Line.empty())
continue;
vector<string> Columns;
while (getline(iss, Column, ','))
{
Columns.push_back(Column);
++count;
}
InputFile t;
t.Date = Columns[1];
t.Value = Columns[2];
t.SignalStrength = Columns[4];
t.Voltage = Columns[5];
InputDataStored.push_back(t);
++count2;
cout << t.Date << " " << t.Value << " " << t.SignalStrength << " " << t.Voltage << endl;
}
input.close();
ofstream output("SensorData.json");
if (!output)
{
cerr << "Output file could not be opened. Exiting" << endl;
return 1;
}
int JSONcount = 0;
output << "[";
for (const auto &t : InputDataStored)
{
++JSONcount;
if (JSONcount > 1)
output << "," << endl;
output << "{" << endl;
output << "\"Date\": \"" << t.Date << "\"" << endl;
output << "\"Temperature\": " << t.Value << endl;
output << "\"Signal_strength\": " << t.SignalStrength << endl;
output << "\"Voltage\": " << t.Voltage << endl;
output << "}";
}
output << "]" << endl;
output << JSONcount << endl;
output << count << endl;
output << count2;
output.close();
return 0;
}

Reading from a file and displaying it backwards

I'm trying to write a program to read from a file and display the text backwards. - My loop backward loop is not working. Any suggestions?
- Also if I'm reading a file that only contain floats integers or floats, how would I display them all as float?
Thanks,
#include <iostream>
#include <fstream>
using namespace std;
void seeReverseText(char fileName[])
{
ifstream fin(fileName);
if (fin.fail())
{
cout << "Error opening file " << fileName << endl;
return;
}
cout.setf(ios::showpoint);
cout.precision(2);
cout.setf(ios::fixed);
int i = 0;
cout << "New order:\n";
while (!fin.eof())
{
// this is what I was trying to do
// i++;
// for (i--; i >= 0; i--)
// fin >> fileName[i];
// cout << "' " << fileName[i] << "'";
fin >> fileName;
cout << fileName << endl;
}
fin.close();
}
int main()
{
char fileName[256];
cout << "Enter the filename: ";
cin >> fileName;
seeReverseText(fileName);
return 0;
}
Try something more like this instead:
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
void seeReverseText(const std::string &fileName)
{
std::ifstream fin(fileName);
if (!fin)
{
std::cout << "Error opening file " << fileName << std::endl;
return;
}
std::cout.setf(std::ios::showpoint);
std::cout.precision(2);
std::cout.setf(std::ios::fixed);
std::cout << "New order:\n";
std::string line;
while (std::getline(fin, line))
{
std::reverse(line.begin(), line.end());
std::cout << line << std::endl;
}
}
int main()
{
std::string fileName;
std::cout << "Enter the filename: ";
if (std::cin >> fileName)
seeReverseText(fileName);
return 0;
}

Reading File, Trying to Display Encrypted Message from a file

#include <iostream>
#include <string>
#include <fstream>
#include "Encrypt.h"
int main() {
std::string Choose;
std::cout << "Please enter write or read(Lower Case Only): ";
std::getline(std::cin, Choose);
if (Choose == "write") {
std::string Sentence;
std::string SecurityKey;
std::string TextFile;
std::cout << "Enter Your sentence that you wish to be encrupted" << std::endl << "Sentence: ";
std::getline(std::cin, Sentence);
std::cout << std::endl << "Secuirty Key Disclaimer Never forget what secruity \nkey you used otherwise your message will be lost forever" << std::endl;
std::cout << "Secuirty Key: ";
std::getline(std::cin, SecurityKey);
std::string message = encrypt(Sentence, SecurityKey);
std::cout << "Encrypted: " << std::endl << message;
std::cout << "\nDecrypted: " << decrypt(message, SecurityKey) << std::endl;
std::cout << "Enter a title for text Document: ";
std::getline(std::cin, TextFile);
TextFile = TextFile + ".txt";
std::ofstream out(TextFile);
out << message;
out.close();
}
else if (Choose == "read") {
std::string NameOfFile;
std::getline(std::cin, NameOfFile);
NameOfFile = NameOfFile + ".txt";
std::string STRING;
std::ifstream infile;
infile.open(NameOfFile);
while (!infile.eof)
{
getline(infile, STRING);
}
infile.close();
std::string S_Key;
std::getline(std::cin, S_Key);
std::cout << "\nDecrypted: " << decrypt(STRING, S_Key) << std::endl;
}
else {
std::cout << "There are only 2 Options.... (lower Case Only)" << std::endl;
}
system("PAUSE");
}
My problem is its not reading the file how it is Encrypting it could this be because of the .eof() reading the file differently to how the program is Encrypting it, .. Its not reading the file Correctly how do i work around this?
If anyone is Interested here is the Encrypt.h
std::string encrypt(std::string msg, std::string key) {
std::string tmp(key);
while (key.size() < msg.size())
key += tmp;
for (std::string::size_type i = 0; i < msg.size(); ++i)
msg[i] ^= key[i];
return msg;
}
std::string decrypt(std::string msg, std::string key) {
return encrypt(msg, key);
}

Read File Line by line and output the first coloumn

I am new to c++ and am trying to do a string search for 2 words(double and triple) in a file and print the line on which they are found. Some lines only have the word "double" and some only have the word "triple".
The code doesn't seem to output the words, it just prints the last line at the end of the loop.
I forgot to add that I need to print the first element of the line on which the word is found, I am able to locate the line where the word is found, however, it doesnt seem to print the first element on the file.
Here is my code.
int main(int argv, char *argc[]){
const string filen("test.txt");
ifstream inFile(filen.c_str());
string line = "";
char IDList[10];
string ID = "";
char* double_word = "double"; // test variable to search in file
char* triple_word = "triple";
stringstream ss;
string word = "";
unsigned int currentLine = 0;
// iterate through each line and check if the words double or triple exist.
while(getline(inFile, line)){
currentLine++;
if (line.find(double_word) != string::npos) {
cout << "found the word \"double\" on line: " << currentLine << endl;
// this part takes the input file and reads the first character of the line i.e. the ID and adds it to the IDList
// string array.
while(inFile >> IDList){
cout << "File Id: " << IDList << endl;
inFile.ignore(numeric_limits<streamsize>::max(), ' ');
for(int i=0;i<10;i++){
ss << IDList[i] << endl;
}
word = ss.str();
}
}
else if(line.find(triple_word) != string::npos){
cout << "found the word \"triple\" on line: " << currentLine << endl;
// now take the id of this file and add it to a different queue.
while(inFile >> IDList){
cout << "File Id: " << IDList << endl;
inFile.ignore(numeric_limits<streamsize>::max(), ' ');
for(int i=0;i<10;i++){
ss << IDList[i] << endl;
}
word = ss.str();
}
}
else if(line.find(double_word) && line.find(triple_word) != string::npos){
cout << "Found both words double and triple in line: " << currentLine << endl;
while(inFile >> IDList){
cout << "File Id: " << IDList << endl;
inFile.ignore(numeric_limits<streamsize>::max(), ' ');
for(int i=0;i<10;i++){
ss << IDList[i] << endl;
}
word = ss.str();
}
}
else{
cout << "neither word found, moving to next line" << endl;
}
}
inFile.close();
cout << "Id's added to the queue" << word << endl;
return 0;
}
I think you can simplify your code and write something like this:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
using std::string;
using std::vector;
using std::cout;
using std::cin;
int main(int argc, char* argv[]) {
const string filen("test.txt");
std::ifstream inFile(filen.c_str());
string line;
string double_word = "double"; // test variable to search in file
string triple_word = "triple";
vector<string> IDs;
unsigned int currentLine = 0;
// iterate through each line and check if the words double or triple exist.
while(getline(inFile, line)){
currentLine++;
bool found_d_word = line.find(double_word) != string::npos;
bool found_t_word = line.find(triple_word) != string::npos;
if ( found_d_word && !found_t_word )
cout << "found the word \"double\" on line: " << currentLine << '\n';
if ( found_t_word && !found_d_word )
cout << "found the word \"triple\" on line: " << currentLine << '\n';
if ( found_d_word && found_t_word )
cout << "Found both words double and triple in line: " << currentLine << '\n';
if ( found_d_word || found_t_word ) {
std::istringstream ss{line};
string ID;
ss >> ID;
cout << "File Id: " << ID << '\n';
// my guess: store all the IDs in one vector
IDs.push_back(ID);
} else {
cout << "neither word found, moving to next line\n";
}
}
inFile.close();
return 0;
}
One of the problems with your code is that you first read a line of the input file (with getline), put that in a string and then, when the word "double" or "triple" is found in the string, you try to read the ID from the file while you should read it from the same string.
Try this,
#include "iostream"
#include "string"
#include "sstream"
#include "fstream"
using namespace std;
int main()
{
stringstream y; string x; int lc=0, id;
ifstream fin("file.txt");
while (getline(fin, x))
{
++lc;
y.str(x);
y >> id;
bool d=x.find("double")!=string::npos;
bool t=x.find("triple")!=string::npos;
if (d and t)
cout << "found words double and triple on line " << lc
<< ", id is " << id << endl;
else if (d)
cout << "found word double on line " << lc
<< ", id is " << id << endl;
else if (t)
cout << "found word triple on line " << lc
<< ", id is " << id << endl;
}
}

Adding values in filestream

For example i have a notepad for numbers.
1 2 3 4 5
Then i want to add 4 in the third line which is 3 so that its new value will be
1 2 7 4 5
Question is how can i do that?
Please help me thank you!
string add;
cout<<"Enter value to be added: ";
cin>>add;
fstream file;
file.open("quantity.txt");
You have not been accurate enough with your question, but I think this is something like what you expect:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
int main(int argc, const char *argv[]) {
std::string filename;
std::cout << "Enter name of file to modify: ";
std::cin >> filename;
std::ifstream inputFile;
inputFile.open(filename);
if(inputFile.fail()) {
std::cout << "Unable to open file \"" << filename << "\" for reading\n";
return 1;
}
unsigned offset;
std::cout << "Enter offset to modify: ";
std::cin >> offset;
int toAdd;
std::cout << "Enter value to be added to line #" << lineNumber << ": ";
std::cin >> toAdd;
std::vector<int> nums;
for(;;) {
int num;
inputFile >> num;
if(inputFile.eof())
break;
nums.push_back(num);
}
inputFile.close();
if(offset >= nums.length()) {
std::cout << "Offset " << offset << " out of bounds!\n";
return 1;
}
nums[offset] += toAdd;
std::ofstream outputFile;
outputFile.open(filename);
if(outputFile.fail()) {
std::cout << "Unable to open file \"" << filename << "\" for writing\n";
return 1;
}
for(int num : nums) // Warning: C++11
outputFile << num << ' ';
outputFile.close();
}