0

I am trying to input the rooms, sort them by price and create a text file afterward but there is always an error which I suspect has to do with the sizeof function

In some compilers, it will compile but it'll have the warning message:

warning: ‘sizeof’ on array function parameter ‘rooms’ will return size of ‘roomType*’ [-Wsizeof-array-argument]

Dev C++ wouldn't compile at all

#include <iostream>
#include <fstream>
#include <algorithm>
#include <iomanip>
using namespace std;

const int roomamt = 4;

struct package
{
    int numRoom;
    int numNight;
};

struct roomType
{
    string type;
    string breakfast;
    int price;
    package packageType;
};

bool comparePrice(roomType p1, roomType p2) 
{ 
    return (p1.price < p2.price); 
}

void input(roomType rooms[roomamt]);
void sort(roomType rooms[roomamt]);

int main()
{
    roomType rooms[roomamt];
    
    input(rooms);
    
    sort(rooms);

}

void input(roomType rooms[roomamt]){
    
    for(int i = 0; i < roomamt; i++){
        cout << "Enter type of room: ";
        cin >> rooms[i].type;
        cout << "Specify if breakfast included: ";
        cin >> rooms[i].breakfast;
        cout << "Enter price of room/night: ";
        cin >> rooms[i].price;
        cout << "Enter num of room: ";
        cin >> rooms[i].packageType.numRoom;
        cout << "Enter num of nights: ";
        cin >> rooms[i].packageType.numNight;
    }
}

void sort(roomType rooms[roomamt]){
    
    int n = sizeof(rooms)/sizeof(rooms[0]); 
    
    sort(rooms, rooms+n, comparePrice); 
    
}

void createFile(roomType rooms[roomamt]){
    
    ofstream priceList("priceList.txt");
    
    priceList << setw(20) << "Room Type" << setw(20) << "Breakfast" << setw(20) << "Price/night" << setw(20) << "Room" << setw(20) << "Nights" << endl;
    priceList << setw(20) << "---------" << setw(20) << "----" << setw(20) << "-----" << setw(20) << "----" << setw(20) << "----" << endl;
    
    for(int i = 0; i < roomamt; i++){
        priceList << setw(20) << rooms[i].type << setw(20) << rooms[i].breakfast << setw(20) << rooms[i].price << setw(20) << setw(20) << rooms[i].packageType.numRoom << setw(20) << rooms[i].packageType.numNight << endl;
    }
}
Mohammed A
  • 1
  • 1
  • 1
  • Does this answer your question? [How do I determine the size of my array in C?](https://stackoverflow.com/questions/37538/how-do-i-determine-the-size-of-my-array-in-c) – Adrian Mole Aug 01 '20 at 12:28
  • Why do calculate the number of elements with `int n = sizeof(rooms)/sizeof(rooms[0]);` if you have the size `roomamt`? `roomType rooms[roomamt]` in the signature of `sort` decays to a pointer declaration. `sizeof(rooms)` returns the size of a pointer, not a the array. – Thomas Sablik Aug 01 '20 at 12:28

3 Answers3

3

You have the common newbie confusion around pointers and arrays. Take this code for instance

void sort(roomType rooms[roomamt]) {
    int n = sizeof(rooms)/sizeof(rooms[0]); 
    sort(rooms, rooms+n, comparePrice);
}

In this code rooms is a pointer. It might look like an array but it isn't. It's impossible to make an array a function parameter in C++. So the compiler changes roomType rooms[roomamt] to roomType* rooms. Because of this sizeof(rooms) is the size of the pointer, not of the array, and so your calculation for the array size is incorrect.

But in your case the fix is easy, just use roomant

void sort(roomType* rooms) {
    sort(rooms, rooms + roomamt, comparePrice);
}

Note here I've changed the code to show rooms as the pointer it really is.

However even without this fix I'm not seeing why your code would crash (or fail to compile).

john
  • 85,011
  • 4
  • 57
  • 81
2

You could use C++ arrays instead of C arrays. C++ arrays can be passed by value and by reference to functions. They can be returned from functions and can be simply copied. They contain their size. All these advantages come with 0 overhead.

#include <array>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iomanip>
using namespace std;

constexpr int roomamt = 4;

struct package
{
    int numRoom;
    int numNight;
};

struct roomType
{
    string type;
    string breakfast;
    int price;
    package packageType;
};

bool comparePrice(roomType p1, roomType p2) 
{ 
    return (p1.price < p2.price); 
}

void input(array<roomType, roomamt> &rooms);
void sort(array<roomType, roomamt> &rooms);

int main()
{
    array<roomType, roomamt> rooms;
    
    input(rooms);
    
    sort(rooms);

}

void input(array<roomType, roomamt> &rooms){
    
    for(int i = 0; i < rooms.size(); i++){
        cout << "Enter type of room: ";
        cin >> rooms[i].type;
        cout << "Specify if breakfast included: ";
        cin >> rooms[i].breakfast;
        cout << "Enter price of room/night: ";
        cin >> rooms[i].price;
        cout << "Enter num of room: ";
        cin >> rooms[i].packageType.numRoom;
        cout << "Enter num of nights: ";
        cin >> rooms[i].packageType.numNight;
    }
}

void sort(array<roomType, roomamt> &rooms){    
    sort(rooms.begin(), rooms.end(), comparePrice); 
    
}

void createFile(array<roomType, roomamt> &rooms){
    
    ofstream priceList("priceList.txt");
    
    priceList << setw(20) << "Room Type" << setw(20) << "Breakfast" << setw(20) << "Price/night" << setw(20) << "Room" << setw(20) << "Nights" << endl;
    priceList << setw(20) << "---------" << setw(20) << "----" << setw(20) << "-----" << setw(20) << "----" << setw(20) << "----" << endl;
    
    for(int i = 0; i < rooms.size(); i++){
        priceList << setw(20) << rooms[i].type << setw(20) << rooms[i].breakfast << setw(20) << rooms[i].price << setw(20) << setw(20) << rooms[i].packageType.numRoom << setw(20) << rooms[i].packageType.numNight << endl;
    }
}
Thomas Sablik
  • 16,127
  • 7
  • 34
  • 62
1

Arrays decay to pointers when passed to functions. This signature

void sort(roomType rooms[roomamt]){

is equivalent to

void sort(roomType* rooms){ 

This is a bit unfortunate, because it feeds the misunderstanding about arrays vs pointers. When you call the function

sort(rooms);

then the array rooms is implicily converted to a pointer to the first element in the array. The important thing is that in main rooms is an array, but in your functions rooms is a pointer. They are different types and the size information is lost.

This can be circumvented by passing the array by reference (see here for details). It is much easier to use std::array (size known at compile-time) or std::vector (dynamic size).

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185