'Declaring a string of fixed size
In C we do
char buffer[100];
Is there a way to declare a fixed size std::string?
Solution 1:[1]
You can use the string::reserve method like this
std::string s;
s.reserve(100);
But this isn't fixed size, because you can add more chars to the string with string::push_back for example.
Solution 2:[2]
In c++17, there will be std::string_view which offers the same (immutable) interface as std::string.
In the meantime, you can wrap a char array and add whatever services to it you choose, eg:
template<std::size_t N>
struct immutable_string
{
using ref = const char (&)[N+1];
constexpr immutable_string(ref s)
: s(s)
{}
constexpr auto begin() const { return (const char*)s; }
constexpr auto end() const { return begin() + size(); }
constexpr std::size_t size() const { return N; }
constexpr ref c_str() const { return s; }
ref s;
friend std::ostream& operator<<(std::ostream& os, immutable_string s)
{
return os.write(s.c_str(), s.size());
}
};
template<std::size_t NL, std::size_t NR>
std::string operator+(immutable_string<NL> l, immutable_string<NR> r)
{
std::string result;
result.reserve(l.size() + r.size());
result.assign(l.begin(), l.end());
result.insert(result.end(), r.begin(), r.end());
return result;
}
template<std::size_t N>
auto make_immutable_string(const char (&s) [N])
{
return immutable_string<N-1>(s);
}
int main()
{
auto x = make_immutable_string("hello, world");
std::cout << x << std::endl;
auto a = make_immutable_string("foo");
auto b = make_immutable_string("bar");
auto c = a + b;
std::cout << c << std::endl;
}
Solution 3:[3]
As of Boost 1.66: A non-allocating string that emulates the interface of std::basic_string.
Solution 4:[4]
I don't know what you want to do, but with an std::array<char, 100> buffer; you should do fine.
You can then get a string like this:
std::string str(std::begin(buffer),std::end(buffer);
Solution 5:[5]
check this https://github.com/m3janitha/fixed_size_string. you can replace char buffer[n]; with fss::fixed_size_string<n> buffer;
Solution 6:[6]
You could use std::array, which is the C++ method of doing exactly what you did in C.
std::array<char, 100> buffer;
If you're worried about stack overflow due to large buffer sizes (like, for example, if that 100 is a stand-in for 1'000'000) you could dynamically allocate it instead.
std::unique_ptr<std::array<char, 100>> buffer = std::make_unique<std::array<char, 100>>();
Since your interface takes a char * as its operand, and this object allows you to query for its size at runtime, this ought to suffice.
Solution 7:[7]
Finally, I made the solution shown below. It will run on Excel 64 bit, but probably it can easily be changed to 32 bit (see suggestions in the code). I have tested it on Excel 2016.
' Helge V. Larsen (MSc, PhD)
' [email protected]
' HELA Consulting
' January 2022.
' Regarding Windows API: Very much inspired by the late Howard Kaikow:
' http://www.standards.com/Office/SetVBAProjectPassword.html
'
' Author: Howard Kaikow
' URL : http://www.standards.com/
' Email : [email protected]
' Date : April 2005
' This will run in Excel 64 bit.
' It will probably run in Excel 32 bit
' if you remove all "PtrSafe" and change all "LongPtr" to "Long".
' (I cannot test it since I do not have access to Exccel 32 bit.)
'
' Alternatively, you could use compiler directives
' #If VBA7 Then
' #Else
' #End If
' to make it run in Excel 32 and 64 bit .
Option Explicit
' API constants
Private Const BM_CLICK As Long = &HF5&
Private Const BM_SETCHECK As Long = &HF1&
Private Const BST_CHECKED As Long = &H1&
Private Const EM_REPLACESEL As Long = &HC2&
Private Const HWND_TOPMOST As Long = -1
Private Const SWP_NOACTIVATE As Long = &H10&
Private Const SWP_NOMOVE As Long = &H2&
Private Const SWP_NOSIZE As Long = &H1&
Private Const SWP_SHOWWINDOW As Long = &H40&
Private Const TCM_SETCURFOCUS As Long = &H1330&
' API functions and subs
Private Declare PtrSafe Function EnumChildWindows Lib "user32" _
(ByVal hWndParent As LongPtr, ByVal lpEnumFunc As LongPtr, ByVal lParam As Long) As Long
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare PtrSafe Function GetDlgItem Lib "user32.dll" _
(ByVal hDlg As LongPtr, ByVal nIDDlgItem As Long) As Long
Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare PtrSafe Function SetFocusAPI Lib "user32" Alias "SetFocus" _
(ByVal hWnd As Long) As Long
Private Declare PtrSafe Sub SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, _
ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long)
Private hWndProjectProperties As LongPtr
Sub HVL_Lock_VBProject()
' Protect VBProject in workbook.
' The workbook is opened in another instance of Excel.
Dim appExcel As Excel.Application
Dim wbkExcel As Excel.Workbook
Dim aFile As String
Dim Pass As String
aFile = HVL_GetFile_Dialog("Browse for Excel workbook", ThisWorkbook.Path, "Excel files, *.xl*,")
If aFile = vbNullString Then Exit Sub
Set appExcel = New Excel.Application
appExcel.Visible = False
Set wbkExcel = appExcel.Workbooks.Open(aFile)
If wbkExcel.VBProject.Protection = vbext_pp_none Then
Pass = HVL_Get_PassWord
If Pass = vbNullString Then GoTo Exit_Sub
SetPassword wbkExcel.VBProject, Pass
Else ' vbext_pp_locked
MsgBox "The VBproject in" & vbCr & _
aFile & vbCr & _
"is protected." & vbCr & vbCr & _
"Cannot change Project Password.", _
vbInformation, _
"Information"
GoTo Exit_Sub
End If
wbkExcel.Save
wbkExcel.Close False
MsgBox "The VBproject in" & vbCr & _
aFile & vbCr & _
"has been locked.", _
vbInformation, _
"Information"
Exit_Sub:
appExcel.Quit
Set appExcel = Nothing
Set wbkExcel = Nothing
End Sub
Sub SetPassword(ByRef aVBProject As VBProject, ByVal strPassword As String)
' Author: Howard Kaikow
' URL : http://www.standards.com/
' Email : [email protected]
' Date : April 2005
' spy++ was used to find the Control IDs in Project Properties dialog
' Changed by Helge V. Larsen.
Const ControlIDConfirmPassword As Long = &H1556&
Const ControlIDLockProject As Long = &H1557&
Const ControlIDOK As Long = &H1&
Const ControlIDPassword As Long = &H1555&
Const ControlIDSysTabControl32 As Long = &H3020&
Dim Ctrl As Office.CommandBarControl
Dim hWnd As Long
Dim hWndLockProject As Long
Dim hWndPassword As Long
Dim hWndConfirmPassword As Long
Dim hWndOK As Long
Dim hWndSysTabControl32 As Long
Dim strCaption As String
With aVBProject
strCaption = .Name & " - Project Properties"
With .VBE
' Find Project Properties dialog
Set Ctrl = .CommandBars.FindControl(ID:=2578)
' Display Project Properties dialog
Ctrl.Execute
Set Ctrl = Nothing
End With
End With
' Get hWnd for Project Properties dialog
hWndProjectProperties = FindWindow(vbNullString, strCaption)
If hWndProjectProperties = 0 Then
Exit Sub
End If
' Get hWnd for OK button in Project Properties dialog
hWndOK = GetDlgItem(hWndProjectProperties, ControlIDOK)
' Get hWnd for Tab Control in Project Properties dialog
hWndSysTabControl32 = GetDlgItem(hWndProjectProperties, ControlIDSysTabControl32)
'Move to Protection tab
SendMessage hWndSysTabControl32, TCM_SETCURFOCUS, 1, ByVal 0&
' Must reset hWndProjectProperties probably because tab changed.
EnumChildWindows ByVal hWndProjectProperties, AddressOf EnumChildProc, ByVal 0
' Get hWnd for Password Edit control in Project Properties dialog
hWndPassword = GetDlgItem(hWndProjectProperties, ControlIDPassword)
' Get hWnd for Confirm Password Edit control in Project Properties dialog
hWndConfirmPassword = GetDlgItem(hWndProjectProperties, ControlIDConfirmPassword)
' Get hWnd for Lock Project checkbox control in Project Properties dialog
hWndLockProject = GetDlgItem(hWndProjectProperties, ControlIDLockProject)
' Lock project for &viewing
SendMessage hWndLockProject, BM_SETCHECK, BST_CHECKED, 0
' &Password
SendMessage hWndPassword, EM_REPLACESEL, vbTrue, ByVal strPassword
' &Confirm password
SendMessage hWndConfirmPassword, EM_REPLACESEL, vbTrue, ByVal strPassword
'OK button
SetFocusAPI hWndOK
SendMessage hWndOK, BM_CLICK, 0&, 0&
End Sub
Function EnumChildProc(ByVal hWnd As LongPtr, ByVal lParam As Long) As Long
hWndProjectProperties = hWnd
' Do not recurse
EnumChildProc = 0
End Function
Function HVL_GetFile_Dialog(Optional DialogTitle As String, _
Optional InitDirectory As String, _
Optional Filter As String, _
Optional InitView As Office.MsoFileDialogView = msoFileDialogViewDetails) As String
' Filter: e.g. "Data bases, *.mdb; *.accdb"
Dim Filter_Arr As Variant
Dim ViewType As Office.MsoFileDialogView
With Application.FileDialog(msoFileDialogFilePicker)
.InitialView = InitView
.AllowMultiSelect = False
If DialogTitle <> vbNullString Then .Title = DialogTitle
If Dir(InitDirectory, vbDirectory) <> vbNullString Then
.InitialFileName = InitDirectory
Else
.InitialFileName = CurDir
End If
If Filter <> vbNullString Then
Filter_Arr = Split(Filter, ",")
.Filters.Add Trim(Filter_Arr(0)), Trim(Filter_Arr(1)), 1
End If
If .Show = True Then
HVL_GetFile_Dialog = .SelectedItems(1)
Else
HVL_GetFile_Dialog = vbNullString
End If
End With
End Function
Function HVL_Get_PassWord()
Dim Pass1 As String
Dim Pass2 As String
Pass1 = InputBox("Enter VBproject password:", "Lock VBroject")
If Pass1 = vbNullString Then GoTo No_Password
Pass2 = InputBox("Caution: If you loose or forget the password," & vbCr & _
"it cannot be recovered. It is advisable to keep" & vbCr & _
"a list of passwords and their corresponding" & vbCr & _
"workbook names in a safe place." & vbCr & _
"(Remember that passwords are case-sensitive.)" & vbCr & vbCr & _
"Confirm VBproject password:", _
"Lock VBproject")
If Pass2 = vbNullString Then GoTo No_Password
If Pass1 <> Pass2 Then
MsgBox "Confirmation password is not identical!", vbCritical, "Error"
GoTo No_Password
End If
HVL_Get_PassWord = Pass1
Exit Function
No_Password:
HVL_Get_PassWord = vbNullString
End Function
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | pospich0815 |
| Solution 2 | Richard Hodges |
| Solution 3 | double-beep |
| Solution 4 | phuclv |
| Solution 5 | janitha M |
| Solution 6 | Xirema |
| Solution 7 | Helge |
