0

I am quite new to C++. I need to make a small application which reads the content of a txt file and then displays the content in the console. I have three points forming a triangle that I will plot later on. I want to do all this operation in a function called read2dFile, so my main is actually empty (except for the call of the function). When I tried this code in a main in another project, everything was working fine. It seems like my function is not properly declared. Here is my code :

**Test.cpp** (FOR THE MAIN)

// Test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "read2dFile.h"

int main()
{
    read2dFile();
    return 0;
}

read2dfile.h (FOR THE FUNCTION HEADER)

#ifndef READ2DFILE_H_
#define READ2DFILE_H_

#include <iostream>
#include <iomanip>
#include <array>
#include <fstream>
#include <sstream>
#include <string>
#include <stdio.h>

using namespace std;

void read2dFile();

#endif

read2dFile.cpp (FOR THE FUNCTION CODE)

#include "read2dFile.h"

int row = 0;
int col = 0;

void read2dFile() {

    string line;
    int x;
    int array[100][100] = { { 0 } };
    string filename;

    ifstream fileIN;

    // Intro
    cout
        << "This program reads the number of rows and columns in your data 
    file."
        << endl;
    cout << "It inputs the data file into an array as well." << endl;
    cout << "\nPlease enter the data file below and press enter." << endl;
    cin >> filename;

    fileIN.open(filename);

    // Error check
    if (fileIN.fail()) {
        cerr << "* File you are trying to access cannot be found or opened *";
        exit(1);
    }

    // Reading the data file
    cout << "\n" << endl;
    while (fileIN.good()) {
        while (getline(fileIN, line)) {
            istringstream stream(line);
            col = 0;
            while (stream >> x) {
                array[row][col] = x;
                col++;
            }
            row++;
        }
    }

    // Display the data
    cout << "# of rows ---> " << row << endl;
    cout << "# of columns ---> " << col << endl;
    cout << " " << endl;
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++) {
            cout << left << setw(6) << array[i][j] << " ";
        }
        cout << endl;
    }

}
user4581301
  • 33,082
  • 7
  • 33
  • 54
  • 4
    No using directives at file scope in headers! – Davis Herring Jan 26 '18 at 02:55
  • 4
    And when you try it in this project, what's not working fine? You seem to have forgotten to describe the problem and actually ask a question. – Igor Tandetnik Jan 26 '18 at 02:57
  • 1
    Did you want everyone to guess what is going wrong, given that you don't want to tell us? – Jonathan Wood Jan 26 '18 at 02:57
  • 2
    _I am quite new to C++_ Yes but what's your question? I recommend you hit some of the [suggested reading material](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) to get started. Try not to put unnecessary includes into your program (especially in header files) and use [forward declarations](http://www.learncpp.com/cpp-tutorial/17-forward-declarations/) where possible. – Justin Randall Jan 26 '18 at 04:09

1 Answers1

0

I have some recommendations (your code compiles fine for me).

  1. Not specific to your question, but you should learn about class and object oriented programming to make life in C++ easier.
  2. These are the only include files that your read2dFile() function needs. Put them into read2dFile.cpp! The reason is because you don't want headers included in other headers unless it's absolutely necessary.

These directives will go at the top of read2dFile.cpp

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
  1. using namespace std; opens the floodgates and can cause namespace collisions. Try to avoid doing this. If you do insist on doing it anyway, do it in the .cpp source files (not in your .h header files). Instead, you can declare usage of specific parts of the standard namespace (only the ones you need).

These using directives can go in place of your using namespace std; and you will again put them into the read2dFile.cpp source file.

using std::string;
using std::ifstream;
using std::cout;
using std::endl;
using std::cin;
using std::cerr;
using std::istringstream;
using std::left;
using std::setw;
  1. Your read2dFile.h has now been reduced to just your function declaration.

The file now looks like this.

#ifndef READ2DFILE_H_
#define READ2DFILE_H_

void read2dFile();

#endif

Your main() can stay as it is, and if it's still not working for you, try removing the precompiled header directive #include "stdafx.h" from your Test.cpp source file. It's not needed here and sometimes can cause compiler errors in certain cases.

Justin Randall
  • 2,243
  • 2
  • 16
  • 23
  • 1
    haha :) 2 agree 3 agree 4 agree 1 :) do not agree :) I think he is coming from pure C or he is reading some book that starts with procedural staff first. –  Jan 26 '18 at 04:56
  • Code still does not build. I use VS 2017 Community. Message error is 1>------ Build started: Project: Test, Configuration: Debug Win32 ------ 1>Test.obj : error LNK2019: unresolved external symbol "void __cdecl read2dFile(void)" (?read2dFile@@YAXXZ) referenced in function _main 1>C:\Users\milan196\Desktop\Test\Test\Debug\Test.exe : fatal error LNK1120: 1 unresolved externals 1>Done building project "Test.vcxproj" -- FAILED. Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped – Michael Landry Jan 26 '18 at 20:09
  • I made all your suggested changes before building but it still does not work. When I test the algorithm in a main, everything works fine. – Michael Landry Jan 26 '18 at 20:13
  • Sorry I thought this was obvious but I should have been explicit. You do have to `#include "read2dFile.h"` both in your **Test.cpp** and **read2dFile.cpp**. If it still doesn't work, then something in your project configuration is wrong so start over from scratch with a clean project workspace. – Justin Randall Jan 26 '18 at 21:33
  • That error message is saying that the linker cannot find the .obj file containing read2dFile() so first thing to make sure of is that your read2dFile.cpp is in your project build and being compiled. If not, then that's your problem . If it is, then you need to find out why the linker doesn't see it. – Justin Randall Jan 26 '18 at 21:46
  • 1
    I started a new empty project and now everything works fine except I can't leave the console open at the end of the execution. However, I can live with that for now. Thank you for your time! The problem is solved. – Michael Landry Jan 27 '18 at 16:56
  • @MichaelLandry Glad to hear it! If you would like the console to remain open at the end of execution, then just do something like this right before main returns. `cin.get()`. This will wait for the user to press return/enter before the console closes. – Justin Randall Jan 27 '18 at 19:04