Cannot seem to save EEPROM readings to variable in string format

I know this is a very basic concept I just cannot seem to grasp it. I am trying to save program settings to EEPROM, then read them back when the Arduino boots. I can save my values and read them back and print them on the Serial Display. I cannot save them as a variable and I only see them as numbers. They do not even correspond to ASCII codes either most of the time. I will get a square empty box for a character instead of a number for example. Please see my simplified code that just contains the code related to this issue below and let me know what I am doing wrong. I know it is something or some things stupid I am doing but I am just not seeing it. Thank you.

#include <EEPROM.h>

// start reading from the first byte (addr 0) of the EEPROM
int addr = 0;
byte value;

void setup() {
  // initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.println("Writing");
  Serial.println("~~~~~~~~~~~~~~~~~~~");
  Serial.println();
  writeMsgText("Item 1", addr);
  writeMsgInt(5,addr);  
  writeMsgInt(10,addr);
  writeMsgInt(15,addr);
  writeMsgInt(20,addr);
  writeMsgText("Item 2", addr);
  writeMsgInt(3,addr);  
  writeMsgInt(22,addr);
  writeMsgInt(34,addr);
  writeMsgInt(43,addr);

  Serial.println("Reading");
  Serial.println("~~~~~~~~~~~~~~~~~~~");
  Serial.println();
  addr = 0;
  while(addr<40){
    // read a byte from the current addr of the EEPROM
    value = EEPROM.read(addr);
    char myCharacter = char(value);
  
    Serial.print(addr);
    Serial.print("\t");
    Serial.print(myCharacter);
    Serial.println();
    delay(500);
    addr++;
  }
  
}


void writeMsgText(String msg, int startingAddr){
  Serial.print("msg: "); Serial.println(msg);
  Serial.print("msg length: "); Serial.println(msg.length());
  char buff[7];
  msg.toCharArray(buff, 7);
  Serial.print("buff: '"); Serial.print(buff); Serial.println("'");
  Serial.print("buff length: "); Serial.println(sizeof(buff));
  EEPROM.write(startingAddr,buff[0]);
  EEPROM.write(startingAddr+1,buff[1]);
  EEPROM.write(startingAddr+2,buff[2]);
  EEPROM.write(startingAddr+3,buff[3]);
  EEPROM.write(startingAddr+4,buff[4]);
  EEPROM.write(startingAddr+5,buff[5]);
  addr = startingAddr + 7;
  Serial.println();
}

void writeMsgInt(int msg, int startingAddr){
  Serial.print("msg: "); Serial.println(msg);  
  EEPROM.write(startingAddr,msg);
  addr = startingAddr + 2;
  Serial.println();
}

void loop() {
 
}

Edit: deleted.

I didn't read far enough into the functions to see they are updating addr as a side-effect. Clue: if you have this kind of side-effect then you don't need to pass the variable into the function, inside the brackets().

You may also take advantage from the EEPROM.put() and EEPROM.get() functions. Used it for writing/reading quite complex structs before, but tbh not sure how it works with strings and other arrays.

I think I found a solution. I will not have to write to EEPROM often just read so I think this will work for what I need.

#include <EEPROM.h>

// start reading from the first byte (addr 0) of the EEPROM
int addr = 0;
byte value;

void setup() {
  // initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.println("Clearing...");
  for(int i = 0; i < EEPROM.length(); i++){
    EEPROM.write(i," ");
  }

  Serial.println("Writing");
  Serial.println("~~~~~~~~~~~~~~~~~~~");
  Serial.println();
  writeMsgText("Item 1: 10, 5, 200, 150/", addr);
  writeMsgText("Item 2: 1, 56, 123, 246/", addr);

  Serial.println("Reading");
  Serial.println("~~~~~~~~~~~~~~~~~~~");
  Serial.println();
  addr = 0;
  while(addr<40){
    // read a byte from the current addr of the EEPROM
    value = EEPROM.read(addr);
    char myCharacter = char(value);
  
    Serial.print(addr);
    Serial.print("\t");
    Serial.print(myCharacter);
    Serial.println();
    addr++;
  }
  
}


void writeMsgText(String msg, int startingAddr){
  char buff[msg.length()];
  msg.toCharArray(buff, msg.length());
  Serial.print("buff: '"); Serial.print(buff); Serial.println("'");
  Serial.print("buff length: "); Serial.println(sizeof(buff));
  for(int i = 0; i < msg.length(); i++){
    EEPROM.write(startingAddr+i,buff[i]);
  }
  addr = startingAddr + msg.length() + 1;
  Serial.println();
}

void loop() {
 
}

There is no need to clear the EEPROM first.

It doesn't help in any way, it takes extra code, and it reduces the life of the EEPROM. Mind that EEPROM can be written to a limited time - every time it's written a complete 4-byte cell is erased and rewritten, so your "clearing" code effectively takes four writes off the lifetime of the EEPROM without adding anything useful to your code.