10

I copied this code from a tutorial to play around with. However, I kept on getting an error that stated that I can't have any empty character constants. The tutorial was in Visual Studio 2008, and I am using Visual Studio 2013, so perhaps this is no longer valid, but I can't find any fix.

Here is the code:

#include "stdafx.h"
#include <iostream>

class MyString
{
    private:
        char *m_pchString;
        int m_nLength;

    public:
        MyString(const char *pchString="")
        {
            // Find the length of the string
            // Plus one character for a terminator
            m_nLength = strlen(pchString) + 1;

            // Allocate a buffer equal to this length
            m_pchString = new char[m_nLength];

            // Copy the parameter into our internal buffer
            strncpy(m_pchString, pchString, m_nLength);

            // Make sure the string is terminated
            // this is where the error occurs
            m_pchString[m_nLength-1] = '';
        }

        ~MyString() // Destructor
        {
            // We need to deallocate our buffer
            delete[] m_pchString;

            // Set m_pchString to null just in case
            m_pchString = 0;
        }

    char* GetString() { return m_pchString; }
    int GetLength() { return m_nLength; }
};

int main()
{
    MyString cMyName("Alex");
    std::cout << "My name is: " << cMyName.GetString() << std::endl;
    return 0;
}

The error I get is the following:

Error 1 error C2137: empty character constant

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
BeepBoop
  • 263
  • 1
  • 2
  • 12
  • To terminate C-style string use null character '\0'. – Petr Vepřek Jul 02 '15 at 19:53
  • 1
    Did you know: If you double click on visual studio errors in the "Error List" tab it takes you to the line they occur on and it highlights the error? It makes it a lot easier to find and fix problems like this. Also, when posting to SO, please include the line number? – kfsone Jul 02 '15 at 19:56
  • @kfsone in all fairness Manny did know which line caused the problem, and even marked it in the code, with a comment. – Tommy Andersen Jul 02 '15 at 20:17
  • in the comments it said where the error was, but it would be put in the explanation next time, thanks. – BeepBoop Jul 03 '15 at 00:11
  • The corresponding question for C: *[Empty character constant in C](https://stackoverflow.com/questions/56214828/)* – Peter Mortensen Sep 06 '22 at 22:52

3 Answers3

22

This line:

m_pchString[m_nLength-1] = '';

What you probably mean is:

m_pchString[m_nLength-1] = '\0';

Or even:

m_pchString[m_nLength-1] = 0;

Strings are zero terminated, which is written as a plain 0 or the null character '\0'. For double quote strings "" the zero termintation character is implicitly added to the end, but since you explicitly set a single character you must specify which.

Tommy Andersen
  • 7,165
  • 1
  • 31
  • 50
  • Could also write `""` since string literals are null terminated – ThatOneDude Jul 02 '15 at 19:55
  • but then i get an error stating that strncpy is unsafe to use if i use the null terminator – BeepBoop Jul 02 '15 at 19:57
  • @ssnobody well that depends, you can't write, say: `m_pchString[m_nLength-1] = "";` since `""` is really a pointer to a null terminated string, and not a single character. – Tommy Andersen Jul 02 '15 at 19:57
  • @Manny the safer version is `strncpy_s` http://en.cppreference.com/w/c/string/byte/strncpy – Tommy Andersen Jul 02 '15 at 20:00
  • however strncpy_s does not take the arguments i have listed – BeepBoop Jul 02 '15 at 20:02
  • @Manny no but that is the safer version. But keep in mind that it is a warning telling you that `strncpy` is unsafe, not an error. And since you created the resulting buffer yourself, with enough capacity to hold the entire string, you shouldn't worry. – Tommy Andersen Jul 02 '15 at 20:03
  • 1
    @TommyA True. If you wanted to exploit the string literals termination you could do `m_pchString[m_nLength-1] = ""[0];` but that's obviously much more complicated (and less readable) than the char style. – ThatOneDude Jul 02 '15 at 20:06
  • The "safety" of `strncpy` is discussed in http://stackoverflow.com/q/869883/3466415. Personally, I try to avoid using _any_ of the variants of "strcpy" functions except in code that is thoroughly examined and tested (I prefer `std::string` for most purposes), and I turn off the VS warning. – David K Jul 02 '15 at 20:06
  • sorry, didn't read the whole documentation properly, my bad. @TommyA, thanks – BeepBoop Jul 02 '15 at 20:08
1

What do you think about null-terminated string? Yes, you are right, such strings must be terminated with null:

m_pchString[m_nLength-1] = 0;
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
AnatolyS
  • 4,249
  • 18
  • 28
1

You've said that you "get an error stating that strncpy is unsafe to use if I use the null terminator," but you use strlen, which simply does not work if the string isn't null terminated. From cplusplus:

The length of a C string is determined by the terminating null-character

My suggestion would be to use null or 0 like others are suggesting and then just use strcpy instead of strncpy as you copy the whole string every time anyway.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
scohe001
  • 15,110
  • 2
  • 31
  • 51