-1

I am trying to create a switch statement using the parameters that can be passed into my File classes constructor in the mode parameter. However, as mode can be up to 2 chars (r, r+, w, or w+), I do not know how to create a switch statement that will get this done for me.

Does anyone have any suggestions on how to implement this? Currently with what I have below, I am getting errors for the r+ and `w+ cases, as those are not chars, but rather strings

File::File(const char *name, const char *mode) {
  int fileMode = 0;    //Initializing mode to 0
  fileName = name;    //Setting the file name of this File object to the name we pass in.

  switch(*mode){
    case 'r':
      //do stuff…
      break;

    // Open a text file for update (that is, for both reading and writing)
    case 'r+':            
      //do stuff…
      break;

    case 'w':
      //do stuff…
      break;

    // Open a text file for update (reading and writing),
    // first truncating the file to zero length if it exists
    // or creating the file if it does not exist.
    case 'w+':           
      //do stuff…
      break;
    
    default:    //We should never reach the default case, as the user shouldnt pass in anything else so I assert(0) in this case.
      assert(0);
  }

Problem solved that I cant use more than one char at a time for a switch statement.

  • 1
    You cannot use `switch`/`case` to compare strings. `'r+'` is not a valid character constant. In your case you might be able to combine two characters into a value of `uint16_t` but this would not make your code easy to read. I suggest to use `switch`/`case` to check for `'r'`, `'w'` or invalid character and use an additional `if(mode[1]=='+')` in both cases. BTW: It might be acceptable to use `assert` in the `default` case if your code is expected to never call your constructor with an invalid input string, but you should not use `assert` to handle run-time errors, e.g. of `malloc`, `open` ... – Bodo May 14 '21 at 09:25
  • 1
    see also https://stackoverflow.com/q/16388510/10622916 – Bodo May 14 '21 at 09:28

1 Answers1

1

You can't use more than one value in case.

1 - You can use more than one switch:

switch(mode[0]){
    case 'r':
        switch(mode[1]){
            case '+':
                switch(mode[2]){
                    case 0:
                        fileMode = O_RDWR | O_CREAT;
                        canWeRead = true;
                        canWeWrite = true;
                        break;
                    default:
                        assert(0);
                }
            case 0:
                fileMode = O_RDONLY | O_CREAT;
                canWeRead = true;
                canWeWrite = false;
                break;
        }
        break;
    case 'w':
        switch(mode[1]){
            case '+':
                switch(mode[2]){
                    case 0:
                        fileMode = O_RDWR | O_CREAT | O_TRUNC;
                        canWeRead = true;
                        canWeWrite = true;
                        break;
                    default:
                        assert(0);
                }
            case 0:
                fileMode = O_WRONLY | O_CREAT;
                canWeRead = false;
                canWeWrite = true;
                break;
        }
        break;
    default:
        assert(0);
}

2 - You can make mode's type char[4] and have ugly function call. Like File("filename", {'r', '+'}) (this way can be affected by endian difference)

switch(*(uint32_t *)mode){
    // r
    case 0x72000000:
        fileMode = O_RDONLY | O_CREAT;
        canWeRead = true;
        canWeWrite = false;
        break;
    // r+
    case 0x722b0000:
        fileMode = O_RDWR | O_CREAT;
        canWeRead = true;
        canWeWrite = true;
        break;
    // w
    case 0x77000000:
        fileMode = O_WRONLY | O_CREAT;
        canWeRead = false;
        canWeWrite = true;
        break;
    // w+
    case 0x772b0000:
        fileMode = O_RDWR | O_CREAT | O_TRUNC;
        canWeRead = true;
        canWeWrite = true;
        break;
    default:
        assert(0);
}

Anyway that ways are just too much overkill for simple thing. System calls would eat more than thousands of more time than string compare.

fsdfhdsjkhfjkds
  • 308
  • 1
  • 9