I have to create a simple code that is supposed to create a .txt file as an output, containing a list fo notations with this format. (time ; topic ; comment)
the code has to run a loop using a struct function showed below:
struct annotation_t {
string topic;
string comment;
time_t stamp;
};
so the user can input the notations as many times he wants till he decides to go out. This is what I did so far.
#include <iostream>
#include <string>
#include <ctime>
#include <fstream>
#include <cstdlib>
#include <vector>
using namespace std;
struct annotation_t {
string topic;
string comment;
time_t stamp;
};
int main()
{
int q = 0;
std::vector<annotation_t> obj;
do
{
annotation_t temp = {};
cout<< "input your topic: ";
cin >> temp.topic ;
cout<< "input yourfeedback: ";
cin >> temp.comment ;
cout<< "input your time stamp: ";
cin >> temp.stamp ;
cout<< "exit?";
cin >> q;
obj.push_back(temp);
} while (q != 0);
ofstream myfile("annotation.txt");
char time[1000];
for(int i = 0;i<50;i++)
{
struct annotation_t obj[i];
myfile<<obj[i].stamp <<" "; // write in file
myfile<<obj[i].topic <<" ";// write in file
myfile<<obj[i].comment; // write in file
myfile<<"\n";
}
cout<<"\nFile Created with Data with name annotation.txt \n";
myfile.close();
system("Pause");
}
I have a problem when it come to exit. if I input any value( even 0) I get a segmentation fault so i am not able to quit the loop and save my file in the txt, or re run it if I want to input more.. Let me know your thoughts.thanks
int i=0;
struct annotation_t obj[i];
You're making an array of annotation_t objects of 0 size
cin >> obj[i].topic ;
Then attempting to access the first element.
Consider using std::vector instead, which will allow you to dynamically change the size of your container to allow the user to input as many as they'd like:
// Empty container
std::vector<annotation_t> obj;
do
{
// Create temporary
annotation_t temp = {};
// Accept input:
cin >> temp.topic;
...
// Add to container:
obj.push_back(temp);
}
In your beneath for loop, you are doing the same thing as above
for(int i = 0;i<50;i++)
{
struct annotation_t obj[i];
Plus, you are creating a new container. You probably intend to use the container from above, which will change your loop into:
// Store the contents of the now populated obj from above
for (auto& a : obj)
{
myfile << a.stamp << " ";
myfile << a.topic << " ";
myfile << a.comment << std::endl;
}
You have problem with declaration 'obj' object.
This is wrong :
struct annotation_t obj[i];
Try this instead :
#include <iostream>
#include <string>
#include <ctime>
#include <fstream>
#include <cstdlib>
using namespace std;
struct annotation_t {
string topic;
string comment;
time_t stamp;
};
int main()
{
int q = 0;
struct annotation_t obj[1000]; //msf
int i=0; //msf
do
{
cout<< "input your topic";
cin >> obj[i].topic ;
cout<< "input yourfeedback";
cin >> obj[i].comment ;
cout<< "input your time stamp";
cin >> obj[i].stamp ;
cout<< "exit?";
cin >> q ;
i++; //msf
} while (q != 0);
ofstream myfile("annotation.txt");
int count=i; //msf
for(i = 0;i<count;i++) //msf
{
myfile<<obj[i].stamp <<" "; // write in file
myfile<<obj[i].topic <<" ";// write in file
myfile<<obj[i].comment; // write in file
myfile<<"\n";
}
cout<<"\nFile Created with Data with name annotation.txt \n";
myfile.close();
system("Pause");
}
I changed your code in many positions that I commented with '//msf'.
I don't have C++ compiler in hand then I hope it will be compiled without errors.
Related
I have a problem. I want to create an integer by user input. For example:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int i = 0;
char newVar;
string newVarName;
cout << "New Variable? (y/n)" << endl;
cin >> newVar;
if (newVar == 'y') {
/* newVarName declares new int with the name
of the user input (newVarName = test --> int test)*/
} else {
break;
}
return 0;
}
How can I do this?
As #Fantastic Mr Fox mentioned :
int name_dependant_on_user_input = value_from_user
This is impossible in c++, because the variable name, is a compile
time thing. The user input happens at runtime, which is after
compilation has completed. Something you could do, is map a string
input to your user input, for eg.
Some other error: String should be string or std::string. And using break; while not within loop or switch statements will return an error. If you want to escape immidiately, you could use exit(0);
Otherwise, as #Eljay mentioned above, a map<string, int> can be used to store both the name and value of your variable:
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main()
{
char newVar;
string newVarName;
map<string, int> varName;
cout << "New Variable? (y/n) : ";
cin >> newVar;
if (newVar == 'y') {
cout << "Name : "; cin >> newVarName;
cout << "Int : "; cin >> varName[newVarName];
} else {
exit(0);
}
//testing
cout << "Test : " << newVarName << " = " << varName[newVarName];
return 0;
}
Result:
New Variable? (y/n) : y
Name : var
Int : 5
Test : var = 5
Also, see why using namespace std; is considered a bad practice.
More info:
std::map : https://en.cppreference.com/w/cpp/container/map
std::string: https://en.cppreference.com/w/cpp/string/basic_string
In c++, you need to be aware of the common concepts of compile time and run time. So in your example:
// newVarName declares new int with the name of the user input
If you mean something like this:
int name_dependant_on_user_input = value_from_user
This is impossible in c++, because the variable name, is a compile time thing. The user input happens at runtime, which is after compilation has completed. Something you could do, is map a string input to your user input, for eg.
std::unordered_map<std::string, int> user_vars;
std::string variable_name;
int variable_value;
cin >> variable_name;
cin >> variable_value;
user_vars[variable_name] = variable_value;
...
for (const auto& value_pair : user_Vars) {
std::cout << "User value for " << value_pair.first << " is " << value_pair.second;
}
im trying to get the data from a string variable and put it into its own place in a string vector but it saves each word as its own point in the vector.
i.e. "buy milk" will result in 0 being buy then 1 being milk not 0 being buy milk.
sorry for not knowing the proper terminology im really new to C++
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string input;
vector <string> Notes;
int SaveNoteOnLine = 0;
string output; //a var needed for specific situations, not used for all output
cout << "welcome to cmdnotes alpha v1.0\n";
while (true) {
cin >> input;
if (input == "-list") {
for (int i = 0; i < SaveNoteOnLine; i++) {
cout << Notes.at(i) << endl;
}
}
else {
Notes.push_back(input);
cout << "saved on line " << SaveNoteOnLine << endl;
SaveNoteOnLine++;
}
}
}
Use
getline(cin,input) inplace of cin>>input it will take whitespaces as input
Our professor wants us to fix the code which counts the amount of values in a data.txt file and computes their average. Here is the code:
#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
string s;
ifstream f;
int nItems;
double * data;
double sum=0;
vector < double > data2;
double item;
cout <<"File name: ";
cin >> s;
f.open (s.c_str() );
while (! f.eof() )
{
f >> item;
data2.push_back(item);
}
for (int i =0; i < nItems; i++)
{
sum += data[i];
}
cout << "The average is " << sum/nItems <<".\n";
cout << "Press the enter key to continue ...";
cin.get();
return EXIT_SUCCESS;
}
His instructions were:
Modify code worked on today so that the average of data in vector < double > data is computed properly. Right now the code just gives you a value which isn't the average.
I tried changing the nItems variable into 12 and that seemed to work, but the goal of the code is to determine nItems and use that to find the average, which I can't seem to figure out.
You use data for which you haven't allocated any memory when you summarise That causes undefined behaviour. You've stored your values in data2. Remove variables you don't need. Also, using namespace std is considered bad practice.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <numeric> // std::accumulate
int main(int, char**) {
std::string filename;
std::cout << "File name: ";
std::cin >> filename;
std::ifstream f(filename); // no need for .c_str()
std::vector<double> data;
double item;
// instead of checking for eof, check if extraction succeeds:
while(f >> item) {
data.push_back(item);
}
// a standard way to sum all entries in a container:
double sum = std::accumulate(data.begin(), data.end(), 0.);
std::cout << "The sum is " << sum << "\n";
// use the containers size() function. it returns the number of items:
std::cout << "The average is " << (sum / data.size()) << "\n";
}
Hey looks like you weren't reading the numbers in from the txt file.
Here I look through the input file once just to count how many numbers there are
so I can make the array.
Then I look through it again to fill the array.
#include <cstdlib>
#include <iostream>
#include <fstream>
// f here stands for find, fstream gives you files
using namespace std;
int main(int argc, char *argv[]) {
string s;
ifstream f;
// input file stream
int nItems;
double * data;
double sum=0;
cout << "File name: ";
cin >> s;
f.open (s.c_str() );
// s.c_str will return a char array equivalent of the string s
nItems=0;
int input =0;
while (f >> input) {//first loop reading through file to count number of items
nItems++;
}
f.close();
data = new double[nItems]; //Make the array
f.open (s.c_str() );//open file for second read
int i=0;
while (f >> input) {//Second loop through file fills array
data[i] = input;
i++;
}
f.close();
for (int i = 0; i < nItems; i++) {
sum += data[i];
}
cout << "The average is " << sum / nItems << ".\n";
cout << endl;
system("pause");
return 0;
}
So, this program is meant to have three parallel arrays that carry the names of ten account holders, their IDs, and their balances. My main file looks like this:
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include "IOFunctions.h" // My header file
using namespace std;
int main ()
{
const int AR_SIZE = 10;
string nameAr;
int idAr;
float balanceAr;
// F U N C T I O N -- ReadInData
ReadInData(nameAr,
idAr,
balanceAr,
AR_SIZE);
}
The error I'm getting looks like this: http://i.imgur.com/1eHOZ7K.png
Now, the header file looks like this:
#ifndef IOFUNCTIONS_H_ // This is my own header
#define IOFUNCTIONS_H_
#include <iomanip>
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
string ReadInData(string nameArray[],
int idArray[],
float balanceArray[],
const int ARRAY_SIZE)
{
ifstream inFile;
string inFileName;
string outFileName;
// INPUT -- Prompts user for input file name
cout << left << setw(40)
<< "What input file would you like to use? ";
getline(cin, inFileName);
// Checks that the file name entered is accessible
while(inFileName != "InFile.txt")
{
cout << setw(40) << "Please enter a valid file name: ";
getline(cin, inFileName);
}
// INPUT -- Prompts user for output file name
cout << setw(40)
<< "What output file would you like to use? ";
getline(cin, outFileName);
// Checks that the file name entered is accurate to assignment
while(outFileName != "OFile.txt")
{
cout << setw(40) << "Please enter a valid file name: ";
getline(cin, outFileName);
}
// PROCESSING -- Takes the data from the input file and assigns it
// to the names array, ID array, and balance array
// NAME ARRAY
inFile.open(inFileName.c_str());
for(int index = 0; index < ARRAY_SIZE; index++)
{
inFile >> nameArray[index];
}
inFile.close();
// ID ARRAY
inFile.open(inFileName.c_str());
for(int index = 0; index < ARRAY_SIZE; index++)
{
inFile >> idArray[index];
}
inFile.close();
// BALANCE ARRAY
inFile.open(inFileName.c_str());
for(int index = 0; index < ARRAY_SIZE; index++)
{
inFile >> balanceArray[index];
}
inFile.close();
return outFileName;
}
#endif /* IOFUNCTIONS_H_ */
All help is greatly appreciated. If I'm missing anything, please let me know.
ReadInData takes a string*, but you are passing it a string. Fix this by passing a reference:
string ReadInData(string &nameArray, //<--
int idArray[],
float balanceArray[],
const int ARRAY_SIZE)
I am trying to read the two words "kelly 1000" in the text file "players", into vectors players and balances respectively. Don't know why it's not working?
string name = "kelly";
int main()
{
int num =0;
vector<string> players;
vector<int> balances;
ifstream input_file("players.txt");
while(!input_file.eof())
{
input_file >> players[num];
input_file >> balances[num];
num++;
}
for(size_t i = 0; i=players.size(); i++)
{
if(name==players[i])
cout << "Welcome " << name << ", your current balance is " << balances[i] << "$." << endl;
else
break;
}
With operator[] you can only access existing elements. Going out of bounds invokes undefined behaviour. Your vectors are empty and you need to use push_back method to add elements to them.
Second problem is while (!file.eof()) anti-pattern. It'll typicaly loop one to many times because the read of last record doesn't neccesarily trigger eof. When reading from streams, always check whether input succeeded before you make use of values read. That's typicaly done by using operator>> inside loop condition.
string temp_s;
int temp_i;
while (input_file >> temp_s >> temp_i) {
players.push_back(temp_s);
balances.push_back(temp_i);
}
This way the loop stops if operator>> fails.
//Hope this is something you want dear.Enjoy
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
string name = "kelly";
int main()
{
int num =0;
string tempname;
int tempbalance;
vector<string> players;
vector<int> balances;
ifstream input_file("players.txt");
while(!input_file.eof())
{ input_file>>tempname;
input_file>>tempbalance;
players.push_back(tempname);
balances.push_back(tempbalance);
}
for(size_t i = 0; i<players.size(); i++)
{
if(name==players.at(i))
cout<< "Welcome " << name << ", your current balance is " << balances.at(i)<< "$." << endl;
}
return 0;
}