Input parametrs as HEX from command line - c++

I would like to print what the user inserts from the command line as HEX
when i declare my variable as: unsigned char myargv[] = {0x00,0xFF};
it works fine, i get: 11111111
but when i pass my parameters from command line i get different value
Example: myApp.exe FF
i get: 01100010
#include <iostream>
#include <string>
using namespace std;
void writeToScreen(unsigned char *data);
int main(int argc,unsigned char *argv[]){
if(argc != 2){
unsigned char myargv[] = {0x00,0xFF};
writeToScreen(&myargv[1]);
}else{
writeToScreen(argv[1]);
}
system("pause");
return 0;
}
void writeToScreen(unsigned char *data){
unsigned char dat;
dat =*(data);
for (unsigned int i=0;i<8;i++)
{
if (dat & 1)
cout<<"1";
else
cout<<"0";
dat>>=1;
}
cout<<endl;
}

You argument is FF. 'F' is 70 in ASCII, and 70 is 0x46 (0100 0110). You have "0110 0010" which is 0x46 written in reverse.
So first, you need to convert the argument (FF) into a number. Because currently, it's only a string. You can use strtol or std::stringstream (with std::hex) for that for instance.
With strtol:
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
void writeToScreen(char *data);
int main(int argc, char *argv[]){
writeToScreen(argv[1]);
return 0;
}
void writeToScreen(char *data){
unsigned char dat = strtol(data, NULL, 16);
for (unsigned int i=0;i<8;i++)
{
if (dat & 1)
cout<<"1";
else
cout<<"0";
dat>>=1;
}
cout<<endl;
}
Beware that the byte is still printed from LSB to MSB.

Another way to input hex parameters into a program as a command line parameter is with the help of Perl as below,
./main $(perl -e 'print "\xc8\xce"')
This in net effect, will send 2 bytes (0xC8 and 0xCE) of data in to the main program.

Related

Convert *argv[] (command line parameters) to unsigned char vector

In C++ I'm trying to convert command line *argv[] pointer (3 arguments) to vector of unsigned chars i.e. mytest 148 64 127
I got a vector:
vector<unsigned char> msg;
Vector includes 3 unsigned chars : msg = {0, 0, 0}
When I trying to convert in this way,
unsigned char c1 = *argv[1];
unsigned char c2 = *argv[2];
unsigned char c3 = *argv[3];
msg = {c1, c2, c3}
I get only first character of these chars.
i.e.
In command line I enter : mytest 148 64 127
I get : 1, 6 and 1
I recommend creating a vector of strings:
#include <iostream>
#include <vector>
int
main(int argc, char *argv[]) {
std::vector<std::string> args;
for (int i = 1; i < argc; i++) {
args.push_back({ argv[i] });
}
for (auto a: args) {
std::cout << a << std::endl;
}
return 0;
}
Simplest is convert to using strings.
vector<string> msg;
If you really want unsigned chars, then you will need to do something like:
vector<vector <unsigned char>> msg;
Rather than copy the characters you can save pointers to argv by doing
vector<unsigned char *> msg;
msg.push_back(reinterpret_cast<unsigned char *>(argv[0]));
You are saving only the 1st char of each argument string into your vector.
unsigned char c1 = *argv[1];
Is the same as doing:
const char *str = argv[1];
unsigned char c1 = str[0]; // <-- 1st char only!
For what you are attempting, you need to instead parse each argument string as-is into the numeric value it represents, so that the argument strings "148" "64" "127" yield the integers 148 64 127. You can use std::stoi() or std::stol() for that, eg:
#include <vector>
#include <string>
//#include <cstdlib>
//#include <limits>
/*
static const int min_uc = std::numeric_limits<unsigned char>::min();
static const int max_uc = std::numeric_limits<unsigned char>::max();
*/
int main(int argc, char* argv[])
{
if (argc < 2)
{
// no arguments given, do something...
return 0;
}
std::vector<unsigned char> msg;
msg.reserve(argc-1);
for (int i = 1; i < argc; ++i)
{
int i = std::stoi(argv[i], nullptr, 0);
//int i = std::strtol(argv[i], nullptr, 0);
if ((i < 0) || (i > 255))
//if ((i < min_uc) || (i > max_uc))
{
// bad input, do something...
return 0;
}
msg.push_back(static_cast<unsigned char>(i));
}
// use msg as needed...
...
}

OS X move terminal caret with arrow keys

I made a simple C programme that demonstrates the issue. Here it is.
#include <stdio.h>
int main(int argc, const char * argv[]) {
char buffer[128];
memset(buffer, 0, sizeof(buffer));
printf("Type data:\n");
scanf("%126s", buffer);
printf("%s\n", buffer);
getchar();
return 0;
}
The problem is that when the application is waiting for user input with scanf() and user user wants to edit line he typed, and to do move caret with arrows, the caret is not moving but new ugly input is inserted.
For some reason it does not handle the keys in a way I expect. I'm not able to go to the previous typed line with the up key, as well.
Obviously I should deliberately enable this behaviour. Could you advice, how can I do that?
Use readline(). Here's a simple example:
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <ctype.h>
#define MAX_LINE_LEN 80
int main() {
char *line_buffer;
int n, i;
while (1) {
line_buffer = readline("Say something: ");
if (!line_buffer) break;
for (i=0; line_buffer[i]; i++) {
line_buffer[i] = toupper(line_buffer[i]);
}
printf("YOU SAID: %s\n",line_buffer);
}
putchar('\n');
return 0;
}
/* (Compile with cc foo.c -lreadline -o foo) */

Hex value comparison and save to file C++

I am reading H.264 bitstream as Hex file in c++. I want to insert some string whenever some certain condition met.Like in the attached image if hex value of 00 00 00 01 occurs anywhere in the file i want to add some string like ABC before 00 00 00 01 in the file and save this as a new file. Write now my approach is to read h.264 file as hex. convert it into string and make a string comparison. if there is a way i can do a straight hex comparison? Here is my current code
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <iomanip>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
unsigned char x;
string s1,s2,s3;
s2="Mushahid Hussain";
s3="0000000141";
std::ifstream input("d:\\Jm\\videos\\trying2.264", std::ios::binary);
input >> std::noskipws;
while (input >> x) {
long constant = 0x0000000168;
std::ostringstream buffer;
buffer << std::hex << std::setw(2) << std::setfill('0')
<< (int)x;
s1=buffer.str();
if (s1.find(s1) != std::string::npos) {
cout<<"hello";
s1+=s2;
}
std::ofstream outfile;
outfile.open("d:\\Jm\\bin\\trying5.264", std::ios_base::app);
outfile << s1;
}
return 0;
}
Edit 1
As answered by Tommylee2k i am able to append string . But problem is that at the end of file hex CD value is appending like shown in the attached image.
perhaps a better approach is to read the file binary into a memory buffer, and find the memcmp() instead.
When you found your pattern, you write the block ahead of the match, then your "ABC"-string, and continue searching the rest of the file
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <malloc.h>
char pattern[4]= { 0x00,0x00,0x01,0x67 };
char *memfind(char *s, int len, char *p, int plen) {
int n=0;
char *pos = s;
while ((pos-s)<(len-plen)) {
while ( *(pos+n) == *(p+n) && n<=plen) n++;
if (n==plen)
return pos;
pos++;n=0;
}
return NULL;
}
int main() {
FILE *in = fopen("in.vid", "r+");
FILE *out = fopen("out.vid", "wb");
// get Filesize
size_t size = 0;
fseek(in, 0L, SEEK_END);
size = ftell(in);
// read whole file in
char *buffer = malloc(size);
fseek (in, 0L, SEEK_SET);
fread (buffer, size, 1, in);
char *currentPos = buffer;
char *found;
if (buffer) {
while (1) {
found = memfind(currentPos, size-(currentPos-buffer), pattern, sizeof(pattern));
if (found==NULL) break;
fwrite(currentPos, 1, (size_t) (found-currentPos), out);
fwrite("ABC", sizeof("ABC"), 1, out);
fwrite(pattern, sizeof(pattern),1,out);
currentPos=found+4;
}
fwrite (currentPos, 1, (size_t) size - (currentPos-buffer), out);
free(buffer);
}
fclose (in);
fclose (out);
return 0;
}

Retrieving Char digits from a text file and appending them into a String?

I am trying to get some chars read from a file and into a string. For example #2%4$$3. My program will take out 243 from the text file, now I need it to be in a string so I can convert it to two hundred and 43 and given to an INT var.
Any help would be Superbly appreciated! :)
Thanks,
Brian
Try this program
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char file_buff[1024]="!#25#3$#4";
char num_buff[1024];
int len,i,k;
// open file and read the entire contents specied as per the size
FILE *f = fopen("file.txt", "r");
fgets(file_buff, 1024, f);
printf("String read: %s\n", file_buff);
fclose(f);
len=strlen(file_buff);
// parse the buffer for digits and store it in a buffer
for(i=0,k=0;i<len;i++)
{
if((file_buff[i] >= 0x30) && (file_buff[i] <= 0x39))
{
num_buff[k]=file_buff[i];
k++;
}
}
num_buff[k]='\0';
printf("%s",num_buff);
return 0;
}

Concatenating Two FASTA Files in C++

I have two FASTA files:
file1.fasta
>foo
ATCGGGG
>bar
CCCCCC
file2.fasta
>qux
ATCGGAAA
What I want to do now is to concatenating them into one file that results:
>foo
ATCGGGG
>bar
CCCCCC
>qux
ATCGGAAA
Thus preserving the name of each sequence that started with ">".
Currently my code below replace that name with index, namely:
>0
ATCGGGG
>1
CCCCCC
>0
ATCGGAAA
What's the right way to modify my code below?
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include<stdio.h>
#include<string>
using namespace std;
#define MAX_LINE_SIZE 1024
int mk_joint_file(char *ctrlFile, char *tgtFile, char *outFile){
char s[MAX_LINE_SIZE];
FILE *ofp = fopen(outFile,"w");
FILE *cfp = fopen(ctrlFile,"r");
FILE *tfp = fopen(tgtFile,"r");
// char *p;
int flg=false;
int line=0;
while(fgets(s,MAX_LINE_SIZE,cfp) != NULL){
if(s[0]=='>'){
flg=true;
fprintf(ofp,">%d\n",line);
line++;
}else{
if(flg==true){
fprintf(ofp,"%s",s);
}
flg=false;
}
}
flg=false;
line=0;
while(fgets(s,MAX_LINE_SIZE,tfp) != NULL){
if(s[0]=='>'){
flg=true;
fprintf(ofp,">%d\n",line);
line++;
}else{
if(flg==true)
fprintf(ofp,"%s",s);
flg=false;
}
}
fclose(cfp);
fclose(tfp);
fclose(ofp);
return(0);
}
int main(int argc, char **argv)
{
string ifname_control = argv[1];
string ifname_target = argv[2];
string ofname = "newjoin.txt";
mk_joint_file((char *)ifname_control.c_str(), (char *)ifname_target.c_str(), (char *)ofname.c_str());
}
Is it any harder than just changing these lines
fprintf(ofp,">%d\n",line);
to
// TODO check fgets() handling of EOL - may not need the \n
fprintf(ofp, %s\n", s);
just change line 29 and 40 to
fprintf(ofp,"%s",s);