Ok, so I've recently been learning to code in c++, but I'm getting a little confused on how you read files to functions.

For instance, say that I have one file with a list of other files in it. The information within the second set of files (each file) contains an integer, a character and a double.

The idea is to open the first file, loop through and open each file inside, reading each piece of information. I'm trying to learn about passing files to functions by value, so my thought was to make a prototype:

istream& getInfo(istream &, double &, char &, int &);

I understand that passing by value allows for a change to the original value in memory (not a copy), but I don't understand how I would go about reading and altering the information if I wanted to. Any help would be greatly appreciated! :) I'm looking for an explanation, and maybe an example in code. I'll be here to answer any questions as well.

I understand how to open/close files. What I'm trying to understand is how I would read information (containing multiple data types) from a file by passing it to a function.

Specifically a function that has a prototype of:

istream& readFile(&istream, &double, &char, &int);

I hope that makes sense. That's about all the example I can give. :/

How would you read input from standard input?

int num;
// grab an integer from standard input
cin >> num;

How would you write to data to standard output?

int age = 32;
cout << "You are " << age << " years old";

You can do the same things with files. Create an object that represents a file, and you can use the object like 'cin' and 'cout' to extract and insert data with << and >> operators.

Let's do the same thing above with file objects instead.

#include <fstream>
#include <iostream>

using namespace std;

int main()
{
    int num;
    float fnum;

    // our file objects for input/output
    ifstream input_file;
    ofstream output_file;

    // let's open a file for input
    input_file.open("filename_here", ios_base::in);

    // now we can use input_file exactly like we do with cin, to extract data

    // let's grab an integer from the file
    input_file >> num;
    // how about a float?
    input_file >> float;

    ifstream.close();

    // time to output what we have to a file
    output_file.open("another_filename_here", ios_base::out);

    // we treat output_file as if it was cout by inserting data into the stream
    output_file << "The integer stored in the file was " << num << endl;
    output_file << "The float is " << fnum;

    output_file.close();

    return 0;
}

Remember, cin represents the standard input "stream". A file object like input_file is a file input "stream". Because they are both streams (merely a sequence of data), they share a lot of functionality. So if you can extract from the standard input stream, you can do the same with a file input stream.

You mean something like this? Of course it will all depend on how the file was written -- what are its exact contents.

istream& readFile(istream& in, double& dbVal, char& charVal, int& intVal)
{
   in >> dbVal >> charVal >> intVal;
   return in;
}

int main()
{
    double dbVal;
    int intVal;
    char charVal;
    ifstream in("file.txt");
    readFile(in, dbVal, charVal, intVal);
}

Edited 4 Years Ago by Ancient Dragon

Yes! Thank you dx9 programmer for the help, but I was more leaning towards Ancient Dragon's answer. :) After a few hours of tinkering with my code I figured it out somewhat. I'll make sure to post my code if I run into any rough spots. Thanks again to both of you! :)

i'm going to try to revive this thread instead of creating a new one. I'm having a weird error in my program and I can't figure it out. Instead of an error message, the .exe just crashes instead. I'll post my code, if somebody could reply that'd be great. It's due at midnight and this is the only bug i've encountered. I took out my code to simplify, i think it's more of a syntax error.

/******************************************************************************
istream& getInfo:
   Description: reads in input stream,double,char, and int by value
                (will read info from file)
   Input:
        istream &: the chosen iostream/fstream
        double &: the temperature value
        char &: the unit of temp. (F):farenheit OR (C): Celcius
        int &: an unimportant number

   Output:  Will call converting function to change the temp to the correct (f)
            value for each file and will also return iostream/fstream
*******************************************************************************/
istream &getInfo(istream &inFile, double &temp, char &unit, int &unnecessary)
{

    while(inFile >> temp >> unit >> unnecessary)
    {
        temp = convertTemp(temp,unit);
        cout << "in the function" << endl;
        return inFile;
    }


}



/******************************************************************************
convertTemp:
   Description: Coverts Celcius to Farenheit
   Input:
        char : the unit of temp. (F):farenheit OR (C): Celcius
        double: the designated temperature in either (F) or (C)

   Output: Will return the unedited (F) or the converted (C)
*******************************************************************************/
double convertTemp(double weatherTemp, char unitTemp)
{
    double convertedWeatherTemp;

    if(unitTemp == 'C'|| unitTemp == 'c') // if the char value is equal to 'C' or 'c'
    {
        convertedWeatherTemp = (((9.0/5.0)*(weatherTemp))+32);
    }
    else if(unitTemp == 'F' || unitTemp == 'f') // if the char value is equal to 'F' or 'f'
    {
        convertedWeatherTemp = weatherTemp;
    }
    else
    {
        cerr << "Char other than c or f";
    }

    return convertedWeatherTemp;
}

//
main function
//

#include "TempFunctions.h"

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    char unit;

    double temp = 0.0, layerOneTemp = 0.0, layerTwoTemp = 0.0, min, max,
           prevMin = 100000.0, prevMax = -100000.0,
           totalAverage = 0.0,localAverage = 0.0;

    int unnecessary, layerTwoCount = 0, layerOneCount = 0;

    string filename;

    ifstream readLayerOne,readLayerTwo;

    //get the name of the first file (containing city names)
    cout << "Please Enter FileName : ";
    cin >> filename;

    readLayerOne.open(filename.c_str());
    //test to see if the file opened
    if(!readLayerOne)
    {
        cerr << "Error Layer One Failed: File Not Found\n";
        return -1;
    }

    else
    {
        while(getline(readLayerOne,filename))
        {
            cout << "Now Attempting to Open a File: " << filename << endl;
            readLayerTwo.open(filename.c_str());
            //test to see if the filestream opened
            if(!readLayerTwo)
            {
                cerr << "Error LayerTwo Failed: "<< filename << " Not Found\n";
                return -2;
            }
            else
            {
                while(getInfo(readLayerTwo,temp,unit,unnecessary))
                {
                    cout << "outside of function" << endl;
                    cout << temp << endl;
                }

            }
        }
    }
    return 0;
}

I've also have a seperate header file containing prototypes, however i didn't include it here

EDIT: 1>c:\users\owner\developmenttools\code\vstudios projects\gradedassignment2\gradedassignment2\tempfunctions.cpp(39): warning C4715: 'getInfo' : not all control paths return a value (i'm getting this warning message)

Edited 4 Years Ago by Hopp3r: extra info

Your GetInfo doesn't return a value everywhere. Actually, it only returns a value within that while loop. Lets assume that the while loop "never" executes and it skips over it.. What happens then? What did you return?

Also perhaps it crashes because you never closed any of the streams you opened? OR because you return -2? Just a wild guess.. Either way, this is how I'd do it:

#include <iostream>
#include <windows.h>
#include <fstream>
#include <sstream>

template<typename T>
std::string ToString(T Type)
{
    std::stringstream SS;
    SS<<Type;
    return SS.str();
}

std::string ConvertTemperature(double Temperature, char Unit)
{
    std::string Degrees = " " + ToString((char)248);
    if (Unit == 'C' || Unit == 'c')
        return ToString(Temperature) + Degrees + "C = " + ToString(((9.0/5.0) * (Temperature)) + 32) + Degrees + "F";

    if (Unit == 'F' || Unit == 'f')
        return ToString(Temperature) + Degrees + "F = " + ToString((Temperature - 32) * (5.0/9.0)) + Degrees + "C";

    return "Unknown unit. Cannot Convert To Fahrenheit or Celsius.";
}

void GetStream(std::istream &Stream)
{
    int Result = 0;
    char Unit = '\0';
    double Temperature = 0.0;

    while(Stream >> Temperature >> Unit >> Result)
    {
        //std::cout<<Temperature<<std::endl;
        //std::cout<<Unit<<std::endl;
        //std::cout<<Result<<std::endl;
        std::cout<<ConvertTemperature(Temperature, Unit)<<std::endl;
        std::cout<<std::endl;
    }
}

void ReadStream(std::istream &Stream)
{
    std::string Line;
    while(getline(Stream, Line))
    {
        std::ifstream FileLayer;
        FileLayer.open(Line.c_str());
        if (FileLayer.is_open())
            GetStream(FileLayer);
        FileLayer.close();
    }
}

int main()
{
    std::ifstream F;
    F.open("C:/Users/Master/Desktop/LayerOne.txt");
    ReadStream(F);
    F.close();
}

LayerOne.txt looks like:

C:/Users/Master/Desktop/LayerTwo.txt
C:/Users/Master/Desktop/LayerThree.txt

LayerTwo.txt looks like:

10.5
F
45

LayerThree.txt looks like:

36.7
C
32

Results looks like:

10.5 °F = -11.9444 °C

36.7 °C = 98.06 °F


Process returned 0 (0x0)   execution time : 0.079 s
Press any key to continue.

Edited 4 Years Ago by triumphost

This question has already been answered. Start a new discussion instead.