#include"std_lib_facilities.h"
void login(){
fstream fin;
fin.open("user.csv",ios::in);
vector<string>data;
string word;
string temp;
string line;
while(fin>>temp){
data.clear();
getline(fin,line);
stringstream s(line);
while(getline(s,word,',')){
data.push_back(word);
}
}
cout<<data.size()<<'\n';
cout<<data[0]<<'\n';
}
int main()
{
login();
}
I am trying to collect data from the user.csv file and the code i have written is a modified version of a working code written by another programmer(https://www.geeksforgeeks.org/csv-file-management-using-c/) but even after trying a lot i am still confused why my code is showing a range error and when i checked the size of vector it is showing 0.....why?? andjust for info the user.csv file contains :
hello,testing,qwerty
Here's a version of your code that might work
void login(){
ifstream fin("user.csv");
if (!fin.is_open()) {
cerr << "file open failed\n";
return;
}
vector<string>data;
string line;
while(getline(fin,line)) {
istringstream s(line);
string word;
while(getline(s,word,',')){
data.push_back(word);
}
}
cout<<data.size()<<'\n';
cout<<data[0]<<'\n';
}
I haven't tested this.
Related
I'm trying to retrieve certain lines from a text file. I'm using:
#include <iostream>
#include <fstream>
using namespace std;
void parse_file()
{
std::ifstream file("VampireV5.txt");
string str= "Clan";
string file_contents;
while (std::getline(file, str))
{
file_contents += str;
file_contents.push_back('\n');
}
cout << file_contents;
file.close();
}
int main()
{
parse_file();
return 0;
}
I want to get that one and only line containing "Clan" until '\n'. I've tried to add an if inside the while loop but it is not returning anything.
Is there a way to make it get 1 line at once?
Your code is almost correct as in: It reads the file line by line and appends the contents to your string.
However since you only want that one line, you also need to check for what you are looking for.
This code snippet should give you only the line, which starts with the word 'Clan'.
If you want to check, whether the string is anywhere on the line, consider checking for != string::npos.
void parse_file()
{
std::ifstream file("VampireV5.txt");
string str;
string file_contents;
while (std::getline(file, str))
{
if (str.find("Clan") == 0)
{
file_contents += str;
file_contents.push_back('\n');
}
}
cout << file_contents;
file.close();
}
For a couple of weeks now, I have been developing a random class generator for the Xbox game Call of Duty: Modern Warfare 3. In this game, different weapons have different levels, which increase as you use the weapon more. I am storing the weapons and their levels in a text file, which store the data on separate lines with the format
weapon-weapon_level
So the M4A1 with weapon level 8 would look like:
m4a1-8
(The weapons are all in lowercase with no punctuation or spaces).
I have already written methods for creating the file and reading the file, but I want a method to edit the file, so the user enters the weapon whose level they want to change, then the new level. Here's what I have so far: (The file is called "weaponlevels.txt")
void WeaponLevelFile::editFile()
{
string line;
string weapon;
string weaponent;
string weaponlevel;
string temp;
cout<<"Please enter the weapon whose level you wish to change. Enter the name in lowercase, with "<<endl;
cout<<"no spaces or punctuation except full stops. E.g. SCAR-L becomes scarl and Barrett .50cal "<<endl;
cout<<"becomes barrett.50cal."<<endl;
cin>>weaponent;
cout<<"Please enter the new weapon level."<<endl;
cin>>temp;
ifstream infile("weaponlevels.txt");
ofstream outfile("weaponlevels.txt");
while (getline(infile, line))
{
istringstream ss(line);
getline(ss,weapon,'-');
if (weapon == weaponent)
{
ss>>weaponlevel;
weaponlevel=temp;
outfile<<weaponlevel<<endl;
infile.close();
outfile.close();
}
}
}
This method does not work however; all it does is wipe the file (so the file is blank). Why does it do this, and what is a better method?
EDIT:
#stardust_'s answer worked the best, but still didn't completely do it. Here is the code:
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
int main()
{
string temp;
string line;
string weapon;
string weaponent;
string weaponlevel;
cout<<"enter weapon"<<endl;
cin>>weaponent;
cout<<"enter level"<<endl;
cin>>temp;
ifstream infile("weaponlevels.txt");
std::string in_str((std::istreambuf_iterator<char>(infile)),
std::istreambuf_iterator<char>());
infile.close();
stringstream infile_ss(in_str);
while (getline(infile_ss, line))
{
istringstream ss(line);
getline(ss,weapon,'-');
if (weapon == weaponent)
{
ss>>weaponlevel;
weaponlevel=temp;
infile_ss<<weaponlevel<<endl;
}
}
ofstream outfile("weaponlevels.txt");
outfile << infile_ss.str();
outfile.close();
}
It modifies the right part of "weaponlevels.txt", but doesn't completely do it. if i enter m4a1 as the weapon and 7 as the weapon level, instead of becoming m4a1-7 it becomes:
7
a1-3
After quite a lot of work, here's what worked:
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
int main()
{
string temp;
string line;
string weapon;
string weaponent;
string weaponlevel;
cout<<"enter weapon"<<endl;
cin>>weaponent;
cout<<"enter level"<<endl;
cin>>temp;
ifstream infile("weaponlevels.txt");
std::string in_str((std::istreambuf_iterator<char>(infile)),
std::istreambuf_iterator<char>());
infile.close();
stringstream infile_ss(in_str);
ostringstream out;
while (getline(infile_ss, line))
{
istringstream ss(line);
getline(ss,weapon,'-');
out << weapon << '-'; // Write the first part of the line.
if (weapon != weaponent)
{ // Not the correct weapon so just write the original information.
ss >> weaponlevel;
out << weaponlevel << endl;
}
else
{ // Found the desired weapon, change the level.
out << temp << endl;
}
}
I loaded the whole string into an ostringstream and found the weapon within the string.
Have you tried using pointers to search through the file for a specific string to replace? I have yet to write a program that uses this myself, but I know it's pretty common. Otherwise you'll just be overwriting the entire file.
Note that I'm not entirely certain whether you have used pointers in your code for this purpose because, as I stated above, I have yet to use this myself. However, from what I saw, I don't think you did. Just correct me if I'm wrong.
There are many problems with your code. You are opening a file twice. you are closing the ifstreams in a loop while reading them (?). ...
However algorithm wise you can open the file for reading, read the whole thing to a string, close the file, modify the string, open the file for writing, write the string, close the file.
int main()
{
cin>>temp;
ifstream infile("weaponlevels.txt");
std::string in_str((std::istreambuf_iterator<char>(infile)),
std::istreambuf_iterator<char>());
infile.close();
stringstream infile_ss(in_str);
while (getline(infile_ss, line))
{
istringstream ss(line);
getline(ss,weapon,'-');
if (weapon == weaponent)
{
ss>>weaponlevel;
weaponlevel=temp;
infile_ss<<weaponlevel<<endl;
}
}
ofstream outfile("weaponlevels.txt");
outfile << infile_ss.str();
outfile.close();
}
instead of
ifstream infile("weaponlevels.txt");
use
ifstream infile("weaponlevels.txt", ifstream::in)
I have a strange problem that seems to happen when I pass an ifstream by reference.
In my main method, I have created an ifstream, and then I pass it to this read method by reference:
void ArrayStorage::read(ifstream& fin)
{
if (fin.is_open())
{
string input;
getline(fin, input, '\n');
}
else
{
}
}
This should work fine, however, I'm getting the following message in the value of the ifstream:
fin {_Filebuffer={_Set_eback=0xcccccccc _Set_egptr=0xcccccccc ...} } std::basic_ifstream > &
Anyone have any ideas?
EDIT: Code that calls the method:
ifstream fin1("data.txt");
ofstream out1("1-In-SortedRead.txt");
if(!fin1.is_open())
{
cout << "FAIL" << endl;
return 1;
}
ArrayStorage arrayStorage1;
// read in values into data structure
arrayStorage1.read(fin1);
If I include the if test in my code the error message is returned and I'm not sure why.
and when it's not used, my program get's stuck in a loop where it never reaches the end of the file. I don't understand what's going wrong.
int countlines()
{
fstream myfile;
myfile.open("questions.txt", ios::in);
string contents;
int linenumber = 0;
//if (myfile.is_open())
// {
while (!myfile.eof())
{
getline( myfile, contents );
if (contents != "")
{
linenumber++;
}
}
cout << "there are " << linenumber << " lines.\n";
//}else {cout<<"Unable to get file.\n";}
myfile.close();
return(linenumber);
}
What's going on is that your file is not being opened. That's why is_open fails.
Then, when you comment out the check, you're breaking your loop because you're iterating incorrectly (see my comment) and not detecting stream failures (.eof() will never be true on that stream).
Make sure that the file is in the right place, and that it is accessible.
The correct idiom for reading a file line-by-line in C++ is using a loop like this:
for (std::string line; std::getline(file,line);)
{
// process line.
}
Inserting this in your example (+fixing indentation and variable names) gives something like this:
int countlines(const std::string& path)
{
// Open the file.
std::ifstream file(path.c_str());
if (!file.is_open()) {
return -1; // or better, throw exception.
}
// Count the lines.
int count = 0;
for (std::string line; std::getline(file,line);)
{
if (!line.empty()) {
++count;
}
}
return count;
}
Note that if you don't intend to process the line contents, you can actually skip processing them using std::streambuf_iterator, which can make your code look like:
int countlines(const std::string& path)
{
// Open the file.
std::ifstream file(path.c_str());
if (!file.is_open()) {
return -1; // or better, throw exception.
}
// Refer to the beginning and end of the file with
// iterators that process the file character by character.
std::istreambuf_iterator<char> current(file);
const std::istreambuf_iterator<char> end;
// Count the number of newline characters.
return std::count(current, end, '\n');
}
The second version will completely bypass copying the file contents and avoid allocating large chunks of memory for long lines.
When using std::istream and std::ostream (whose std::fstream implements), the recommended usage is to directly use the stream in a bool context instead of calling eof() function because it only return true when you managed to read until the last byte of the file. If there was any error before that, the function will still return true.
So, you should have written your code as:
int countlines() {
ifstream myfile;
int linenumber = 0;
string linecontent;
myfile.open("question.txt", ios::in);
while (getline(myfile, linecontent)) {
if (!linecontent.empty()) {
++linenumber;
}
}
return linenumber;
}
Try the following code. It will also (hopefully) give you an idea why the file open is failing...
int countlines()
{
ifstream myfile;
myfile.open("questions.txt");
string contents;
int linenumber = 0;
if (myfile.is_open())
{
while (getline(myfile, contents))
{
if (contents != "")
linenumber++;
}
cout << "there are " << linenumber << " lines." << endl;
myfile.close();
}
else
cout << "Unable to get file (reason: " << strerror(errno) << ")." << endl;
return linenumber;
}
i am trying to open a file with ifstream and i want to use a string as the path (my program makes a string path). it will compile but it stays blank.
string path = NameOfTheFile; // it would be something close to "c:\file\textfile.txt"
string line;
ifstream myfile (path); // will compile but wont do anything.
// ifstream myfile ("c:\\file\\textfile.txt"); // This works but i can't change it
if (myfile.is_open())
{
while (! myfile.eof() )
{
getline (myfile,line);
cout << line << endl;
}
}
I am using windows 7, My compiler is VC++ 2010.
string path = compute_file_path();
ifstream myfile (path.c_str());
if (!myfile) {
// open failed, handle that
}
else for (string line; getline(myfile, line);) {
use(line);
}
Have you tried ifstream myfile(path.c_str());?
See a previous post about the problems with while (!whatever.eof()).
I'm unsure as to how this actually compiles, but I assume you are looking for:
#include <fstream>
#include <string>
//...
//...
std::string filename("somefile.txt");
std::ifstream somefile(filename.c_str());
if (somefile.is_open())
{
// do something
}
//Check out piece of code working for me
//---------------------------------------
char lBuffer[100];
//---
std::string myfile = "/var/log/mylog.log";
std::ifstream log_file (myfile.str());
//---
log_file.getline(lBuffer,80);
//---