(C++) Trying to remember where to define functions - c++

It's be awhile since I touched C++, but I'm writing inside my main I have a function called "solution" and right now that line is giving me the error: "a function definition is not allowed here before '{'"
Afterwards I thought I was supposed to write my funciton definitions after my main(), but that led to another slue of errors.
Also, as my code stands, I get the error of "invalid arguments" when I call my function solution and pass it to my outfile.
I also get the error on the final '{' of "expected '{' at end of input."
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;
int main(int argc, char** argv) {
ifstream infile("TEST.txt", std::ifstream::in);
string line;
vector<string> inputLines;
if(infile.is_open()){
while(getline(infile, line)){
cout << line << '\n';
inputLines.push_back(line);
}
}
infile.close();
ofstream outfile("output.txt", std::ofstream::out);
for(unsigned int i = 1; i < inputLines.size(); i+= 3){
int credit = inputLines[i];
int numofItems = inputLines[i+1];
int numofItemscopy = inputLines[i+1];
vector<int> items;
stringstream ssin(inputLines[i+2]);
int x = 0;
while(ssin.good() && x < numofItems){
ssin >> items[x];
++x;
}
outfile << solution(credit,
numofItems,
numofItemscopy,
items.size());
outfile << inputLines[i] << '\n';
}
outfile.close();
return 0;
}
string solution(int cred, vector<int> original, vector<int> copy, int size){
for(int i = 0; i < size; i++ ){
for (int ii = 0; ii < size; ii++){
if(original[i] + copy[ii] == cred){
return std::string(i) + std::string(ii);
}
}
}
return "";
}
EDIT:
I put my solution function after my main, now I am getting the following errors:
On all three lines of :
int credit = inputLines[i];
int numofItems = inputLines[i+1];
int numofItemscopy = inputLines[i+1];
I get the error: "cannot convert ‘std::basic_string’ to ‘int’ initialization"
Also when I call my "solution" function:
outfile << solution(credit,
numofItems,
numofItemscopy,
items.size());
I get the error that "Solution was not declared in this scope."

First of all, you need to declare your function before you use it in your main function. You can then define it after your main function if you so desire. The compiler goes from top to bottom, and it only knows about what it has seen up to that point. The compiler has not yet seen the solution function when you call it in main, so it does not know what to do.
string solution(int cred, vector<int> original, vector<int> copy, int size);
Your declaration should look like this. To declare a function you just take its header and instead of giving it a body with {}, you just end the line with a ; like follows.
int num = stoi("32");
As for parsing strings to integers, in C++11 you can do that simply as seen above. See more info on that here: https://stackoverflow.com/a/11354496/2749485
See below for how your code should now look:
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;
string solution(int cred, vector<int> original, vector<int> copy, int size);
int main(int argc, char** argv) {
ifstream infile("TEST.txt", std::ifstream::in);
string line;
vector<string> inputLines;
if(infile.is_open()){
while(getline(infile, line)){
cout << line << '\n';
inputLines.push_back(line);
}
}
infile.close();
ofstream outfile("output.txt", std::ofstream::out);
for(unsigned int i = 1; i < inputLines.size(); i+= 3){
int credit = stoi(inputLines[i]);
int numofItems = stoi(inputLines[i+1]);
int numofItemscopy = stoi(inputLines[i+1]);
vector<int> items;
stringstream ssin(inputLines[i+2]);
int x = 0;
while(ssin.good() && x < numofItems){
ssin >> items[x];
++x;
}
outfile << solution(credit,
numofItems,
numofItemscopy,
items.size());
outfile << inputLines[i] << '\n';
}
outfile.close();
return 0;
}
string solution(int cred, vector<int> original, vector<int> copy, int size){
for(int i = 0; i < size; i++ ){
for (int ii = 0; ii < size; ii++){
if(original[i] + copy[ii] == cred){
return std::string(i) + std::string(ii);
}
}
}
return "";
}

Function definitions should go before your main() if you want to have them in the same source file

Related

C++ string array about nums

Say the strings is "Asah1234&^%736hsi)(91",
than storage 1234,736,91 in three arrays
In general,i want to put each continuous nums in each array.
Queations: how many arrays i will need,what's the size of each group of numbers,how to make the loop.
I want to write a fuction to do it.
#include<iostream>
using namespace std;
void splitString(string str)
{
string num;
for (int i = 0; i < str.length(); i++)
{
if (isdigit(str[i]))
num.push_back(str[i]);
}
cout << num << endl;
}
int countnum( string str)
{
string num;
int sum = 0;
for (int i = 0; i < str.length(); i++)
{
if (isdigit(str[i]))
sum++;
}
cout << sum << endl;
return 0;
}
int main()
{
const int MAXLEN = 100;
char str[MAXLEN];
printf("please enter strings:");
scanf_s("%s", str, MAXLEN);
splitString(str);
countnum( str);
return 0;
}
Maybe I have a misunderstanding here. Then please comment and I will delete the answer.
This is a standard task and will be solved with a regex. It is just the definition of a variable and initialzing this variable with its range constructor. So, a one-liner.
There is no further statement needed.
Please see:
#include <iostream>
#include <string>
#include <regex>
#include <vector>
std::regex re{ R"(\d+)" };
int main() {
// The input string with test data
std::string test{"Asah123&^%736hsi)(918"};
// Define a variable numbers and use the range constructor to put all data in it
std::vector numbers(std::sregex_token_iterator(test.begin(), test.end(), re), {});
// Show the result on the screen
for (const auto& n : numbers) std::cout << n << "\n";
return 0;
}

Having issue with file input in my C++ program

My code compiles but for some reason there is one error that comes up:
Error:Multiple markers at this line - Invalid arguments ' Candidates are: void open(const char *, enum std::_Ios_Openmode) ' - no
matching function for call to 'std::basic_ifstream::open(std::__cxx11::string&)'
I cannot seem to figure out why this error is thrown.
Here's my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(){
int array_for_numbs[10];
int numbers[9]={1,2,3,4,5,6,7,8,9};
int counttarr[9]={0};
ifstream fileinpt;
int num, dgt;
string txtfile;
cout<<"enter the test file:";
cin >> txtfile;
fileinpt.open(txtfile);// this line is where the error pops up :(
int i=0;
while (!fileinpt.eof())
{
fileinpt >> array_for_numbs[i];
i=i+1;
}
fileinpt.close();
for(int i = 0; i < 10; i++)
{
num=array_for_numbs[i];
do
{
dgt=num%10;
num=num/10;
}while(num>0);
for(int i = 0; i < 9; i++)
{
if(dgt==numbers[i])
{
counttarr[i]=counttarr[i]+1;
}
}
}
cout<<"Digit \t"<< "Count \t"<<"Frequency "<<endl;
for(int i = 0; i < 9; i++)
{
float frq=(float)counttarr[i]/(float)100;
cout<<(i+1)<<"\t"<< counttarr[i]<<"\t" <<frq<<endl;
}
system("pause");
return 0;
}
"open" function filename argument has char* datatype, however, you are trying to pass std::string type path. Open function is a C function which is not aware of std::string type.
You have to cast/convert std::string to char*
Use;
fileinpt.open(txtfile.c_str());

I want to create a function in c++ to read a file having the file as an argument, but I have problems when I compile the program

This is the function that read the file
void read_function(istream& filename, vector< vector<double> >& v)
{
//vector<vector<double> > v;
if (filename)
{
string linea;
int i = 0;
while (getline(filename, linea))
{
v.push_back(vector<double>());
stringstream split(linea);
double value;
while (split >> value)
{
v.back().push_back(value);
}
}
}
};
The main function
int main(int argc, char const *argv[]){
if (argc < 2)
{
cerr << "input file's name\n"<< endl;
}
string program_name = argv[0];
ifstream input;
input.open(argv[1]);
vector< vector<double> > array;
for (int i = 0; i < array.size(); i++)
{
for (int j = 0; j < array[i].size(); j++)
cout << read_function(argv[1], array) << '\t';
cout << endl;
}
return 0;
}
When I compile the code I get the following errors messages
error: invalid initialization of reference of type ‘std::istream& {aka std::basic_istream&}’ from expression of type ‘const char*’
cout << read_function(argv[1], array) << '\t';
error: in passing argument 1 of ‘void read_function(std::istream&, std::vector >&)’
void read_function(istream& filename, vector< vector >& v)
Please dont take this the wrong way, but the errors you made in your code look like this might be a too difficult task for your level of programming skills.
You make a couple of mistakes:
You (kind of) declare input in main but try to use it in read_function
the parameters you use in getline are incorrect
the first parameter of read_function is of type ifstream not char*
getline is a member function of ifstream
read_function returns nothing, so cout<<read_function(...) is incorrect
I would suggest before trying to use more complicated things like sstream, fstream or vector you first try to understand how to call a function, what the parameters and their types are, what an object is and how to access its members.
I corrected your mistakes, the code below only reads in numbers from your input file, no characters. I assumed that was your goal, since you used a double vector. Also there are more elegant ways to do this, but I tried to stay as close to your code as possible.
code:
#include<fstream>
#include<iostream>
#include<vector>
#include<sstream>
using namespace std;
void read_function(char* filename, vector< vector<double> >& v)
{
int maxNumberOfCharsPerLine=1000;
ifstream input;
input.open(filename);
if(input.is_open())
{
char* inputChar;
string linea;
while (input.getline(inputChar, maxNumberOfCharsPerLine))
{
linea=inputChar;
v.push_back(vector<double>());
stringstream split(linea);
double value;
while (split >> value)
{
v.back().push_back(value);
}
}
}
input.close();
}
int main(int argc, char const *argv[]){
if (argc < 2)
{
cerr << "no input file's name\n"<< endl;
}
vector< vector<double> > array;
read_function((char*)argv[1], array);
for (int i = 0; i < array.size(); i++)
{
for (int j = 0; j < array[i].size(); j++)
{
cout << array[i][j] <<" ";
}
cout << endl;
}
return 0;
}

For-Loop - value of i is not 0 even if code says 'int i = 0'. i = BIG number, why? How to fix?

I'm designing a program to clean up a text file that contains code. It removes comments, excess spaces/lines, and creates a new line for lines in the file with multiple semi-colons.
I actually got this program to work, but it used arrays. Since I am working on another program that builds on this, except with a more diverse size of data inputs, I'm converting it to use vectors instead of standard arrays so I can re-purpose the program...which is kind of the point.
My problem is that after the program iterates through the first for-loop, the rest of the for-loops initialize the iterator with a value of '3435973836', regardless of proper declaration ('int i = 0', 'int k = 0', etc). I declare them unsigned and omitting singed/unsigned still initializes the value incorrectly (-858993460).
This does 1 of 2 things:
unsigned the loop never starts as the value is too high to start the loop.
omitting makes the loop run for a long, long time.
Any thoughts? I've posted the code below. Please ignore any other errors I've made other than this, as I have been unable to get past this to debug anything else.
EDIT --> SOLVED: the problem that I was passing the vectors by value. But even when I changed it to pass by reference the program would still not work. The actual problem was with Microsoft Visual Studio 2012. Once I PBV once, it corrupted my project. I had to start a new VS project and insert the code. If you do this, be careful you don't run the program while still PBV or you'll have to do it again. I don't know why this happens. Maybe somebody who knows MS Visual Studio could answer that.
Thanks again community!
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
void removeComments(vector<string> row, ifstream & myfile);
void sortLines (vector<string> row);
//void cleanCode (vector<string> row);
int main()
{
vector<string> row;
ifstream myfile;
//Open txt file
myfile.open("newdata.txt");
if(myfile.is_open())
{
//Remove comments, create proper lines, and remove/add spaces.
removeComments(row, myfile);
sortLines(row);
//cleanCode(row);
}
else
{
cout<< "ERROR: No file was able to open. Check the file name or location and try again."<< endl << endl;
}
for (unsigned int i = 0; i < row.size(); i++)
{
cout<< row[i] << endl;
}
cout<< endl;
myfile.close();
system("PAUSE");
return 0;
}
//FUNCTIONS
//Removes all comments.
void removeComments(vector<string> row, ifstream & myfile)
{
string line;
while(getline(myfile, line))
{
string tempString;
for(unsigned int i = 0; i < line.length(); i++)
{
//Copy characters to row string array until "//".
//All character following and including "//" will be ignored.
if(line.at(i) == '/' && line.at(i+1) == '/')
{
break;
}
else
{
tempString += line.at(i);
}
}
row.push_back(tempString);
}
}
//Creates a new line after every semi-colon.
void sortLines (vector<string> row)
{
vector<string> tempRow;
string tempLine;
string tempString;
for (unsigned int i = 0; i < row.size(); i++)
{
tempLine = row [i];
for (unsigned int j = 0; j < tempLine.length(); j++)
{
tempString += tempLine[j];
if (tempLine[j] == ';')
{
tempRow.push_back(tempString);
}
}
}
//Revalue row array elements.
//DEBUGGING OUTPUT
for (unsigned int i = 0; i < tempRow.size(); i++)
{
cout<< tempRow[i] << endl;
}
row.clear();
row = tempRow;
}
Okay, this is my by-reference edit:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
void removeComments(vector<string> &row, ifstream & myfile);
void sortLines (vector<string> &row);
//void cleanCode (vector<string> &row);
int main()
{
vector<string> row;
ifstream myfile;
//Open txt file
myfile.open("newdata.txt");
if(myfile.is_open())
{
//Remove comments, create proper lines, and remove/add spaces.
removeComments(row, myfile);
sortLines(row);
//cleanCode(row);
}
else
{
cout<< "ERROR: No file was able to open. Check the file name or location and try again."<< endl << endl;
}
for (unsigned int i = 0; i < row.size(); i++)
{
cout<< row[i] << endl;
}
cout<< endl;
myfile.close();
system("PAUSE");
return 0;
}
//FUNCTIONS
//Removes all comments.
void removeComments(vector<string> &row, ifstream & myfile)
{
string line;
while(getline(myfile, line))
{
string tempString;
for(unsigned int i = 0; i < line.length(); i++)
{
//Copy characters to row string array until "//".
//All character following and including "//" will be ignored.
if(line.at(i) == '/' && line.at(i+1) == '/')
{
break;
}
else
{
tempString += line.at(i);
}
}
row.push_back(tempString);
}
}
//Creates a new line after every semi-colon.
void sortLines (vector<string> &row)
{
vector<string> tempRow;
string tempLine;
string tempString;
for (unsigned int i = 0; i < row.size(); i++)
{
tempLine = row [i];
for (unsigned int j = 0; j < tempLine.length(); j++)
{
tempString += tempLine[j];
if (tempLine[j] == ';')
{
tempRow.push_back(tempString);
}
}
}
//Revalue row array elements.
//DEBUGGING OUTPUT
for (unsigned int i = 0; i < tempRow.size(); i++)
{
cout<< tempRow[i] << endl;
}
row.clear();
row = tempRow;
}
As others have noted you're:
Passing vectors by value
Using something possibly uninitialized out-of-my-scope (this is nowhere declared/defined in your question) as increment variable
//Creates a new line after every semi-colon.
void sortLines (vector<string> row)
{
vector<string> tempRow;
string tempLine;
string tempString;
for (unsigned int i = 0; i < row.size(); k++) // <-- what is k??
{
Why pass "string line" to removeComments? It should be local to that function cos you don't use it outside. It looks dodgy for the same reason that the passed vectors did.

Traverse file vertically

I need to traverse a file in a vertical manner. If suppose the file contents are:
adg
beh
cfi
It should print the file as:
abc
def
ghi
The length for each line will be same(i.e. all lines will be of length 3 for above example). I have written a code but it doesn't traverse the file as required.
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int main()
{
fstream fs;
fs.open("asd.txt",ios::in);
string str;
char *ch = new char();
int lineLen = 0, k = 0;
if(getline(fs,str))
{
lineLen = str.length();
}
fs.seekg(0);
if(lineLen > 0)
{
for(int i = 0;i<lineLen;i++)
{
fs.seekg(i+k*lineLen);
while(fs.read(ch,1))
{
k++;
fs.seekg(i+k*lineLen);
cout<<*ch;
}
k = 0;
}
}
fs.close();
cin.ignore();
}
I am a bit new to file handling and couldn't find the mistake. Also, is there a better approach for this to be followed?
Pretty much your way with some little tweaks
//lines = no. of lines in file
fs.seekg(0, fs.beg);
fs.clear();
if(lineLen > 0)
{
for(int k = 0; k < lineLen; k++) {
for(int i = 0;i<lines;i++){
fs.seekg(k+i * (lineLen + 2), fs.beg); //use lines + 2
if(fs.read (ch,1));
cout << *ch;
}
cout << endl;
}
Untested pseudo-code that may give you some ideas. Basically, load the whole file into a 2d vector of characters for easy access. It will use more memory than reading directly from the file but this won't matter unless the file is very big.
vector<vector<char>> filemap;
string line;
while (getline(filestream, line))
{
filemap.push_back(vector<char>(line.begin(), line.end()));
}
for (int x = 0; x < XSIZE; x++)
{
for (int y = 0; y < YSIZE; y++)
{
filestream << filemap[y][x]; // note x/y are opposite way round in 2d vectors
}
filestream << '\n';
}
You might find this task much simpler if you were to use mmap(2). There may be a C++ equivalent or wrapper, but I'm afraid I'm not much of an expert on that front. Hopefully someone will come along with a better answer if that's the case.
Here's a quick C (not ++) example. I'll see if I can google around and C++ify it some more:
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
int main(void)
{
int fd = open("input", O_RDONLY);
struct stat s;
fstat(fd, &s);
// map the file as one big string
char *c = mmap(0, s.st_size, PROT_READ, MAP_SHARED, fd, 0);
// calculate sizes
int columns = strchr(c, '\n') - c; // first newline delimits a row
int stride = columns + 1; // count the newline!
int rows = s.st_size / stride; // all rows are the same length
for (int x = 0; x < columns; x++)
{
for (int y = 0; y < rows; y++)
{
putchar(c[y*stride + x]);
}
putchar('\n');
}
munmap(c, s.st_size);
close(fd);
return 0;
}
Edit: A quick search around didn't turn up a much better way to handle this in C++ as far as I could tell. I mean, I can add a typecast on the mmap line and change the putchar calls to std::cout, but that doesn't really seem like it makes any difference.
Instead of trying to seek() repeatedly in the source file it is much easier and faster to simply read in the whole source file then generate output from the in-memory contents.
This sounds an awful like like a class assignment, so I won't simply write the answer for you. However this should point you in the right way -- Some PseodoCode is included
To avoid pain, it should presumably be safe to assume some upper bound on line length and max lines, i.e.,
const int MaxLines = 100;
const int MaxLength = 80;
int lineno, linelength;
// array of char pointers for each line
char *lines[] = (*lines[])malloc(Maxlines * sizeof(char*));
// ReadLoop
lineno = 0;
while (not eof)
{
getline(buffer);
if (++lineno++ == 1)
{
linelength = strlen(buffer);
}
else
{
if (linelength != strlen(buffer))
{
cout "Line # " << lineno << " does not match the expected length";
exit();
}
}
lines[lineno] = malloc(strlen(buffer)+1));
strcpy(lines[lineno], buffer);
}
int cc, linecnt = lineno;
// now all data in memory, output "vertical data"
for (cc = 0; cc < linelength; ++cc)
{
for (lineno=0; lineno<<linelength; ++lineno)
{
cout << lines[xx][yy]; // xx && yy left you to figure out
}
cout "\n";
}
Provided that your file is not enormous, there's no reason not to just slurp the whole thing into memory. There may be a more idiomatic way to do this in C++, but the following works:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
int main(int argc, char *argv[])
{
std::fstream infile("foo.txt");
std::vector<std::string> lines;
std::string line;
while(std::getline(infile,line)) {
lines.push_back(line);
}
int m=lines.size();
int n=lines[0].length();
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
std::cout << lines[j].at(i);
}
std::cout << std::endl;
}
return 0;
}
Problems arise when all the lines in the file are not the same length, of course.
And now, a version that “doesn't use any extra memory” (of course, it does, but not much):
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <algorithm>
int main(int argc, char *argv[])
{
std::fstream infile("foo.txt");
std::vector<std::string> lines;
std::string line;
std::getline(infile, line);
int n = line.length();
int m = 1+std::count(std::istreambuf_iterator<char>(infile),
std::istreambuf_iterator<char>(), '\n');
infile.clear();
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
infile.seekg(j*m+i);
std::cout << char(infile.peek());
}
std::cout << std::endl;
}
return 0;
}