c++ ofstream(someVariable) initialization - c++

So I tried to do this:
#include <iostream>//For cout/cin
#include <fstream> //For ifstream/ofstream
using namespace std;
int main()
{
string types[] = {"Creativity", "Action", "Service"};
for(int i = 0; i < sizeof(types)/sizeof(string); i++) {
string type = types[i];
string filename = type + ".html";
ofstream newFile(filename);
//newFile << toHTML(getActivities(type));
newFile.close();
}
return 0;
}
and I'm being hit with errors. I'm new to C++, so I don't know what to try, or if this is even possible (SURELY it is...).
I tried the following, but it was really just a stab in the dark and didn't help:
#include <iostream>//For cout/cin
#include <fstream> //For ifstream/ofstream
using namespace std;
int main()
{
string types[] = {"Creativity", "Action", "Service"};
for(int i = 0; i < sizeof(types)/sizeof(string); i++) {
string type = types[i];
//Attempting to add const..
const string filename = type + ".html";
ofstream newFile(filename);
//newFile << toHTML(getActivities(type));
newFile.close();
}
return 0;
}
I mean, its all happy if I do `ofstream newFile("somefile.html");

The original IOstream library didn't have a constructor taking a std::string. The only type supported was char const*. You can get a char const* from a std::string using c_str():
std::string name("whatever");
std::ofstream out(name.c_str());
The type of a string literal isn't of type std::string but it is of type char const[n] where n is the number of characters in the string, including the terminating null character.
In C++ 2011 the File stream classes are improved to also take std::string where a string is expected.

Related

i am trying to use getline to read a csv file line by line and separate the data in the file and turn a string into int

I am a beginner and I just need a bit of help on why I getline is showing an error:
this is what I have so far
#include <iostream>
#include <iomanip>
#include <cmath>
#include <fstream>
using namespace std;
const double TAX_RATE = 0.0825;
const int MAX_ITEMS = 1000;
const int MAX_TRANSACTIONS = 100;
int main(int argc, char const *argv[]){
string fname = "";
int itemCnt = 0, start = 0, end = 0;
int ids[MAX_ITEMS], qtys[MAX_ITEMS];
double costs[MAX_ITEMS], subtotals[MAX_TRANSACTIONS],
taxes[MAX_TRANSACTIONS], totals[MAX_TRANSACTIONS];
string names[MAX_ITEMS], paymentTypes[MAX_ITEMS], payments[MAX_ITEMS];
ifstream iFile;
if ( argc != 2 ) {
cout<<"usage: "<< argv[0]<< " <file name>" <<endl;
return 0;
} else {
iFile.open(argv[1]);
}
if (!iFile) {
cout<<"Error: Invalid file name"<<endl;
cin.clear();
}
while (!iFile.eof())
{
getline(iFile,str); //this isn't working
int commaLoc = str.find(',');
ids[itemCnt]= str.substr(0,commaLoc);
str = str.substr(commaLoc +1, str.length());
//string to int I'm not sure how to do I know its something with stoi() but not sure how to format it
}
return 0;
}
I am able to get the file to open but I'm not sure why getline isn't working it keeps saying something like
no instance of overload function
My csv file looks like:
1,Laptop,799.99,1,cash,1100
I need it to read the first number and because Its a string i don't know how to save it as an int
Multiple errors. First there is nothing called 'str' in your program. I will guess its just a string used as a temp buffer
do not do this (!File.eof) it doesnt do what you think.
while (iFile)
{
string str; <<<<<==== added
getline(iFile,str); //this isn't working <<<===is now
int commaLoc = str.find(',');
Next this line doesnt work because ids are ints and substring returns a string.
// ids[itemCnt]= str.substr(0,commaLoc);
ids[itemCnt]= stoi(str.substr(0,commaLoc)); <<<<==== fixed
str = str.substr(commaLoc +1, str.length());
}
I strongly recommend you use std::vector instead of c-style fixed size arrays. Takes 5 minutes to learn how to use them and they have huge benefits. If you must use fixed size arrays use std::array instead of c-style
You can read a string and try to convert it to a number in different ways. For example, since C++17, you can use from_chars. One of its overloads:
Receives a pair of begin and end char pointers, and an int variable,
tries to parse an int number, and
and returns the parsed number, together with a pointer to the first character that wasn't part of the match.
int i{};
auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), i);
if (ec == std::errc{}) { /* do something with i */} else { /* error */ }
[Demo]
Full code (using a istrinstream instead of a ifstream):
#include <charconv> // from_chars
#include <iomanip>
#include <iostream>
#include <sstream> // istringstream
#include <system_error> // errc
constinit const int MAX_ITEMS = 10;
int main() {
std::istringstream iss{
"1,Laptop,799.99,1,cash,1100\n"
"2,PC,688.88,2,card,1101\n"
"blah,Keyboard,39.00,3,cash,1102"
};
size_t itemCnt{};
int ids[MAX_ITEMS]{};
std::string str{};
while (std::getline(iss, str)) {
// Parse counter
int i{};
auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), i);
if (ec == std::errc{}) {
ids[itemCnt] = i;
// Remaining string
std::string remaining_string{ str.substr(ptr - str.data() + 1) };
std::cout << ids[itemCnt] << ", " << remaining_string << "\n";
}
else {
std::cout << "Error: invalid counter.\n";
}
++itemCnt;
}
}
// Outputs:
//
// 1, Laptop,799.99,1,cash,1100
// 2, PC,688.88,2,card,1101
// Error: invalid counter.

C++ How to write function that return char pointer

I want to write a function that receive an int argument then converter to a char pointer (c-string), but my code output is not right.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
char *stoc(int n){
stringstream stream;
stream <<"Log"<<n<<".txt";
string name;
stream >>name;
int len = name.length();
char ch[len+1];
for(int i=0; i<len; i++){
ch[i]=name[i];
}
ch[len+1] = '\0';
return ch;
}
int main() {
char *name = stoc(3);
cout << name << endl;
return 0;
}
Summarising the comments:
You normally do not use C-style-strings in C++, just stick to std::strings. Therefor you should rather return name instead of your converted ch, especially since you have already created a std::string. Having access to at least C++11 you can then easily convert your rather long function into a one-liner
C++11
std::string stoc(int n) {
return "Log" + std::to_string(n) + ".txt";
}
prior C++11
std::string stoc(int n) {
std::ostringstream oss;
oss << "Log" + n + ".txt";
return oss.str(); // by accessing a stringstreams content directly there is no need to use an extra variable
}
If you do need to use a C-style-string later on somewhere, e.g. as a parameter for a C-library function, you can use c_str to convert any std::string into it's C-style equivalent:
int main() {
std::string name = stoc(3);
std::cout << name << std::endl;
}
You should do this instead of returning a pointer to a local variable (which yields in undefined behaviour):
...
char *ch = new char[len+1];
for(int i=0; i<len; i++){
ch[i]=name[i];
}
ch[len] = '\0';
...
int main() {
char *name = stoc(3);
cout << name << endl;
delete [] name; // delete what has been allocated in stoc
return 0;
}
Also note the ch[len] = '\0' instead of ch[len + 1] = '\0'.
But in C++ you should rather use std::string and not deal with char arrays, new and delete at all.

Create string of specific length in C++

For my class, I have to take three strings, then center them.
Here's a link to the problem, and no, I'm not asking for the answer to the problem!
http://www.hpcodewars.org/past/cw3/problems/Prog05.htm
I have everything I need, but I need to create a string of "*" with a specific length. In this case, it needs to be 21 characters long of asterisks, and I don't know how to create that.
I mean, yeah, I can do
string test = "********************"
but it needs to be a different length as it changes.
I have a variable set to how long the string needs to be, but I need to know how to create a string with a specific length, then add in the asterisks.
Code so far:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string line;
string lines[2];
int x = 0;
int maxLength;
ifstream myfile ("example.txt");
if (myfile.is_open()) // opening file, setting the strings in the input stream to a variable to use at a later time
{
while ( getline (myfile,line) )
{
lines[x] = line;
x++;
}
myfile.close();
}
if(lines[0].length() > lines[1].length()) //finding the max length;
{
maxLength = lines[0].length();
}else
{
maxLength = lines[1].length();
}
if(lines[2].length() > maxLength)
{
maxLength = lines[2].length();
}
maxLength = maxLength + 4;
cout<<maxLength<<endl;
return 0;
}
It's much simpler than you think. std::string has a constructor just for this purpose:
#include <string>
#include <iostream>
int main()
{
std::string s(21, '*');
std::cout << s << std::endl;
return 0;
}
Output:
*********************

Initializer but incomplete type?

The following code gives me 2 errors when i compile
#include <iostream>
#include <fstream>
#include <cstring>
#include "Translator.h"
using namespace std;
void Dictionary::translate(char out_s[], const char s[])
{
int i;
char englishWord[MAX_NUM_WORDS][MAX_WORD_LEN];
for (i=0;i < numEntries; i++)
{
if (strcmp(englishWord[i], s)==0)
break;
}
if (i<numEntries)
strcpy(out_s,elvishWord[i]);
}
char Translator::toElvish(const char elvish_line[],const char english_line[])
{
int j=0;
char temp_eng_words[2000][50];
//char temp_elv_words[2000][50]; NOT SURE IF I NEED THIS
std::string str = english_line;
std:: istringstream stm(str);
string word;
while( stm >> word) // read white-space delimited tokens one by one
{
int k=0;
strcpy (temp_eng_words[k],word.c_str());
k++;
}
for (int i=0; i<2000;i++) // ERROR: out_s was not declared in this scope
{
Dictionary::translate (out_s,temp_eng_words[i]); // ERROR RELATES TO THIS LINE
}
}
Translator::Translator(const char dictFileName[]) : dict(dictFileName)
{
char englishWord[2000][50];
char temp_eng_word[50];
char temp_elv_word[50];
char elvishWord[2000][50];
int num_entries;
fstream str;
str.open(dictFileName, ios::in);
int i;
while (!str.fail())
{
for (i=0; i< 2000; i++)
{
str>> temp_eng_word;
str>> temp_elv_word;
strcpy(englishWord[i],temp_eng_word);
strcpy(elvishWord[i],temp_elv_word);
}
num_entries = i;
}
str.close();
}
}
The first one is at std::string istringstream stm(str); where it says it the variable has an initializer but incomplete type. If I put in std::string istringstream stm(str); it says expected initializer before stm andstm was not declared in the scope.
It also says out_s was not declared in this scope at Dictionary::translate (out_s,temp_eng_words[i]);. I don't see why one parameter is recognisied and one is not?
Thanks in advance.
You have to include header file:
#include <sstream>
#include <string>
when you want to use stringstream and string.
Meanwhile:
Dictionary::translate (out_s,temp_eng_words[i]);
If out_s is not a member of the class, you seems forgot to define out_s before using it inside toElvish.
Meanwhile:
while( stm >> word) // read white-space delimited tokens one by one
{
int k=0; //^^Why do you initialize k everytime you read a word?
strcpy (temp_eng_words[k],word.c_str());
k++;
}
You just need to include sstream
Your translator would be much simpler if you used std::map.
#include <map>
#include <string>
// map[english word] returns the elvish word.
typedef std::map<std::string, std::string> Dictionary;
// Define the dictionary
Dictionary english_to_elvish_dictionary;
std::string To_Elvish(const std::string& english_word)
{
Dictionary::iterator iter;
std::string elvish_word;
iter = english_to_elvish_dictionary.find(english_word);
if (iter != english_to_elvish_dictionary.end())
{
// English word is in dictionary, return the elvish equivalent.
elvish_word = *iter;
}
return elvish_word;
}
The above code fragment replaces most of your code and reduces your issues with arrays of arrays of C-strings. Less code == less problems.
To see a list of issues your having, search StackOverflow for "[c++] elvish english".

strcpy c++ cannot convert parameter 1 from string char*

i am trying to put the words that there are in a txt file* into an array of strings.
But there is an error with the strcpy(). it sais: 'strcpy' : cannot convert parameter 1 from 'std::string' to 'char *' . Why is that? Isn't it possible to create an array of strings like this in c++?
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void ArrayFillingStopWords(string *p);
int main()
{
string p[319];//lekseis sto stopwords
ArrayFillingStopWords(p);
for(int i=0; i<319; i++)
{
cout << p[i];
}
return 0;
}
void ArrayFillingStopWords(string *p)
{
char c;
int i=0;
string word="";
ifstream stopwords;
stopwords.open("stopWords.txt");
if( stopwords.is_open() )
{
while( stopwords.good() )
{
c = (char)stopwords.get();
if(isalpha(c))
{
word = word + c;
}
else
{
strcpy (p[i], word);//<---
word = "";
i++;
}
}
}
else
{
cout << "error opening file";
}
stopwords.close();
}
I suggest strcpy (p[i], word); be changed to p[i] = word;. This is the C++ way of doing things and takes advantage of the std::string assignment operator.
You don't need strcpy here. A simple assignment will do it: p[i] = word;. strcpy is for C-style strings, which are null-terminated arrays of characters:
const char text[] = "abcd";
char target[5];
strcpy(target, text);
Using std::string means you don't have to worry about getting the size of the array right, or about calling functions like strcpy.