operator>> sets the stream's eofbit flag if it tries to read past EOF.  You can use that condition to break your loops.  But you have to actually perform a read operation BEFORE you can evaluate eof().  See Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong? for more details on that.
Since you are dealing with line-based text, you can use std::getline() to read each line first, and then you can use std::istringstream to parse each line, eg:
int main()
{
    vector<int> vec;
    ifstream file ("file.txt");
    string line;
    while (getline(file, line)) {
        istringstream iss(line);
        int amount, nums;
        iss >> amount;
        cout << amount << endl;
        for (int i = 0; (i < amount) && (iss >> nums); ++i){
            vec.push_back(nums);
        }
        printArray(vec);
        bubbleSort(vec);
        vec.clear();
    }
    return 0;
}
Alternatively, you can simply take advantage of the fact that operator>> skips whitespace, including line breaks, eg:
int main()
{
    vector<int> vec;
    int amount, nums;
    ifstream file ("file.txt");
    while (file >> amount) {
        cout << amount << endl;
        for (int i = 0; (i < amount) && (file >> nums); ++i){
            vec.push_back(nums);
        }
        printArray(vec);
        bubbleSort(vec);
        vec.clear();
    }
    return 0;
}
Although, this approach would be a little less resilient to errors in the input data, compared to the std:getline() approach.  If the actual amount of numbers in a given line does not match the specified amount at the beginning of the line, this approach will get its reading of the file out of sync.  Worse, if a given line contains any non-integer values, this approach will fail to read any subsequent data at all.
In the std:getline() approach, if a given line is malformed, the code will simply move on to the next line and continue on like nothing bad happened.