Read raw bytes in argv[] - c

I was wondering if there was a way to read bytes (like this: \x00\x01\x02) from the command line in C.
For example:
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("%s", argv[1]);
return 0;
}
user#UbuntuServer: ~/Code# gcc Program.c -o Program
user#UbuntuServer: ~/Code# ./Program "\x48\x69"
Hiuser#UbuntuServer: ~/Code# ./Program "\x48\x69\x0a"
Hi
user#UbuntuServer: ~/Code#
Thanks!

Unless you use a library to parse regex strings like that, you'll need to parse the hex manually. Check out this answer (which has slightly different syntax but a similar function):
Hexadecimal string to byte array in C

I would go for something like this:
int main(int argc, char **argv)
{
char *buf = malloc(strlen(argv[1]) / 4 + 1);
size_t i = 0;
for (char *tok = strtok(argv[1], "\\x"); tok; tok = strtok(NULL, "\\x"))
{
sscanf(tok, "%02hhx", buf + i);
i++;
}
buf[i] = '\0';
printf("%s", buf);
free(buf);
return 0;
}

I found the HEX to ASCII conversion functions on this thread, and modified it to suit my situation.
#include <stdio.h>
#include <string.h>
int hexToInt(char c) {
int first = c / 16 - 3;
int second = c % 16;
int result = first * 10 + second;
if(result > 9) {
result--;
}
return result;
}
int hexToASCII(char c, char d) {
int high = hexToInt(c) * 16;
int low = hexToInt(d);
return high + low;
}
int main(int argc, char *argv[]) {
char* hexString = argv[1];
char buf = 0;
for(int i = 0; i < strlen(hexString); i++) {
if(i % 2 != 0) {
printf("%c", hexToASCII(buf, hexString[i]));
} else {
buf = hexString[i];
}
}
return 0;
}

Related

generating main arguments without the parameter

In C programming language, is it possible to access int argc or char **argv without using the parameters? I know some of you might ask why this is needed, just for research purposes.
Is it possible to generate the cmd line arguments without using the main parameter variables ? For example, to illustrate some pseudo code, that i have in mind,
LPTSTR cmd = GetCommandLine();
splitted = cmd.split(" ") //split from spaces
char **someArgv.pushForEach Splitted, length++
and you'd have a someArgv with the parameters and length as argc, this'd really help to know if possible to illustrate.
If OP already has the command as a string, then:
Form a copy of the string
Parse it for argument count
Allocate for argv[]
Parse & tokenize copy for each argv[]
Call main()
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
// Not standard, but commonly available
char *strdup(const char *s);
// Return length of token and adjust offset to the next one
// Adjust as needed
// Presently only ' ' are used to separate
// More advanced would have escape characters, other white-space, etc.
size_t tokenize(const char *s, size_t *offset) {
// find following space
size_t len = strcspn(s + *offset, " ");
*offset += len;
// find first non-space
*offset += strspn(s + *offset, " ");
return len;
}
int call_main(const char *cmd) {
char *cmd2 = strdup(cmd);
cmd2 += strspn(cmd2, " "); // skip leading spaces
size_t offset = 0;
int argc = 0;
while (tokenize(cmd2, &offset) > 0) {
argc++;
}
char **argv = malloc(sizeof *argv * ((unsigned)argc + 1u));
offset = 0;
for (int a = 0; a < argc; a++) {
argv[a] = &cmd2[offset];
size_t len = tokenize(cmd2, &offset);
argv[a][len] = '\0';
}
argv[argc] = NULL;
int retval = 0;
#if 0
retval = main(argc, argv);
#else
printf("argc:%d argv:", argc);
for (int a = 0; a < argc; a++) {
printf("%p \"%s\", ", argv[a], argv[a]);
}
printf("%p\n", argv[argc]);
#endif
free(cmd2);
free(argv);
return retval;
}
Sample
int main() {
call_main(" name 123 abc 456 ");
}
argc:4 argv:0x800062322 "name", 0x800062327 "123", 0x80006232c "abc", 0x800062331 "456", 0x0
Pedantic: The strings provided to main() should be modifiable. Avoid code like
argv[1] = "Hello";
....
main(argc, argv);
#include <stdio.h>
int main(int argc, char *argv[]);
int callMain(void)
{
char *argv[4];
argv[0] = "binary";
argv[1] = "param1";
argv[2] = "param2";
argv[3] = NULL;
return main(3, argv);
}
int main(int argc, char *argv[])
{
if (argc <= 1)
{
return callMain();
}
printf("ARGC: %u\n", argc);
int i;
for (i = 0; i < argc; i++)
printf("ARG: %u - %s\n", i, argv[i]);
return 0;
}

How do I concatenate strings via command line arguments separated by a +?

What I want to do is write arguments in the command line separated by a + and concatenate the arguments into a single string
eg:
./concat Wow + this + is + cool
Wow this is cool
I looked up a question for this sort of topic before but that involved concatenating only the first character of each argument and not the entire arguments. And it didn't ignore the separator
This is what I have
void concat(char **argv, int argc, char *string)
{
size_t i = 0;
for(int j=1; j<argc; j++)
{
string[i++] = *argv[j];
if(j+1 != argc)
{
string[i++] = ',';
string[i++] = ' ';
}
}
string[i] = '\0';
}
And this is what I'm doing in main to call this function
int main(int argc, char *argv[])
{
int allnum=0;
char string[1000];
concat(argv, argc, string);
printf("%s\n", string);
}
Using the strcpy or strcat in string.h is more simple to concatenate string.
For example:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
char * s = malloc (2 * argc *sizeof (char));
if (argc < 2)
exit(-1);
for(int i = 1; i < argc; i += 2) {
strcat(s, argv[i]);
strcat(s, " ");
}
printf("%s\n", s);
return 0;
}

Tail -c linux command implementation in C

I need to write a tail in C language, where the input stream will be the argument in the console. The function should cut n characters from the input data. The command calling the program should be "echo" an example text "| ./a.out 4" - that is, the last 4 characters of the given input will be printed.
Unfortunately, my function does not print anything to me.
Thanks in advance. If there are any other, smarter solutions then I am open to suggestions.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define BUFFSIZE 1024
#define MAXLINES 100
char* tailFunction (const char* argv[])
{
char* buf, data;
int n = 0, i =0;
buf = malloc(sizeof(char) * MAXLINES);
n = atoi(argv[0]+1);
while (data != EOF)
{
data = getc(stdin);
buf[i] = data;
i++;
}
int x = strlen(buf) - n;
for ( ; x < strlen(buf) ; x++)
{
printf("%c", buf[x]);
}
free(buf);
return 0;
}
int main(int argc, const char *argv[])
{
if (argc !=2)
{
return -1;
}
if (argv < MAXLINES)
{
tailFunction(argv);
return 0;
}
else return -1;
}

How do I separate a string into different chars

Also after I want to add a key to each letter like 'a' + 1 = 'b'. So I want to take a string for instance "Hello" then do
char 1 = H + 1;
char 2 = E + 1;
etc.
printf("%c" + "%c" + "%c" + "%c" + "%c", 1 , 2 , 3 , 4 , 5);
also I would love for this to be automated because IDK how long the string might be and what key theyre are going to use.
You can do something like this:
#include<stdio.h>
#include<string.h>
int main()
{
char text[] = "Hello";
int i=0;
int size= strlen(text);
for(i=0;i<size;i++)
{
//something here
}
return 0;
}
Assuming the string is mutable, you can update it in place:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void update(char *s, int delta)
{
while(*s)
*s++ += delta;
}
int main(int argc, char **argv)
{
char str[] = "Hello";
update(str, 1);
printf("Encoded: \"%s\"\n", str);
update(str, -1);
printf("Decoded: \"%s\"\n", str);
return 0;
}
If the string is immutable, you will need to make a copy of it, and update the copy.
int main(int argc, char **argv)
{
const char str[] = "Hello";
char *copy = strdup(str);
update(copy, 1);
printf("Encoded: \"%s\"\n", copy);
update(copy, -1);
printf("Decoded: \"%s\"\n", copy);
free(copy);
return 0;
}
You should read about dynamic arrays in C.
#include <stdio.h>
#include <string.h>
char* code(const char* message)
{
int i = 0;
char* coded;
for (i = 0; i < strlen(message); i++)
{
coded[i] = message[i] - 3;
}
return coded;
}
char* decode(const char* message)
{
int i = 0;
char* coded;
for (i = 0; i < strlen(message); i++)
{
coded[i] = message[i] + 3;
}
return coded;
}
int main()
{
// This is dynamic allocated chars array
char* message = "Hello World!";
message = code(message);
printf("%s\n", message);
message = decode(message);
printf("%s\n", message);
}

Getting a segmentation fault in my code

My code is giving me a segmentation fault. I'm 99% sure the fault is stemming from my lousy code construction.
#include <stdio.h>
#include <assert.h>
#include <string.h>
int decToBit(unsigned int I, char *str){
str = "";
int currentVal = I;
do{
if(I%2 == 0)
strcat(str,"0");
else
strcat(str,"1");
} while(currentVal > 0);
return(0);
}
You need to make sure that there is enough space in str to add the extra characters:
char myStr[200];
myStr[0] = '\0'; // make sure you start with a "zero length" string.
strcpy(myStr, str);
and then use myStr where you were using str.
As it is, the statement
str="";
points str to a const char* - that is a string you can read but not write.
Incidentally the call signature for main is
int main(int argc, char *argv[])
in other words, you need a pointer to a pointer to char. If I am not mistaken, you would like to do the following (a bit of mind reading here):
Every odd argument gets a 1 added; every even argument gets a 0 added.
If my mind reading trick worked, then you might want to try this:
#include <stdio.h>
#include <string.h>
int main(int argc, char * argv[]) {
char temp[200];
temp[0] = '\0';
int ii;
for(ii = 0; ii < argc; ii++) {
strncpy(temp, argv[ii], 200); // safe copy
if(ii%2==0) {
strcat(temp, "0");
}
else {
strcat(temp, "1");
}
printf("%s\n", temp);
}
}
edit just realized you edited the question and now your purpose is much clearer.
Modified your function a bit:
int decToBit(unsigned int I, char *str){
str[0] = '\0';
char *digit;
do
{
digit = "1";
if ( I%2 == 0) digit = "0";
strcat(str, digit);
I>>=1;
} while (I != 0);
return(0);
}
It seems to work...
In do-while loop you should increment the value of currentVal. Otherwise it will be an infinity loop and you will end up with Segmentation fault.
Initialize str[0] properly.
Divide I by 2 each loop.
But then the string will be in a little endian order. Doubt that was intended?
int decToBit(unsigned int I, char *str) {
str[0] = '\0';
do {
if (I%2 == 0)
strcat(str,"0");
else
strcat(str,"1");
I /= 2;
} while(I > 0);
return(0);
}
// call example
char buf[sizeof(unsigned)*CHAR_BIT + 1];
decToBit(1234567u, buf);
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <assert.h>
char *decToBit(unsigned int I, char *str){
int bit_size = CHAR_BIT * sizeof(I);
str += bit_size;
*str = 0;
do{
*--str = "01"[I & 1];
}while(I>>=1);
return str;
}
int main(){
char bits[33];
printf("%s\n", decToBit(0, bits));
printf("%s\n", decToBit(-1, bits));
printf("%s\n", decToBit(5, bits));
return 0;
}

Resources