-2

I'm writing a basic program that will read a list of integers from a text file and output to the screen the smallest integer and largest integer in the file. I made sure that the text file is in the same folder as the source code file, and the name of the file is the same as what I call it in the code. The program cannot open the file, no matter what. How can I fix this?

This is my program:

 #include <iostream>
 #include <fstream>
 #include <cstdlib>
 using namespace std;

int main()
{
    ifstream inStream;

    inStream.open("infile.txt");
    if (inStream.fail())
    {
        cout<<"Input file opening failed.\n";
        system("pause");
        exit(1);
    }

    int arr[100], i = 0;

    while(!inStream.eof())
    {
        inStream>>arr[i++];
    }

    int min = arr[0];

    for (int index = 1; index <= i; index++)
    {
        if (arr[index] < min)
        {
            min = arr[index];
        }
    }

    int max = arr[0];

    for (int index = 1; index <= i; index++)
    {
        if (arr[index] > max)
        {
            max = arr[index];
        }
    }

    cout<<"The smallest number is "<<min<<endl;
    cout<<"The largest number is "<<max<<endl;

    inStream.close();

    system("pause");
    return 0;
}
Jashaszun
  • 9,207
  • 3
  • 29
  • 57
Johnny Sack
  • 69
  • 2
  • 12
  • 1
    Note that your program also suffers from other serious problems: a cycle with `!eof` pre-condition. It will typically lead to your program "reading" more values than actually exist in the file (by one). Don't use `!eof` as a pre-condition. On top of that your cycles iterate till `index <= i` (instead of `index < i`), which will also attempt to access non-existent data in the array. – AnT stands with Russia Jul 27 '15 at 20:48
  • Rather than using an array, you should keep two variables: smallest and largest. If the integer read is smaller, it becomes the smallest; if the integer is greater than largest, it becomes the largest. No need to store all the values. – Thomas Matthews Jul 27 '15 at 21:43
  • @ThomasMatthews I don't understand how it could be done without storing all the numbers from the file in an array in order to work with them and output results. Can you explain more? – Johnny Sack Jul 27 '15 at 21:51
  • Set `smallest` to `MAX_INT`. Set `largest` to `MIN_INT`. Loop: read value from file. `if (value < smallest) smallest = value; if (value > largest) largest = value;`. End loop. The `MAX_INT` and `MIN_INT` are defined in `limits.h` and may be named `INT_MAX` and `INT_MIN`. – Thomas Matthews Jul 27 '15 at 22:33
  • @ThomasMatthews What is limits.h? I think that might be beyond the scope of what I'm learning in class or anything in my textbook. Is there a more simple way to set the max and min value? – Johnny Sack Jul 28 '15 at 05:03
  • @AnT For the index < i part, if I have 5 numbers, i in this code will be 4, not 5, so unless the cycle goes up to 4 which is equal to i, it won't reach the end of the numbers. This was my understanding for why I put index <= i. But you are actually right. My code didn't work but your changes made it work. Why is this? Why doesn't it have to cycle all the way up to 4 which is the final index in the array? – Johnny Sack Jul 28 '15 at 05:08
  • @Johnny Sack: "if I have 5 numbers, i in this code will be 4, not 5," - I don't know what made you think so. Your code, as written, is obviously intended to have `5` in `i` if you read `5` numbers. But because of the `!eof` problem you are actually likely to have `6` in `i` even though you read only `5` numbers, which makes it even worse. – AnT stands with Russia Jul 28 '15 at 05:24
  • @AnT I'll address the eof thing but I first want to make sure I understand the loop. I am initializing i at 0. Then the first number from the input file is stored into arr[0]. The second number to arr[1] and so on. This means if I have 5 numbers, the i will only increment up to 4. So i should go from 0 to 4. This how I understand it. Can you explain where I'm wrong? – Johnny Sack Jul 28 '15 at 05:29
  • @Johnny Sack" No. Every time you store something into the array, you immediately increment `i` after that. Which means that after you read `arr[0]` `i` becomes `1`. After you read `arr[1]`, `i` becomes `2`. After you read `arr[2]`, `i` becomes `3`. `i` is always greater (by `1`) than the last read element of the array. So, after you read the fifth number into `arr[4]`, `i` will become `5`. In other words, `i` is the exact number of elements you read. If you read `5`, `i` is `5`. – AnT stands with Russia Jul 28 '15 at 05:31
  • @AnT Oh I finally get it now! Thanks! – Johnny Sack Jul 28 '15 at 05:34
  • But because of the `!eof` issue, you might end up doing an extra "fictive" read of a non-existent element from the file. `i` will become `6`, with `arr[5]` containing garbage. (See http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – AnT stands with Russia Jul 28 '15 at 05:35

1 Answers1

1

If you tried to open "C:\SomeDirectory\infile.txt" that would be an Absolute Path. This is opposed to "infile.txt" which is called a relative path. That begs the question, "where is it relative to?". It is relative to the "Current Working Directory" or CWD. Generally the CWD is set to where the executable is, but it doesn't have to be! In fact, if you drag and drop a file onto your executable, the CWD will be the location of where you dragged your file from. Or if you run from Visual Studio and launch the code from inside the IDE (by hitting the button or using F5) the CWD will not be where the executable is.

The short answer is you generally want to use absolute paths. There are definitely cases where relative paths make sense, but you really have to understand how your program is being used and where the CWD is in order for that to be useful. For your case, I would just stick to an absolute path.

RyanP
  • 1,898
  • 15
  • 20
  • 1
    "The short answer is you generally want to use absolute paths." - not good advice! When you work in a team on a project with external dependencies, you don't necessarily know where exactly they will be on all other team members' machines. It may be easier to determine where that resource will be relative to the Current Working Directory than using an absolute path. Alternatively, you can use Environmental Path Variables (ideally ones which already come with Windows) to locate the resource. – Matt Arnold Jul 27 '20 at 09:49