Calling void functions in main

Hi,
I'm relatively new to programming and I'm trying to create a program where I make a function in a .cpp file and then call it in main. For this assignment, I need to use strings which I'm not good with either and I keep getting errors when I try to call my function.
Any help would be appreciated

[code]
This is the .cpp file
#include <iostream>
#include <string>
#include <fstream>
#include "functions.h"
using namespace std;
void readResp(ifstream &infile, string resp[], string cat[], int &size) {
string noUse;
string temp;
infile.open("myassign.txt");
if (infile) {
while (infile >> temp) {
size = 0;
categories[size] = temp;
size++;
infile >> noUse;
}
}
cout << categories[size];
}

This is the main.cpp file:
#include <iostream>
#include <fstream>
#include <string>
#include "functions.h"
using namespace std;
int main() {
char input;
ifstream infile;
int size = 0;
string resp[size];
string cat[size];
cout << "Please chooose an option from A through F;" << endl;
while (cin >> input) {
switch(input) {
case 'a':
case 'A':

readResp(&infile, resp[&size], cat[&size], &size);
break;
case 'b':
case 'B':

break;
case 'c':
case 'C':

break;
case 'd':
case 'D':

break;
case 'e':
case 'E':

break;
case 'f':
case 'F':
//exit
break;
}
}
return 0;
}


Please note that I'm not done with my program yet, I'm just starting. And the error I'm getting in this particular code is:

C:\Users\hp\CLionProjects\untitled\main.cpp:28:55: error: invalid types 'std::__cxx11::string [size] {aka std::__cxx11::basic_string<char> [size]}[int*]' for array subscript
readResponses(&infile, responses[&size], categories[size], &size)



Thanks.
Can you post functions.h please?

I think you left off the closing code tag, as your code isn't formatted and it's showing the leading tag.

I'd expect it to look something like:
1
2
3
4
5
6
#pragma once

#include <string>
#include <fstream>

void readResp(std::ifstream &infile, std::string resp[], std::string cat[], int &size);
Last edited on
Yes, this is my functions.h:

#ifndef UNTITLED_FUNCTIONS_H
#define UNTITLED_FUNCTIONS_H
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
void readResp(ifstream &infile, string resp[], string cat[], int &size);

#endif //UNTITLED_FUNCTIONS_H
You're called the parameter cat in the argument list, but refer to it as categories within the function.

Also, in main(), you call:
 
readResp(&infile, resp[&size], cat[&size], &size);

but it should be:
 
readResp(&infile, resp, cat, size);
Last edited on
Hello az1234,

Because you had a problem with using the code tags this may help:
http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

I found the second link to be the most help.

First problem in "main" is at the top.

This solved the problem:
1
2
3
4
5
6
7
8
9
#include <iostream>
#include <fstream>
#include <string>

using namespace std;  // <--- Best not to use.

#include "functions.h"

int main()

Removing line 5 would solve a lot of problems. More so in the future.

Next is: string resp[MAXSIZE];. You are defining an array of strings. What is in the[]s, "MAXSIZE", needs to be a constant value. Either something like 10 or a variable defined as a constant as constexpr int MAXSIZE{ 10 };. The capital letters are generally used for a constant variable and it helps to remind you that it is defined as a constant. The same applies to the other string array. For this type of use "MAXSIZE" is most often seen and used.

In case "A" when you call the function just the variable names are needed. Not all the extra that you originally have.

This is what I ended up with in "main" to get the program to compile:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <fstream>
#include <string>

using namespace std;  // <--- Best not to use.

#include "functions.h"

int main()
{
	constexpr int MAXSIZE{ 10 };  // <--- Changed.

	char input;
	ifstream infile;
	string resp[MAXSIZE];  // <--- Changed.
	string cat[MAXSIZE];  // <--- Changed.

	cout << "Please chooose an option from A through F;" << endl;

	while (cin >> input)
	{
		switch (input)
		{
		case 'a':
		case 'A':
			readResp(infile, resp, cat, MAXSIZE);  // <--- Changed.
			break;


In "Functions.h" Which looks like this:
1
2
3
4
5
6
7
8
9
10
#ifndef UNTITLED_FUNCTIONS_H
#define UNTITLED_FUNCTIONS_H
//#include <iostream> // <--- These header files should not be here.
//#include <string>
//#include <fstream>
//using namespace std;  // <--- Never use here.

void readResp(ifstream &infile, string resp[], string categories[], int size);  // <--- Changed.

#endif //UNTITLED_FUNCTIONS_H 

The comments say what is needed. All I changes here is the name of the string variable.

As far as using namespace std; you should read this: http://www.lonecpluspluscoder.com/2012/09/22/i-dont-want-to-see-another-using-namespace-xxx-in-a-header-file-ever-again/

In the "functions.cpp" file the beginning was changed to match what is in the "main" file. The only change I made was to the string variable name. I made it match what is inside the function.

I have not tested it yet, but the line size = 0; I believe should be outside the while loop. Inside the loop on each iteration you will be setting "size" to zero and overwriting the same element of the array.

Some suggestions:

You define a file stream in "main" and pass it to your function. This works, but it would be better to define the file stream in the function and not have to pass it.

Your program uses an input file. It would help if you post this file so everyone can see what you are using and everyone will be using the same information. You may also get a suggestion of a better way to read this file.

Hope that helps,

Andy
I disagree with Andy about the header:
Functions.h
1
2
3
4
5
6
7
8
9
10
#ifndef UNTITLED_FUNCTIONS_H
#define UNTITLED_FUNCTIONS_H
#include <string>
#include <iosfwd> // forward declares std::istream

void readResp( std::istream& infile,
               std::string* resp, std::string* categories,
               size_t size );

#endif //UNTITLED_FUNCTIONS_H 

First and foremost, Andy says that a header should not include any other headers. That means that anyone willing to use that header must know what other headers to include before that header, or face compile errors.

Guess what? We can include <string> without first including quite many other Standard Library headers. Does that mean that the Standard Library headers have special exception from "Andy's Rule"?

No, it is perfectly ok and expected that a header includes necessary bits. What is necessary in this header? The std::istream and std::string do need at least a forward declaration.

The <iosfwd> provides forward declarations for most iostream types. That is sufficient.
There is no similar forward declaration header for std::string and thus the actual <string> is necessary.

Why did I write std::istream and std::string? Why the std::-prefix? I'm explicitly referring to the istream and string that are in the std-namespace. I don't rely on any using ...
Explicit is unambiguous.

Did I make a typo by writing istream and not ifstream? No. I assume that the function does not actually use any file-specific features of the stream. If the function requires ifstream, then it can be used only with ifstreams, but if it can take istream, then you can call it with any istream, including ifstream. That is more generic and reusable.

string* foo vs string foo[]. For the compiler these are identical. In the function the foo is a pointer. You might want to keep the [], for you want to hint to the user that you expect a pointer to array.

int size vs size_t size. The size_t is an unsigned integer type. I presume that the size knows the size of array(s). Can you have an array with -7 elements? No. The use of unsigned type hints that negative values are not logical.
@ keskiverto,

First and foremost, Andy says that a header should not include any other headers.

Understand that I did not come up with that. It came from others that have been around longer than I have who said that. I will concede that I may not have explained my self in the best way, but do remember that I am working with what others have said.

These days I have the feeling that something that was said a year ago has changed and no longer applies.

Andy
Thank you so much for your help, all the stuff you guys said makes sense and my program is finally running. For the namespace std, I've heard that you shouldn't use it but my instructor wants us too. The issue I'm facing now is that the function still isn't actually being processed in my main.cpp. When I enter in letter 'a' after it says to choose an option, nothing happens. I need the information that is in the string array to be outputted
That is probably due to:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void readResp( ifstream& infile, string resp[], string cat[], int &size )
{
  string noUse;
  string temp;
  infile.open("myassign.txt");
  if (infile) {
    while (infile >> temp) {
      size = 0; // size==0, every time
      cat[size] = temp; // overwrite cat[0], every time
      size++;
      infile >> noUse;
    }
  }
  cout << cat[size]; // show cat[1]
}
so I had to change my code a bit because I found out that string cat[] should only read in the even lines while string resp[] should only read in the odd lines.
This is what I have:

void readResponses(ifstream &infile, string resp[], string cat[], int size) {
string noUse;
string temp;
infile.open("myassign.txt");
if (infile) {
int i;
while (infile >> i) {
size == 0;
int const maxsize = 25;
for (i = 0; i < maxsize; i++) {
if (i % 2 == 0) {
cat[i] = i;
} else {
resp[i] = i;
}

cout << cat[i];
}
}
}
Topic archived. No new replies allowed.