Extended ASCII charatcer string convert into Hex format - format

I am trying to convert the input ascii string to hex format using the format specifier "%.2X" . I have pasted the program at below which does the same. But, this program works in Linux server its giving improper hex output.
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int main ()
{
char *buffer = "<9e>¥/gÿbbbbABCD";
char *newBuffer = new char[strlen(buffer)*2 + 1];
for(int i = 0; i< strlen(buffer); ++i)
{
sprintf(newBuffer+(2*i), "%02x", buffer[i]);
//cout<<"\t"<<newBuffer;
}
cout<<"\t"<<newBuffer;
return 0;
}
o/p: 3c39653effff2f67ffff6262626241424344
for this extended ASCII char ¥ and ÿ is giving ffff and ffff.
Please tell me how to convert properly.

If we typecast the source string with unsigned char, the problem gets solved:
sprintf(newBuffer+(2*i), "%02x", (unsigned char)buffer[i]);

Related

Non-ASCII character casted on int

I would like to cast a non-ASCII character (for example 'ą') on int to get it number in UTF-8. When I do something like this:
#include <iostream>
using namespace std;
int main()
{
cout << static_cast<int>('ą')<<endl;
return 0;
}
I get -71 what is not its proper number in UTF-8. I heard that it might be because 'ą' is stored in 2 bytes and one of them is cut away when initialization of variable. Any solution for this?

Why this is showing error ? even though it seems all syntax is correct?

I was writing a c++ code then encountered this error, how to resolve this ?
#include<iostream>
using namespace std;
int main(){
string str="([])[]({})";
char a[10];
int stk[10], total=0;
for(int i=0; i<10; i++){
a[i]=str[i];
cout<<a[i];
if(a[i]=="[" || a[i]=="{" || a[i]=="("){
}
}
}
Put single ticks around the items being compared: '[' instead of "[". That way you are comparing char to char instead of char to a string

How do i pass a variable as wchat_t** from a std::wstring in c++

I am using VS 2019 and the C++ Language Standard is set to Default which I assume is C++ 11?
I have the following constructor of a class in a header file:
input_parser(int& argc, wchar_t** argv)
{
for (auto i = 0; i < argc; ++i)
{
this->tokens_.emplace_back(argv[i]);
}
};
To call the methods argv parameter I am creating an array of wchar_t in the following manner:
std::wstring command_line = L"-m \"F-14RHV\" -s \"BIT|Flir\" -d";
auto buffer = new wchar_t[command_line.length() + 1];
wcsncpy_s(buffer, command_line.length()+1, command_line.c_str(), command_line.length() + 1);
const auto inputs = input_parser(argc, &buffer);
delete[] buffer;
Inside the constructor the first pass when argc == 0 is fine but I get an access violation when argc == 1.
Okay so some programmer dude was correct and here is how I have to do it after I figure out how to split the string by spaces!
Here is the final answer:
#include <string>
#include <sstream>
#include <algorithm>
#include <iostream>
#include <iterator>
std::wstring text = L"-m \"F-14RHV\" -s \"BIT|Flir\" -d";
std::wistringstream iss(text);
std::vector<std::wstring> results((std::istream_iterator<std::wstring, wchar_t>(iss)),
std::istream_iterator<std::wstring, wchar_t>());
Using a vector is going to make this process MUCH easier. I will probably change the other side to use a vector now.
Thanks for the help.

Building simply download menager with libcurl on Ubuntu, in C

I'm having some problems with my code. I get segmentation code error after compiling my program. I want to build simply download tool so i'm using the simplest ideas for it.(User enters the url and program download file into users desktop). Could you give me some tips how to make this program work or how to convert it to better one (more demanding code with better results).
#define CURL_STATICLIB
#include <stdio.h>
#include <curl/curl.h>
#include <string.h>
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
size_t written;
written = fwrite(ptr, size, nmemb, stream);
return written;
}
int main(void)
{
CURL *curl;
FILE *fp;
CURLcode res;
int x;
char y[200];
char page;
char outfilename[FILENAME_MAX];
char path_pdf = "/home/user_name/Desktop/document.pdf";
char path_jpg = "/home/user_name/Desktop/picture.jpg";
char path_txt = "/home/user_name/Desktop/document.txt";
char FILEPATH[2] = {path_pdf, path_jpg, path_txt};
printf("Enter file url \n"); // for example http://oi58.tinypic.com/15nk3de.jpg
scanf ("%s",y);
char *url = "y";
printf("Choose type of file:\n [0] - pdf\n [1] - jpg\n [2] - txt\n "); //choose 1
scanf("%d",x);
outfilename[FILENAME_MAX] = FILEPATH[x];
curl = curl_easy_init();
if (curl)
{
fp = fopen(outfilename,"wb");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(fp);
}
return 0;
}
There are several reasons that your code isn't working:
path_pdf, path_jpg, and path_txt should be type char*
FILEPATH should be declared as char FILEPATH[3] = {path_pdf, path_jpg, path_txt}; as RaptorDotCpp pointed out.
Your second scanf call should be scanf("%d", &x); since scanf requires the arguments after the format to be pointers. This is where your code segfaulted when I tested it.
url should be initialized as char *url = y;. This sets url to the value the user entered instead of only the letter "y".
outfilename[FILENAME_MAX] = FILEPATH[x]; writes past the end of outfilename. Use outfilename = FILEPATH[x]; instead, which won't cause a buffer overflow.

Retrieving VolumeDetails of WINDOWS Drives - stuck with 'char []' to 'LPCWSTR' conversion

I am trying to get the VolumeDetails of my WINDOWS system- Drive label plus its respective Volume Serial number. I've tried since an hour and built a code which gone wrong in syntax. At present I am getting the following error with it-
error C2664: 'GetVolumeInformationW' : cannot convert parameter 1 from 'char []' to 'LPCWSTR'
Here is my code:
// getVolDrive.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <direct.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <sstream>
#include <string>
#include <ctype.h>
#include <algorithm>
using namespace std;
//wchar_t mydrives[5];// = " A: ";
char mydrives[] = " A: ";
string retVolSno(char drives[]) //wchar_t drives[]
{
DWORD dwSerial;
stringstream ss;
cout<<drives<<endl;
if(!GetVolumeInformation(drives, NULL, 0, &dwSerial, NULL, NULL, NULL, 0))
{
ss<<"Error: "<<GetLastError();
}
else
{
ss<<hex<<dwSerial;
}
return ss.str();
}
int _tmain(int argc, _TCHAR* argv[])
{
string cVolSno;
ULONG DriveMask = _getdrives();
if(DriveMask == 0)
printf("_getdrives() failed with failure code: %d\n", GetLastError());
else
{
printf("This machine has the following logical drives:\n");
while (DriveMask)
{
cout << "In While" << endl;
if(DriveMask & 1)
printf("%s", mydrives);
wcout << mydrives << endl;
cVolSno = retVolSno(mydrives);
cout<<cVolSno<<endl;
++mydrives[1];
DriveMask >>= 1;
}
}
//std::transform(cVolSno.begin(), cVolSno.end(),cVolSno.begin(), ::toupper);
//cout<<cVolSno<<endl;
_getch();
return 0;
}
I've also tried replacing char with wchar_t, I didn't got any build errors, but while executing the application, got Error Code 3- Path not found!.
CODE MODIFIED:
// getVolDrive.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <direct.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <sstream>
#include <string>
#include <ctype.h>
#include <algorithm>
using namespace std;
//wchar_t mydrives[5];// = " A: ";
char mydrives[] = " A:\\\\ ";
string retVolSno(char drives[]) //wchar_t drives[]
{
DWORD dwSerial;
stringstream ss;
wchar_t text[10];
mbstowcs(text,drives,100); //strlen(drives)+1
LPWSTR ptr = text;
if(!GetVolumeInformation(ptr, NULL, 0, &dwSerial, NULL, NULL, NULL, 0))
{
ss<<"Error: "<<GetLastError();
}
else
{
ss<<hex<<dwSerial;
}
return ss.str();
}
int _tmain(int argc, _TCHAR* argv[])
{
string cVolSno;
ULONG DriveMask = _getdrives();
if(DriveMask == 0)
printf("_getdrives() failed with failure code: %d\n", GetLastError());
else
{
printf("This machine has the following logical drives:\n");
while (DriveMask)
{
if(DriveMask & 1)
printf("%s \n", mydrives);
cVolSno = retVolSno(mydrives);
std::transform(cVolSno.begin(), cVolSno.end(),cVolSno.begin(), ::toupper);
cout<<cVolSno<<endl;
++mydrives[1];
DriveMask >>= 1;
}
}
//std::transform(cVolSno.begin(), cVolSno.end(),cVolSno.begin(), ::toupper);
//cout<<cVolSno<<endl;
_getch();
return 0;
}
OUTPUT:
This machine has the following logical drives:
ERROR: 123
ERROR: 123
C:\\
ERROR: 123
D:\\
ERROR: 123
E:\\
ERROR: 123
I see at least these main issues:
1) wchar_t is the right type because you're compiling for UNICODE, you can write generic code using TCHAR macro or explicitly declare your buffer as wchar_t but that's what to do.
2) You have that error because you're passing wrong path to GetVolumeInformation() (trailing backslash is required so A: must become A:\).
Moreover please note that you have a little bit more easy way to achieve same result, you can use GetLogicalDriveStrings() to directly get a NULL delimited string list. Split it using, for example, this (don't forget UNICODE) and use c_str() with each entry.
EDIT about your modified code:
Why you drive path is A:\\ (escaped to A:\\\\)? Just one trailing backslash is needed so mydrives has to be declared as:
wchar_t mydrives[] = L"A:\\";
EDIT 2: there are more errors in your code so I'll post a reviewed version. There are more things I'd change but I'll point out just what doesn't actually work.
Function retVolSno to read volume serial number. Original version were almost right, in your modified version you perform useless character conversion. What you had to do was just to accept a wchar_t drive path.
Global variable mydrives. You actually don't need any global variable for that. It must be wchar_t and space before/after path are useless. One trailing backslash is needed. Line where you increment character value (++mydrives[0];) must be changed accordingly (index 0 instead of 1).
Check for drive availability. After if(DriveMask & 1) you did forget { then you won't print drive name but you'll perform GetVolumeInformation() even on unavailable drives (error 123). That's why indentation is important...
You're mixing UNICODE/NOT UNICODE and C/C++ stuff. I strongly suggest you pick one of them and you keep it (C or C++? UNICODE or NOT UNICODE?). For example you used C function printf() to print stuff and you have both std::string and wchar_t things.
Let's put everything together to have a working version. First the function to read serial number given drive path:
wstring getVolumeSerialNumber(const wchar_t* drivePath)
{
DWORD dwSerial;
wstringstream ss;
if (!GetVolumeInformation(drivePath, NULL, 0, &dwSerial, NULL, NULL, NULL, 0))
ss << L"Error: " << GetLastError();
else
ss << hex << dwSerial;
return ss.str();
}
It's almost the same as your original version, just changed to work with UNICODE characters. Then main function that cycles through available drives and print out their serial number:
int _tmain(int argc, _TCHAR* argv[])
{
wchar_t drive[] = L"A:\\";
ULONG driveMask = _getdrives();
if (driveMask == 0)
wcout << L"_getdrives() failed with failure code: " << GetLastError() << endl;
else
{
wcout << L"This machine has the following logical drives:" << endl;
while (driveMask)
{
if (driveMask & 1)
{
wcout << drive << endl;
wcout << getVolumeSerialNumber(drive) << endl;
}
++drive[0];
driveMask >>= 1;
}
}
wcin.ignore();
return 0;
}
From the documentation , the first parameters should be with trailing slash if drive letter is passed.
lpRootPathName [in, optional]
A pointer to a string that contains the root directory of the volume to be described.
If this parameter is NULL, the root of the current directory is used.
A trailing backslash is required.
For example, you specify \\MyServer\MyShare as \\MyServer\MyShare\, or the C drive as C:\

Resources