Expected Primary-Expression before ']' token? - c++

I'm trying to be able to call a function with the vector and for some reason it's saying "expected primary expression before ']'. The vector could hold any number of files, depending on the amount of numbers in myfile, so I'm not sure what I should put there.
#include <fstream>
#include <string>
#include <vector>
#include <iostream>
using namespace std; // not recommended
double averageCalc(string[],int);
int main () {
double average;
string line;
ifstream myfile ("array_pgmdata.txt");
//int index = 0; // not needed
//string myArray[index]; // UB - if it even compiles, it's a VLA of size 0.
std::vector<std::string> myArray; // use this instead to be able to grow it
// dynamically
if (myfile) // open and in a good state
{
// while (! myfile.eof() ) // It'll not be eof when you've read the last line
// only when you try to read beynd the last line,
// so you'll add "line" one extra time at the end
// if you use that. Use this instead:
while(getline(myfile, line))
{
// myArray[index++] << line; // you have 0 elements in the array and
// can't add to it in any way
myArray.push_back(line);
}
}
else cout << "Unable to open file";
for(size_t idx=0; idx < myArray.size(); ++idx) {
std::cout << myArray[idx] << "\n";
}
average = averageCalc(myArray[], line); // error here
return 0;
}
double averageCalc(string nums[], int count)
{
int a, total, elements, averaged1, averaged2;
// string averaged2;
for(a = 0; a < count; a++)
{
total+=a;
elements++;
}
averaged1 = total / elements;
return averaged2;
}

There's a few problems here. Firstly, your function averageCalc expects a parameter of type string[] which is an array of strings. When you call the function, you are trying to pass it a std::vector<string>, which is not an array of strings, it is a class. Presumably, you would want to change your function to take in a vector, like so:
double averageCalc( const std::vector<string> & nums ); // no need for size now
The other issue you have is in calling your function. When you call it, you pass myArray[] as a parameter, which is the error you compiler is giving you. This is not valid syntax, you simply want to pass in myArray.

I think that the error occurs becase firstly you create the array with std::vector<std::string> myArray; so the data is string type but when you want to calculate the average value the function expects a value int, double etc. in order to perform math. Either change the string to int or use a function to convert it:
int main()
{
string s = "12345";
// object from the class stringstream
stringstream geek(s);
// The object has the value 12345 and stream
// it to the integer x
int x = 0;
geek >> x;
// Now the variable x holds the value 12345
cout << "Value of x : " << x;
return 0;
}

Related

How to set up function parameters to get back a 2 dimensional vector filled with values read from a file?

I am struggling to write parameters for a function 'readFile' which parameters are - a file name and a 2D vector to which information is copied from the file. The program doesn't throw ANY errors, but it does return just an empty vector. If i copy the code from 'readFile' function to main() function, it does work, but I want to make a seperate function so I can fill vectors with information from different files. Also I will need to pass these arguments for different type of functions with similar structure where I read from a file and copy to a 2D vector, so I really have to figure this out.
'PrintVector' function works fine. Could someone help me?
#include <string>
#include <sstream>
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
void printVector(vector< vector <float> > v)
{
for (size_t i=0; i<v.size(); ++i)
{
for (size_t j=0; j<v[i].size(); ++j)
{
cout << v[i][j] << "\t";
}
cout << "\n";
}
}
void readFile(char* filename, vector< vector<float> > &rowvector)
{
ifstream myfile(filename, ios::in);
string line;
string field;
vector<float> v; // 1 row
float result; // converted string value is saved in 'result' as a float type
if(myfile.is_open()){
while ( getline(myfile,line) ) // get next line in file
{
v.clear();
stringstream ss(line);
while (getline(ss,field,',')) // comma seperates elements
{
istringstream convert(field);
if ( !(convert >> result) )
result = 0;
v.push_back(result); // add each field to the 1D array
}
rowvector.push_back(v); // add the 1D array to the 2D array
}
}
myfile.close();
}
int main()
{
vector< vector<float> > myvector; // new 2D vector
readFile("test.txt", myvector);
printVector(myvector);
return 0;
}
Any help is much appreciated!

inserting spaces function after char worked outside the code but inside return error in C++

I made a function inserting spaces after a specific char(s)
it works perfect for any long ,any char when separated.
like now
using namespace std;
insert_spaces_before_delims(string a)
{
vector<int> found;
int temp;
int i=0;
//string a="Ahmeed+Khaled+awwad=Ahmedd-AWWAd"; //string be a parameter
temp = a.find_first_of("+-="); // chars be parameters if need to change
found.push_back(temp);
a.insert(found[i]," ");
while(a.find_first_of("+-=",found[i]+2)!= string::npos)
{
temp = a.find_first_of("+-=",found[i]+2);
found.push_back(temp);
a.insert(found[i+1]," ");
i++;
}
}
int main(void)
{
string equation;
getline(cin,equation);
insert_spaces_before_delims(equation);
//the output is the string with spaces before every +,- and =
}
i debug the function when returns that error
"terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::replace: __pos (which is 4294967295) > this->size() (which is 0)"
by condition (==string::npos)
why it comes again in the code and stop the code from continue , just return the error and end the program.
struct variable_content
{
//string coefficient; // coefficient of x ( value before x)
int value; // value of X = coefficient but in another type
string order; // order (number ) of x (number after x)
};
spilit__each_string(string,char,variable_content,vector<string>,vector<variable_content>);
spliting_each_variable(char ,variable_content ,vector<string> ,vector<variable_content>);
insert_spaces_before_delims(string );
int main()
{
int number_equations;
string equation; //receive string
vector<string> equations; // vector for equations input from user
vector<string> variables; // initial empty vector of string for each var as strings at all
vector<variable_content> variable; //initial empty vector of struct for each var
char delim[] = " ";
char delim1[]="xX";
cin>>number_equations;
number_equations++;
variable_content temp;
for (int i=0; i<number_equations;i++)
{
getline(cin,equation); //worked
//***the problem function , if i commented it the code works fine****
insert_spaces_before_delims(equation); //return error and stop the code
equations.push_back(equation); //worked
//make a temp struct and put tok1 in coefficient of it
spilit__each_string(equation, delim,temp,variables,variable);//worked
spliting_each_variable(delim1,temp ,variables,variable); //worked
}
//printing vector of struct of every variable
for(int y=0; y<variable.size();y++)
{
cout<<variable[y].value<<"\t"<<variable[y].order<<endl;
}
}
that the important parts
and the link of the whole code on github.https://github.com/AhmedKAwwad/Split-String-into-vector/blob/master/main.cpp
https://ericlippert.com/2014/03/05/how-to-debug-small-programs/
this link make me debug my code and found that having cin>> and getline mixed in my code do the error , then i use getline and then convert the string to integer
thanks for comments

Creating 2D String Vector from text file

I'm having slight trouble creating a 2D Vector of String that's created by reading values from a text file. I initially thought I needed to use an array. however I've come to realise that a vector would be much more suited to what I'm trying to achieve.
Here's my code so far:
I've initialised the vector globally, but haven't given it the number of rows or columns because I want that to be determined when we read the file:
vector<vector<string>> data;
Test data in the file called "test" currently looks like this:
test1 test2 test3
blue1 blue2 blue3
frog1 frog2 frog3
I then have a function that opens the file and attempts to copy over the strings from text.txt to the vector.
void createVector()
{
ifstream myReadFile;
myReadFile.open("text.txt");
while (!myReadFile.eof()) {
for (int i = 0; i < 5; i++){
vector<string> tmpVec;
string tmpString;
for (int j = 0; j < 3; j++){
myReadFile >> tmpString;
tmpVec.push_back(tmpString);
}
data.push_back(tmpVec);
}
}
}
However, when I attempt to check the size of my vector in my main function, it returns the value '0'.
int main()
{
cout << data.size();
}
I think I just need a pair of fresh eyes to tell me where I'm going wrong. I feel like the issues lies within the createVector function, although I'm not 100% sure.
Thank you!
You should use std::getline to get the line of data first, then extract each string from the line and add to your vector. This avoids the while -- eof() issue that was pointed out in the comments.
Here is an example:
#include <string>
#include <iostream>
#include <vector>
#include <sstream>
typedef std::vector<std::string> StringArray;
std::vector<StringArray> data;
void createVector()
{
//...
std::string line, tempStr;
while (std::getline(myReadFile, line))
{
// add empty vector
data.push_back(StringArray());
// now parse the line
std::istringstream strm(line);
while (strm >> tempStr)
// add string to the last added vector
data.back().push_back(tempStr);
}
}
int main()
{
createVector();
std::cout << data.size();
}
Live Example

FIXED: Access Violation Reading Location (pointer to string array)

FIXED: http://pastebin.com/71QxqGk5
first post/question.
So this is C++ and I am trying to print an array of words.
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <cctype>
#include <ctime>
using namespace std;
//structs
struct Input
{
int size;
string* word;
bool is_palindrome[];
};
//prototypes
bool openInputFile(ifstream &ifs);
void File_to_Array(string* word, int &size);
void PrintArray(string* word, int size);
//main
int main()
{
Input myInput = { 0, nullptr, false };
File_to_Array(myInput.word, myInput.size);//copy arr and get size
cout << myInput.word; //this outputs 00000000
cout << *myInput.word; //this breaks and throws exception as commented below
//Exception thrown at 0x0098BB6B in Project1.exe: 0xC0000005: Access violation reading location 0x00000014.
PrintArray(myInput.word, myInput.size);//print array of strings
system("PAUSE");
return 0;
}
//functions
bool openInputFile(ifstream &ifs)
{
string filename;
cout << "Enter the input filename: " << endl;
getline(cin, filename);
ifs.open(filename.c_str());
return ifs.is_open();
}
void File_to_Array(string* word, int &size)//copies file to dyn arr and assigns size from first elem
{
ifstream myFile;
while (!openInputFile(myFile))
cout << "Could not open file" << endl;
string tempstr = "";
getline(myFile, tempstr);//first line is size of dyn arr
size = stoi(tempstr);//now we have max size of dyn arr of strings
word = new string [size];//now we have the array of strings, *word[index] = string1
int i;
for (i = 0; getline(myFile, word[i]) && i < size; ++i);//for each line
//copy line of string from file to string arr within "bool" test, second param of for loop //copying done
size = i;
myFile.close();//done with file, no need, close it
}
void PrintArray(string* word, int size)
{
//for (int i = 0; i < size; ++i)
//cout used to be here, but now its in main, for debugging
}
So I'm wondering if my problem is with passing a member of a struct, and if I should have instead passed the entire struct type "myInput" into the functions and use the -> operator to access the members of myInput.
below is an example of a text file
5
month
Runner
NEON
digit
ferret
nothing
the 5 would be the size of the dynamically allocated array, the rest are strings, as you can see there are 6 strings, so I have in the for loop a test for whether the file is still transferring strings to the array.
This part of the File_to_Array is causing the problem:
word = new string [size];
You think that you are setting the pointer of myInput object to point to the string array, but you're not. When you pass the pointer to the function here:
File_to_Array(myInput.word, myInput.size)
^^^^^^^^^^^^
you are really passing a copy of the pointer. So inside the File_to_Array, this copy is re-pointed to the newly-created string array, but the real pointer inside myInput is not changed. You should pass a reference to the pointer instead:
void File_to_Array(string*& word, int &size)
\___________/
^--reference to a pointer
I would also suggest you to use a vector[string] instead. Finally, your bool is_palindrome[]; member and it's initialization look very strange, but it's hard to comment further since they are never used in the code.

Reading number list from file to a dynamic array

I'm having trouble reading a number list from a .txt file to a dynamic array of type double. This first number in the list is the number of numbers to add to the array. After the first number, the numbers in the list all have decimals.
My header file:
#include <iostream>
#ifndef SORT
#define SORT
class Sort{
private:
double i;
double* darray; // da array
double j;
double size;
public:
Sort();
~Sort();
std::string getFileName(int, char**);
bool checkFileName(std::string);
void letsDoIt(std::string);
void getArray(std::string);
};
#endif
main.cpp:
#include <stdio.h>
#include <stdlib.h>
#include "main.h"
int main(int argc, char** argv)
{
Sort sort;
std::string cheese = sort.getFileName(argc, argv); //cheese is the file name
bool ean = sort.checkFileName(cheese); //pass in file name fo' da check
sort.letsDoIt(cheese); //starts the whole thing up
return 0;
}
impl.cpp:
#include <iostream>
#include <fstream>
#include <cstring>
#include <stdlib.h>
#include "main.h"
Sort::Sort(){
darray[0];
i = 0;
j = 0;
size = 0;
}
Sort::~Sort(){
std::cout << "Destroyed" << std::endl;
}
std::string Sort::getFileName(int argc, char* argv[]){
std::string fileIn = "";
for(int i = 1; i < argc;)//argc the number of arguements
{
fileIn += argv[i];//argv the array of arguements
if(++i != argc)
fileIn += " ";
}
return fileIn;
}
bool Sort::checkFileName(std::string userFile){
if(userFile.empty()){
std::cout<<"No user input"<<std::endl;
return false;
}
else{
std::ifstream tryread(userFile.c_str());
if (tryread.is_open()){
tryread.close();
return true;
}
else{
return false;
}
}
}
void Sort::letsDoIt(std::string file){
getArray(file);
}
void Sort::getArray(std::string file){
double n = 0;
int count = 0;
// create a file-reading object
std::ifstream fin;
fin.open(file.c_str()); // open a file
fin >> n; //first line of the file is the number of numbers to collect to the array
size = n;
std::cout << "size: " << size << std::endl;
darray = (double*)malloc(n * sizeof(double)); //allocate storage for the array
// read each line of the file
while (!fin.eof())
{
fin >> n;
if (count == 0){ //if count is 0, don't add to array
count++;
std::cout << "count++" << std::endl;
}
else {
darray[count - 1] = n; //array = line from file
count++;
}
std::cout << std::endl;
}
free((void*) darray);
}
I have to use malloc, but I think I may be using it incorrectly. I've read other posts but I am still having trouble understanding what is going on.
Thanks for the help!
Your use of malloc() is fine. Your reading is not doing what you want it to do.
Say I have the inputfile:
3
1.2
2.3
3.7
My array would be:
[0]: 2.3
[1]: 3.7
[2]: 0
This is because you are reading in the value 1.2 as if you were rereading the number of values.
When you have this line:
fin >> n; //first line of the file is the number of numbers to collect to the array
You are reading in the count, in this case 3, and advancing where in the file you will read from next. You are then attempting to reread that value but are getting the first entry instead.
I believe that replacing your while() {...} with the code below will do what you are looking for.
while (count != size && fin >> n)
{
darray[count++] = n; //array = line from file
std::cout << n << std::endl;
}
This should give you the correct values in the array:
[0]: 1.2
[1]: 2.3
[2]: 3.7
You appear to be writing the next exploitable program. You are mistakenly trusting the first line of the file to determine your buffer size, then reading an unlimited amount of data from the remainder of the file into a buffer that is not unlimited. This allows an evil input file to trash some other memory in your program, possibly allowing the creator of that file to take control of your computer. Oh noes!
Here's what you need to do to fix it:
Remember how much memory you allocated (you'll need it in step #2). Have a variable alleged_size or array_length that is separate from the one you use to read the rest of the data.
Don't allow count to run past the end of the array. Your loop should look more like this:
while ((count < alleged_size) && (cin >> n))
This both prevents array overrun and decides whether to process data based on whether it was parsed successfully, not whether you reached the end-of-file at some useless point in the past.
The less problematic bug is the one #bentank noticed, that you didn't realize that you kept your position in the file, which is after the first line, and shouldn't expect to hit that line within the loop.
In addition to this, you probably want to deallocate the memory in your destructor. Right now you throw the data away immediately after parsing it. Wouldn't other functions like to party on that data too?