working on some code that will place (output/input) 5 different files onto my desktop. Finally, got it down to one error message which is "error <23>: C2109: subscript an array or pointer type is required". Its with myfile.open; I've tried -> operator. Not exactly how to make this into an array, if that is what I'm suppose to do as I have tried making string into char and warnings occur. Can anybody let me know how I can modify my code to correct this? I'm relatively new to C++ and programming, only a few months.
#include <iostream>
#include <fstream>
using namespace std;
struct pizza{
string FILENAMES[9];
};
int main ()
{
int i;
char FILENAMES;
pizza greg = {"file1.doc", "file2.doc", "file3.doc", "file4.doc", "file5.doc"};
cout << "Input is invalid. Program will end. " << "\n" ;
for (i = 0; i < 5; i++)
{
const char *path="/Desktop/Libraries/Documents" ;
ofstream myfile(path);
myfile.open (FILENAMES[i]) ;
myfile << "How you like math?\n" ;
myfile.close();
};
return 0;
}
Your suggestions helped a lot, and my program is now up and running. (no pun intended, haha.)
The loop should really look something like this:
const char *path="/Desktop/Libraries/Documents";
for (int i = 0; i < 5; ++i)
{
std::string name(path + greg.FILENAMES[i]);
std::ofstream myfile(name.c_str());
if (myfile) {
myfile << "How you like math?\n" ;
}
else {
std::cerr << "ERROR: failed to open '" << name << "' for writing\n";
}
}
char FILENAMES;
FILENAMES is not an array. Even if it were, you would have to make it an array of strings or a two dimensional array of characters to do what you intend here.
What you probably intend to do is access the field inside greg.
myfile.open (greg.FILENAMES[i]);
Related
I'm just beginning to learn C++ and I am having some trouble with a program. It's supposed to sort numbers from an external file. I've managed to successfully code the sorting algorithm, but I am having trouble working with the external file. I am just testing some things out in a separate program to gain an understanding of how things like ifstream work. I should be able to figure out how to implement it into my program once I gain a better understanding of how it works.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
int main() {
using namespace std;
int count;
ifstream InFile;
InFile.open ("unsorted.txt");
InFile >> count;
int numbers[count];
for(int a = 0; a < count; a++)
InFile >> numbers[a];
cout << numbers << endl;
}
Currently, the output for this is 0x7ffc246c98e0 I am not sure why this is the case I'm just attempting to print my file of integers. Could anyone help explain what I am doing wrong? I'd be very thankful.
When you do
cout << numbers << endl;
you print the pointer to the first element of the array.
You want
cout << numbers[a] << '\n';
to print the current element.
Furthermore, if that's all your program is doing, then you don't actually need the array. All you need is a single int variable:
int value;
for (int a = 0; a < count; ++a)
{
InFile >> value;
cout << value << '\n';
}
That also solve the problem with the variable-length array (since there isn't any).
If you intend to use count variable to count the file size or something, it is where your code goes wrong. You can't count the length of the file as like as you are trying.
while( getline ( InFile, line ) )
{
count += line.length();
}
Maybe, try like this!!!
If you use
InFile>>count;
it would try to store all the string from InFile stream to count, which is not intended.
I am writing a code to check to see if one document (text1.txt) contains a list of banned words (bannedwords.txt) in it.
For example, the text1 document contains lyrics to a song and i want to check whether the word pig from the banned document is included in it. I then want the out put to be similar to:
"pig" found 0 times
"ant" found 3 times
This is what I have come up with so far but cannot seem to put the array of banned words into the search. Any help would be amazing :D
Thanks Fitz
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
bool CheckWord(char* filename, char* search)
{
int offset;
string line;
ifstream Myfile;
Myfile.open(filename);
if (Myfile.is_open())
{
while (!Myfile.eof())
{
getline(Myfile, line);
if ((offset = line.find(search, 0)) != string::npos)
{
cout << "The Word " << search<< " was found" << endl;
return true;
}
else
{
cout << "Not found";
}
}
Myfile.close();
}
else
cout << "Unable to open this file." << endl;
return false;
}
int main()
{
ifstream file("banned.txt");
if (file.is_open())//file is opened
{
string bannedWords[8];//array is created
for (int i = 0; i < 8; ++i)
{
file >> bannedWords[i];
}
}
else //file could not be opened
{
cout << "File could not be opened." << endl;
}
ifstream text1;//file is opened
text1.open("text1.txt");
if (!text1)//if file could not be opened
{
cout << "Unable to open file" << endl;
}
CheckWord("text1.txt", "cat");
system("pause");
}
Your main() function is reading the contents of banned.txt into an array of 8 std::string named bannedWords.
The array bannedWords is not being used anywhere after that. C++ doesn't work by magic, and compilers are not psychic so cannot read your mind in order to understand what you want your code to do. If an array (or its elements) are not accessed anywhere, they will not be used to do what you want with them.
You need to pass strings from the bannedWords array to CheckWord(). For example;
CheckWord("text1.txt", bannedWords[0].c_str());
will attempt to pass the contents of the first string in bannedWords to CheckWord().
However, that will not compile either unless you make the second parameter of CheckWord() (named search) be const qualified.
Or, better yet, change the type of the second argument to be of type std::string. If you do that, you can eliminate the usage of c_str() in the above.
I don't claim that is a complete solution to your problem - because there are numerous problems in your code, some related to what you've asked about, and some not. However, my advice here will get you started.
Your question is really vague; it looks like you need to spend some time to pin down your program structure before you could ask for help here.
However, since we were all new once, here's a suggestion for a suitable structure:
(I'm leaving out the file handling bits because they're irrelevant to the essential structure)
//Populate your array of banned words
std::string bannedWords[8];
int i;
for (int i = 0; i < 8; ++i)
{
file >> bannedWords[i];
}
//Load the entire file content into memory
std::ifstream in("text1.txt");
std::string fileContents((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
So now the entire file content is in the string "fileContents", and the 8 banned words are in "bannedWords". I suggest this approach because otherwise you're opening, reading, and closing the file for every word. Hardly a good design.
Now you've got to check each word against the file content. There's some more sophisticated ways to do this, but your simplest option is a loop.
//Loop through each banned word, and check if it's in the file
for (int i = 0; i < 8; i++)
{
if (fileContents.find(bannedwords[i]) != std::string::npos)
{
//Do whatever
}
}
Obviously you'll need to do the find a little differently if you want to count the number of occurrences, but that's another question.
In file called abc.txt, I have input following text:
sample text
sample text
sample text
sample text
sample text
Firstly I created variable(named text) for saving text- read from the file. Then program reads file abc.txt. I created vector named: ArrSent for saving each line from the file abc.txt. After loop while ends program close the file abc.txt. Then program have to output all sentences from vector ArrSent to the screnn.I have this kind of problem: after end of program, appears alert with message: vector subscript out of range. I have no idea why..
#include<iostream>
#include<string>
#include<fstream>
#include<vector>
using namespace std;
void function()
{
string text;//variable to save text from file
ifstream myfile("abc.txt");//reading from file colled abc.txt
vector<string> ArrSent;
if (myfile.is_open())
{
//cout <<"myplik.good()= "<< myfile.good() << endl;
while (myfile.good())
{
getline(myfile, text);
ArrSent.push_back(text);
}
myfile.close();
}
for (int i = 0; i <= ArrSent.size(); i++)
{
cout << ArrSent[i] << endl;
}
}
int main()
{
function();
system("pause");
return 0;
}
It is wrong here
for (int i = 0; i <= ArrSent.size(); i++)
{
cout << ArrSent[i] << endl;
}
should be
for (int i = 0; i < ArrSent.size(); i++)
{
cout << ArrSent[i] << endl;
}
The reason for that is that in C/C++, vector/array are zero based. That is to say that, if you have a vector, my_vector, size of 10, it goes like, my_vector[0], my_vector[1], ... my_vector[9]. There is no my_vector[10].
A better way to iterate through it , could be (C++11)
for (const auto & v : ArrSent)
{
cout << v << endl;
}
or
for (vector<string>::const_iterator i = ArrSent.begin(); i != ArrSent.end(); ++i)
cout << *i << endl;
As pointed out by WhozCraig, the while loop for reading is also buggy, a better version could be
while (getline(myfile, text))
{
ArrSent.push_back(text);
}
A Word About function
Notable: Your function name is function. While that may be descriptive, you should know that standard library headers can freely include other standard library header (and very frequently do just that). One such header in the standard library is <functional> which declares, as luck would have it, std::function.
Why would you care? Because your using namespace std; brings everything in std out in the open with no namespace qualifier requirements, including potentially std::function (whether or not you included <functional>).
Which means although this will still compile:
void function()
{
// .. stuff
}
This may not:
int main()
{
function(); // HERE
//... other stuff
}
This doesn't know whether you're calling your function or attempting to instantiate a single temporary of type std::function<> (which it can't anyway, as no template parameters are described). The result may be a ambiguous.
You can fix this by using ::function(); in your main(), but it would be better if you got developed the habit of not slurping in the entire std library in via using namespace std;, and/or not using names of common types/ids from the standard library.
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class PERSON{
string name, surname;
public:
void set_name(string aname, string asurname){
name = aname;
surname = asurname;
};
void read(){
}
void output(){
cout << name << " " << surname << "\n";
}
void save(PERSON *x){
ofstream file("test.bin", ios::out | ios::app | ios::binary);
if(!file.is_open()){
cout << "ERROR\n";
}else{
file.write((char*)x, sizeof(*x));
file.close();
}
}
};
/*
*
*
*
*/
int main(int argc, char** argv) {
PERSON * person1 = new PERSON;
PERSON * person2 = new PERSON;
person1->set_name("Amon", "Raa");
person1->save(oseba1);
ifstream file2("test.bin", ios::in | ios::binary);
if(!file2.is_open()){
cout << "Error\n";
return 0;
}
while(!file2.eof()){
file2.read((char *)person2, sizeof(*person2));
person2->output();
}
file2.close();
return 0;
}
This is my code...what I am doing wrong?
What I am trying to do is to save each time a class to the end of the binary file and then read all entries...
but each time I run the program I get printed only the last entered name
so run it first time
the file is written correctly and the output is OK
then I change the name to something else, lets say John Doe, I get the output of 2times John Doe
Please help... I am a complete beginner ;(
Serialization of classes is for example included in the boost package.
http://www.boost.org/doc/libs/1_53_0/libs/serialization/doc/index.html
I do not think you actually want to implement these kind of functionality yourself.
You can't simply write out the binary image of a class in C++, especially one that contains pointers and non-POD members. Once you have indirections in your data, simply writing out a memory image doesn't work, both because just writing out the memory image of the class doesn't include the pointed-to data and because in order for this to work you'd have to load all the data including the pointed-to data into the exact same memory location that they were in when you saved them. That's not easily possible (to put it mildly).
You have two options, one manual, one using a third party library:
1) You write and read each member out separately with a bunch of bookkeeping information. That should work in you case as all you really have to load and save is the contents of the two strings and their respective lengths
2) The other option - especially when the data structure is more complex than the one you are using - is to use something like boost::serialization to do the grunt work for you.
You have to use pointer array of class PERSON. Then read from the binary file and populate array of persons.
ifstream input("PERSON.std",ios::binary);
input.seekg(0, ios::end);
int count = input.tellg() / sizeof(PERSON);
PERSON *persons = new PERSON[count];
input.seekg(0, ios::beg);
input.read((char*) persons, sizeof(PERSON)*count);
cout << count << endl;
for (int j = 0; j < count; j++)
{
cout << count << endl;
cout <<persons[j].output() << "\n";
}
cout << '\n';
input.close();
I need to read a .dat file which looks like this:
Atask1 Atask2 Atask3 Atask4 Atask5
Btask1 Btask2 Btask3 Btask4 Btask5
Ctask1 Ctask2 Ctask3 Ctask4 Ctask5
Dtask1 Dtask2 Dtask3 Dtask4 Dtask5
and i need to be able to output information like this:
cout << line(3) << endl; // required output shown below
>>Ctask1 Ctask2 Ctask3 Ctask4 Ctask5
cout << line(2)(4) << endl; // required output shown below
>>Btask4
I don't know how to read 1 line and split it into an array of 5 different strings.
I'd ideally like to have the whole .dat file converted into a vector or a list or some kind of matrix/array structure for easy reference
any simple code or solutions for this??
PLEASE HELP?!?!?!? :-)
EDIT:
vector<string> dutyVec[5];
dut1.open(dutyFILE);
if( !dut1.is_open() ){
cout << "Can't open file " << dutyFILE << endl;
exit(1);
}
if(dut1.eof()){
cout << "Empty file - no duties" << endl;
exit(1);
}
while ( !dut1.eof()){
int count = 0;
getline(dut1, dutyVec[count]);
count++;
}
Your problem addresses a number of issues, all of which I will attempt to answer in one go. So, forgive the length of this post.
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <fstream>
int main(int argc, char argv[]){
std::vector <std::string> v;//just a temporary string vector to store each line
std::ifstream ifile;
ifile.open("C://sample.txt");//this is the location of your text file (windows)
//check to see that the file was opened correctly
if(ifile.is_open()) {
//while the end of file character has not been read, do the following:
while(!ifile.eof()) {
std::string temp;//just a temporary string
getline(ifile, temp);//this gets all the text up to the newline character
v.push_back(temp);//add the line to the temporary string vector
}
ifile.close();//close the file
}
//this is the vector that will contain all the tokens that
//can be accessed via tokens[line-number][[position-number]
std::vector < std::vector<std::string> > tokens(v.size());//initialize it to be the size of the temporary string vector
//iterate over the tokens vector and fill it with data
for (int i=0; i<v.size(); i++) {
//tokenize the string here:
//by using an input stringstream
//see here: http://stackoverflow.com/questions/5167625/splitting-a-c-stdstring-using-tokens-e-g
std::istringstream f(v[i].c_str());
std::string temp;
while(std::getline(f, temp, ' ')) {
tokens[i].push_back(temp);//now tokens is completely filled with all the information from the file
}
}
//at this point, the tokens vector has been filled with the information
//now you can actually use it like you wanted:
//tokens[line-number][[position-number]
//let's test it below:
//let's see that the information is correct
for (int i=0; i<tokens.size(); i++) {
for(int j=0; j<tokens[i].size(); j++) {
std::cout << tokens[i][j] << ' ';
}
std::cout << std::endl;
}
system("pause");//only true if you use windows. (shudder)
return 0;
}
Note, I did not use iterators, which would have been beneficial here. But, that's something I think you can attempt for yourself.