Combining a static char* and a constant string - string

I want to be able to append a constant string to the end of another string in the form of a char*, and then use the resulting string as an argument for open(). Here's what it looks like:
file1.cpp
#include "string.h"
file2 foo;
char* word = "some";
foo.firstWord = word; //I want the file2 class to be able to see "some"
file2.h
#include <fstream>
#include <iostream>
#define SECONDWORD "file.txt"
class file2{
public:
file2();
static char* firstWord;
static char* fullWord;
private:
ofstream stream;
}
file2.cpp
#include "file2.h"
char* file2::firstWord;
char* file2::fullWord;
fullWord = firstWord + SECONDWORD; //so fullWord is now "somefile.txt" ,I know this doesn't work, but basically I am trying to figure out this part
file2::file2(){
stream.open(fullWord);
}
So I am not very well versed in C++, so any help would be appreciated!

C++-style solution might be the following.
#include <string>
char* a = "file";
char* b = ".txt";
...
stream.open((std::string(a) + b).c_str());
What happens here? First, std::string(a) creates a temporary std::string object. Than b value is added to it. At last, c_str() method returns a c-style string which contains a + b.

Related

C++11: how to use accumulate / lambda function to calculate the sum of all sizes from a vector of string?

For a vector of strings, return the sum of each string's size.
I tried to use accumulate, together with a lambda function (Is it the best way of calculating what I want in 1-line?)
Codes are written in wandbox (https://wandbox.org/permlink/YAqXGiwxuGVZkDPT)
#include <iostream>
#include <numeric>
#include <string>
#include <vector>
using namespace std;
int main() {
vector<string> v = {"abc", "def", "ghi"};
size_t totalSize = accumulate(v.begin(), v.end(), [](string s){return s.size();});
cout << totalSize << endl;
return 0;
}
I expect to get a number (9), however, errors are returned:
/opt/wandbox/gcc-head/include/c++/10.0.0/bits/stl_numeric.h:135:39: note: 'std::__cxx11::basic_string' is not derived from 'const __gnu_cxx::__normal_iterator<_Iterator, _Container>'
135 | __init = _GLIBCXX_MOVE_IF_20(__init) + *__first;
I want to know how to fix my codes? Thanks.
That's because you do not use std::accumulate properly. Namely, you 1) did not specify the initial value and 2) provided unary predicate instead of a binary. Please check the docs.
The proper way to write what you want would be:
#include <iostream>
#include <numeric>
#include <string>
#include <vector>
using namespace std;
int main() {
vector<string> v = {"abc", "def", "ghi"};
size_t totalSize = accumulate(v.begin(), v.end(), 0,
[](size_t sum, const std::string& str){ return sum + str.size(); });
cout << totalSize << endl;
return 0;
}
Both issues are fixed in this code:
0 is specified as initial value, because std::accumulate needs to know where to start, and
The lambda now accepts two parameters: accumulated value, and the next element.
Also note how std::string is passed by const ref into the lambda, while you passed it by value, which was leading to string copy on each invocation, which is not cool

How to fix "expected identifier or '(' in C compilation?

I am new to coding and I keep getting stuck in the first few lines of code and I cannot figure out why. This is what I have so far:
#include <stdio.h>
#include <cs50.h>
int main(void);
int n;
{
printf("Minute: ");
int n = get_int();
}
I am getting this message when I try to compile the code:
What did I do wrong?
You're trying to call the main function. You should only define it. It will be called when the program is executed (it is the "entry point").
To define it, remove the semicolon after
int main(void)
You can also remove that void keyword
Then move that line down, between
int n; and the { that comes after it
Additionally, you're declaring the n variable twice. After you fix the first error, the compiler will complain about this one. Remove one of the declarations then.
You should remove the semicolon after int main(void) and move the variable declaration for n within the braces. Here is the correct code below.
#include <stdio.h>
#include <cs50.h>
int main(void)
{
int n;
printf("Minute: ");
int n = get_int();
}

Convert a String^ to wstring C++

I programmed a little Application in C++. There is a ListBox in the UI. And I want to use the selected Item of ListBox for an Algorithm where I can use only wstrings.
All in all I have two questions:
-how can I convert my
String^ curItem = listBox2->SelectedItem->ToString();
to a wstring test?
-What means the ^ in the code?
Thanks a lot!
It should be as simple as:
std::wstring result = msclr::interop::marshal_as<std::wstring>(curItem);
You'll also need header files to make that work:
#include <msclr\marshal.h>
#include <msclr\marshal_cppstd.h>
What this marshal_as specialization looks like inside, for the curious:
#include <vcclr.h>
pin_ptr<WCHAR> content = PtrToStringChars(curItem);
std::wstring result(content, curItem->Length);
This works because System::String is stored as wide characters internally. If you wanted a std::string, you'd have to perform Unicode conversion with e.g. WideCharToMultiByte. Convenient that marshal_as handles all the details for you.
I flagged this as a duplicate, but here's the answer on how to get from System.String^ to a std::string.
String^ test = L"I am a .Net string of type System::String";
IntPtr ptrToNativeString = Marshal::StringToHGlobalAnsi(test);
char* nativeString = static_cast<char*>(ptrToNativeString.ToPointer());
The trick is make sure you use Interop and marshalling, because you have to cross the boundary from managed code to non-managed code.
My version is:
Platform::String^ str = L"my text";
std::wstring wstring = str->Data();
With Visual Studio 2015, just do this:
String^ s = "Bonjour!";
C++/CLI
#include <vcclr.h>
pin_ptr<const wchar_t> ptr = PtrToStringChars(s);
C++/CX
const wchart_t* ptr = s->Data();
According to microsoft:
Ref How to: Convert System::String to Standard String
You can convert a String to std::string or std::wstring, without using PtrToStringChars in Vcclr.h.
// convert_system_string.cpp
// compile with: /clr
#include <string>
#include <iostream>
using namespace std;
using namespace System;
void MarshalString ( String ^ s, string& os ) {
using namespace Runtime::InteropServices;
const char* chars =
(const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
os = chars;
Marshal::FreeHGlobal(IntPtr((void*)chars));
}
void MarshalString ( String ^ s, wstring& os ) {
using namespace Runtime::InteropServices;
const wchar_t* chars =
(const wchar_t*)(Marshal::StringToHGlobalUni(s)).ToPointer();
os = chars;
Marshal::FreeHGlobal(IntPtr((void*)chars));
}
int main() {
string a = "test";
wstring b = L"test2";
String ^ c = gcnew String("abcd");
cout << a << endl;
MarshalString(c, a);
c = "efgh";
MarshalString(c, b);
cout << a << endl;
wcout << b << endl;
}
output:
test
abcd
efgh

cant convert parameter from char[#] to LPWSTR

When I compile this code in Visual C++, I got the below error. Can help me solve this issue..
DWORD nBufferLength = MAX_PATH;
char szCurrentDirectory[MAX_PATH + 1];
GetCurrentDirectory(nBufferLength, szCurrentDirectory);
szCurrentDirectory[MAX_PATH +1 ] = '\0';
Error message:
Error 5 error C2664: 'GetCurrentDirectoryW' : cannot convert parameter 2 from 'char [261]' to 'LPWSTR' c:\car.cpp
Your program is configured to be compiled as unicode. Thats why GetCurrentDirectory is GetCurrentDirectoryW, which expects a LPWSTR (wchar_t*).
GetCurrentDirectoryW expects a wchar_t instead of char array. You can do this using TCHAR, which - like GetCurrentDirectory - depends on the unicode setting and always represents the appropriate character type.
Don't forget to prepend your '\0' with an L in order to make the char literal unicode, too!
It seems you have define UNICODE, _UNICODE compiler flags. In that case, you need to change the type of szCurrentDirectory from char to TCHAR.
Headers:
#include <iostream>
#include <fstream>
#include <direct.h>
#include <string.h>
#include <windows.h> //not sure
Function to get current directory:
std::string getCurrentDirectoryOnWindows()
{
const unsigned long maxDir = 260;
wchar_t currentDir[maxDir];
GetCurrentDirectory(maxDir, currentDir);
std::wstring ws(currentDir);
std::string current_dir(ws.begin(), ws.end());
return std::string(current_dir);
}
To call function:
std::string path = getCurrentDirectoryOnWindows(); //Output like: C:\Users\NameUser\Documents\Programming\MFC Program 5
To make dir (Folder) in current directory:
std::string FolderName = "NewFolder";
std::string Dir1 = getCurrentDirectoryOnWindows() + "\\" + FolderName;
_mkdir(Dir1.c_str());
This works for me in MFC C++.

Error initializing XGCValues

I was following this tutorial, bit stuck here:
This code doesn't compile, and the error message is
c:35: error: invalid initializer
I'm not sure what's wrong with the line
XGCValues valu=CapButt|JoinBevel;
infact, I copied it from the said tutorial. Here's the full code I have:
#include <stdio.h>
#include <X11/Xlib.h>
#include <unistd.h>
int main()
{
Display *display=XOpenDisplay(NULL);
int scr=DefaultScreen(display);
Window root_window=RootWindow(display,scr);
unsigned int width=DisplayWidth(display,scr)/3;
unsigned int height=DisplayHeight(display,scr)/3;
unsigned int border=2;
Window my_win=XCreateSimpleWindow(display,root_window,0,0,width,height,border,BlackPixel(display,scr),WhitePixel(display,scr));
GC gc;
XGCValues valu=CapButt|JoinBevel;
unsigned long valmask=GCCapStyle|GCJoinStyle;
gc=XCreateGC(display,my_win,valmask,&valu);
XDrawLine(display,my_win,gc,5,5,20,20);
XMapWindow(display,my_win);
XFlush(display);
sleep(10);
return 0;
}
Thank You
The example in the tutorial is wrong - if you look in <X11/Xlib.h> or read the XCreateGC man page you'll see XGCValues is a struct, not a integral type, so you would need to initialize it with something like:
XGCValues values;
values.cap_style = CapButt;
values.join_style = JoinBevel;

Resources