int main(int argc, char **argv){
char Q[MAXCHAR];
Q=argv[k+1];}
Q is an array while argv[k+1] is a pointer.
How can I get the content of argv[k+1] into Q?
You can use snprintf
snprintf(Q, MAXCHAR, "%s", argv[k]);
(edited : first version recommended strncpy).
You can't directly assign Q = argv[k+1]. For an array (Q[MAXCHAR]), arrayname (Q) is the base address. The base address of an array can't be changed.
Assuming k = 0, you can use any of the following to get the argv[1] data into Q.
memmove(Q, argv[1], strlen(argv[1]) + 1);
or
snprintf(Q, strlen(argv[1]) + 1, "%s", argv[1]);
or
strncpy(Q, argv[1], strlen(argv[1]) + 1);
or
memcpy(Q, argv[1], strlen(argv[1]) + 1);
or
sprintf(Q, "%s", argv[1]);
or
strcpy(Q, argv[1]);
Here is the program and it's output using memmove:
#include <stdio.h>
#include <string.h>
#define MAXCHAR 20
int main(int argc, char **argv)
{
if (argc < 2) {
puts("Not enough arguments");
return -1;
}
char Q[MAXCHAR] = {0};
memmove(Q, argv[1], strlen(argv[1]) + 1);
puts(Q);
return 0;
}
Output:
me#linux:~$ ./a.out stackexchange
stackexchange
Related
char* argv[MAXARGS];
char* buf2=malloc(MAXLINE * sizeof(char));
strcpy(buf2, buf); //buf is string with some words
char* ptr = strtok(buf2, " ");
argv[0]=ptr;
strcpy(argv[0], ptr);
free(buf2);
Like above, I want to copy value of ptr to argv[0] but I can't use strcpy(argv[0],ptr) directly because accessing argv[0] without argv[0]=ptr cause segmentation fault. So I made code like above but then, after I free buf2, argv[0] becomes null. How can I copy ptr to argv without using =ptr in advance?
Code:
#define MAXARGS 128
#define MAXLINE 256
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
void eval(char* cmdline);
int parseline(char* buf, char** argv);
int main()
{
char cmdline[MAXLINE]; /* Command line */
char* ret;
while (1) {
/* Read */
printf("mini> ");
ret = fgets(cmdline, MAXLINE, stdin);
if (feof(stdin) || ret == NULL)
exit(0);
/* Evaluate */
eval(cmdline);
}
}
void eval(char* cmdline)
{
char** argv=malloc(MAXARGS*sizeof(char)); /* Argument list execve() */
char buf[MAXLINE]; /* Holds modified command line */
int bg; /* Should the job run in bg or fg? */
pid_t pid; /* Process id */
strcpy(buf, cmdline);
bg = parseline(buf, argv);
free(argv);
}
int parseline(char* buf, char** argv)
{
int argc; /* Number of args */
int bg; /* Background job? */
char* buf2=malloc(MAXLINE * sizeof(char));
while (*buf && (*buf == ' '))
buf++;
buf[strlen(buf) - 1] = ' ';/* Replace trailing '\n' with space */
strcpy(buf2, buf);
/* Build the argv list */
argc = 0;
char* ptr = strtok(buf2, " ");
printf("ptr: %s\n", ptr);
while (ptr != NULL) {
//argv[argc]=ptr;
strcpy(argv[argc++], ptr);
ptr = strtok(NULL, " ");
}
argv[argc] = NULL;
printf("0: %s\n", argv[0]);
/* Ignore blank line */
if (argc == 0)
return 1;
/* Should the job run in the background? */
if ((bg = (*argv[argc - 1] == '&')) != 0)
argv[--argc] = NULL;
free(buf2);
printf("0: %s\n", argv[0]);
if(argv[1]!=NULL)
printf("1: %s\n", argv[1]);
return bg;
}
Many errors in your code - I will not check everything only your issue.
Wrong allocation:
char** argv=malloc(MAXARGS*sizeof(char));
You need to allocate space for char pointers - you allocate for char. It is better to use objects instead of types.
char **argv=malloc(MAXARGS * sizeof(*argv));
Now you have allocated the memory for pointers - but not for char arrays to accommodate the strings. To directly copy to argv[n] you need to allocate this memory:
argv[n] = malloc(sizeof(**argv) * (strlen(ptr)+1));
if(argv[n]) strcpy(argv[n], ptr);
In your code you never check the result of malloc - you need to do it after every allocation/reallocation
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char *ptr;
char temp[20];
if (strlen(argv[1]) < strlen(argv[2]))
{
strcpy(temp,argv[1]);
strcpy(argv[1],argv[2]);
strcpy(argv[2],temp);
}
ptr = strstr(argv[1],argv[2]);
if (ptr == NULL)
printf("Non-inclusive");
else
printf("%s is part of %s", argv[2], argv[1]);
return 0;
}
When I enter "abc abcd",
I want to get "abc is part of abcd" as a result,
but real result is "abc is part of abcdabc"
The length of each string in the argv array is fixed. So when you attempt to swap the contents of argv[1] and argv[2] when their sizes are different you write past the end of the shorter one. This triggers undefined behavior.
Better to use separate char * variables, one pointing the longer string and one pointer to the shorter.
int main(int argc, char *argv[])
{
char *ptr;
char *s_short, *s_long;
if (strlen(argv[1]) < strlen(argv[2])) {
s_short = argv[1];
s_long = argv[2];
} else {
s_short = argv[2];
s_long = argv[1];
}
ptr = strstr(s_long,s_short);
if (ptr == NULL)
printf("Non-inclusive");
else
printf("%s is part of %s", s_short, s_long);
return 0;
}
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;
}
I am new in programming and currently learning on C. Could you please assist me on solving below's case?
An example of this will be if a user is entering "cbamike", I would like to separate it into two strings: cba and mike.
I tried below's code but it doesnt work:
#include <stdio.h>;
int main (int argc, string argv[])
{
char* input[50] = argv[1];
char* first[10];
char* second[10];
sprintf(first, "%c %c %c", input[0], input[1], input[2]);
sprintf(second, "%c %c %c %c", input[3], input[4], input[5], inpput[6]);
printf("%s\n", input);
printf("%s\n", first);
printf("%s\n", second);
}
There is no string in c,
you can use strncpy to get first few characters as aswered there: Strings in c, how to get subString
int main (int argc, string argv[])
{
char* input = argv[1];
char first[4];
char second[5];
strncpy(first, input, 3);
strncpy(second, input + 3, 4);
first[3] = second[4] = '\0';
}
#include <stdio.h>
#include <string.h>
int main (int argc, char* argv[])
{
if(argc >= 2)
{
const int len = strlen(argv[1]) / 2;
char str1[len + 2], str2[len + 2];
snprintf(str1, len + 1, "%s", argv[1]);
snprintf(str2, len + 2, "%s", argv[1] + len);
printf("1: %s\n2: %s\n", str1, str2);
}
return 0;
}
This is a very simple question and mistake that I'm making but can anyone explain how I could use sprintf to add to a argv value?
On the command line, I have a file name say data.new.txt (but in my scenario I don't know the name of the file) how can I write to a new file that is named data.new.output.txt
I don't want to create a new file with a different name or update the new file, because this is program will output about 100+ files and that's the specification.
int main(int argc, char * argv[]){
char buffer[100];
sprintf(buffer, "%s.decoded", argv[1]);
printf("%s\n", buffer);
}
Cheers!
Here is a C99 (it uses snprintf()) program for you. Have fun!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *buildname(const char *old, const char *newpart) {
char *dot;
char *buf = NULL;
dot = strrchr(old, '.');
if (dot) {
size_t len;
len = snprintf(NULL, 0, "%.*s%s.%s",
(int)(dot - old) + 1, old, newpart, dot + 1);
buf = malloc(len + 1);
if (buf) {
snprintf(buf, len + 1, "%.*s%s.%s",
(int)(dot - old) + 1, old, newpart, dot + 1);
}
}
return buf;
}
int main(void) {
char *p, *q;
q = "data.new.txt";
p = buildname(q, "output");
if (p) printf("%s ==> %s\n", q, p);
else printf("%s ==> (no dots)\n", q);
free(p);
q = "rrrrrrrrrrrr";
p = buildname(q, "aaa");
if (p) printf("%s ==> %s\n", q, p);
else printf("%s ==> (no dots)\n", q);
free(p);
q = "a.b.c.d.e.f.g.h.i.j.k.l";
p = buildname(q, "Q.Q");
if (p) printf("%s ==> %s\n", q, p);
else printf("%s ==> (no dots)\n", q);
free(p);
return 0;
}