I'm new to C and trying to figure out arrays and command line arguments. I have:
int main(int argc, int **argv) {
int vals[8];
for(int i = 0;i < 8;i = i + 1) {
vals[i] = atoi(argv[i]);
printf("%d", vals[i]);
}
}
I call it with ./file 1 2 3 4 5 6 7 8 and I would expect it to spit out 12345678, but instead, it spits out 01234567 which to me says that it's just printing the array positions. How do I get to actually print/access the value of vals[i], and/or make sure that the command line value is actually being properly assigned?
Thanks in advance.
Start with argv[1] In order to exclude the first element of argv which is the program name. A simple way to do this is to increment argv at the top of the program.
int main(int argc, char **argv) {
argv++; /* argv[0] is the program name */
int vals[8];
for(int i = 0;i < 8;i = i + 1) {
vals[i] = atoi(argv[i]);
printf("%d", vals[i]);
}
}
On a side note, you should check the value of argc prior to accessing elements at index i in argv
argv [0] is the name of the program.
The arguments start at 1. You should also get in the habit of using argc in loops.
int main(int argc, int *argv[])
{
for(int i = 1 ; i < argc ; ++ i )
{
int val = atoi(argv[i]);
printf("%d", val);
}
}
Related
I'm new to C and I'm trying to convert all strings that the user typed in the command line to integers and store them into a new array, so that I can use it later. But I get a "segmentation fault (core dumped)" issue.
Can someone check with my code and point out the error(s)?
int main(int argc, char *argv[]) {
long int conv[argc - 1];
for (int i = 0; i < argc; i++) {
conv[i] = strtol(argv[i + 1], NULL, 10);
}
If I run this program like, ./main 1 2 3, then {1, 2, 3} should be stored in the new array of integers.
The arguments you pass in to your program are stored in argv[1] to argv[argc-1], so you'd want to change the for loop to something like this: for (int i = 1; ...) {...}. Also, with strtol(argv[i+1],NULL,10);, when i==argc-1, you're trying to access the array out of bounds.
Here's a modified version of your code with the fixes applied:
int main(int argc, char *argv[]){
long int conv[argc-1];
for(int i=1;i<argc;i++){
conv[i-1]=strtol(argv[i],NULL,10);
}
}
Your loop attempts to access an "out-of-bounds" array element on its last iteration: if you run the program with, say, ./main 1 2 3, then argc will be 4 and the last argument will be in argv[3]. However, when the loop index, i is 3, the loop will still run and you will be attempting to read argv[i + i] – which is argv[4] and thus beyond the end of the array.
You can simplify your loop (or, at least, rewrite it) to use the actual i value for the argv index and i - 1 for the conv index; but, of course, you then need to start the loop with i = 1:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
long int conv[argc - 1];
for (int i = 1; i < argc; i++) {
conv[i - 1] = strtol(argv[i], NULL, 10);
}
// Data check:
for (int j = 0; j < argc - 1; ++j) {
printf("Data %d is %ld\n", j, conv[j]);
}
return 0;
}
In line int d = atoi(argv[2]); there seems to be something wrong. "null pointer passed as argument 1..."
What can I do?
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, string argv[])
{
int num;
int i = 1;
int j = 1;
int board [i][j];
// 2nd CL argument is size of grid.
if (argc != 2)
{
return false;
}
int d = atoi(argv[2]);
if (d <= 0)
{
return false;
}
// setting up board.
// number of tiles needed.
num = d * d - 1;
// iterating over columns and rows
for (i = 0; i <= d; i++)
{
for (j = 0; j <= d; j++)
{
// set values.
board[i][j] = num;
num --;
}
printf ("%d", board[i][j]); // TESTING.
printf ("\n");
}
// if even swap 1 & 2. Don't display 1.
}
argv[0] holds the name of the command used to start your program. If you expect two command line arguments, check argc == 3 and read the command line arguments from argv[1] and argv[2].
You have a multiple issues with your program
1) string is not a standard type in C.
2) false is not a standard constant in C98.
Standard C (since C99) provides a boolean type, called _Bool. By including the header stdbool.h one can use the more intuitive name bool and the constants true and false.
3) Your board has a fixed size 1x1 board[1][1]:
int i = 1;
int j = 1;
int board [i][j];
Fix this otherwise your program will smash memory.
4) You need 2 arguments for your board. Arguments start on position argv[1] and argv[2] in argv[] Since first argv[0] is name of the program you need argc = 3.
I am trying to create a simplified version of the Rummy card game. I need to parse in the card abbreviations for example SA is Spades Ace. DT is Diamond 10 etc. I know there is an easier way to do this but that's how my assignment wants it done.
The sample execution would look like
rummy 3 S2 H9 C4... etc. include all 52 cards.
The number in argv[1] is the players in the game. How am I supposed to take the cards starting after the number and put them into an array?
My code so far
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int players = *argv[1];
char deck[52];
int i, j, pid, cid;
if (players > '5' || players < '3')
{
printf("%c is not the allowed number of players, min is 3 and max is 5\n",*argv[1]);
exit(0);
}
}
Quick and dirty demonstration:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int players = atoi(argv[1]);
char deck[52][3];
int i, j, pid, cid;
if (players > 5 || players < 3)
{
printf("%d is not the allowed number of players, min is 3 and max is 5\n", players);
exit(0);
}
for (i = 0; i < argc - 2; i++)
{
strcpy(deck[i], argv[i+2]);
}
for (i = 0; i < argc - 2; i++)
{
printf("%s\n", deck[i]);
}
}
Absolultely no sanity checks are done concerning the input. It's just for demonstration.
Your int argc is the count of arguments. So you can indeed manually load all of these cards into an array if you so choose.
Assuming you execute the program like this:
example.exe rummy 3 S1 S2 S3 S4 A1 A2 A3 A4
You could then read the cards into an array like this (assuming that "rummy" is game type and "3" is some other control variable, you need to make sure of this)
int main(int argc, char *argv[])
{
char game[10] = argv[0];
int players = atoi(argv[1]);
char deck[52][3]; // an array of strings max lenght 3 (2 characters + required '\0' terminator
for (int i = 0; i < argc - 2; i++) // argc - 2 because we're accessing at i+2 so the last iteration will essentially access the last element
{
strcpy(deck[i], argv[i+2]); // copy into actual array
}
return 0;
}
Now you got your cards in an array of char arrays called deck. Take note that this is completly only a sample and that it is not recommended for direct use. In an eventual program you must have sanity checks and validation against all possible cases (too many args, too little args, wrong args, etc.
All arguments passed on command line are stored in argv array. argv[0] is always the name of the program and next come your arguments if any (as null-terminated strings).
So assuming you have called this as:
rummy 3 S2 H9 C4
this is what argv contains:
argv[0] = "rummy"
argv[1] = "3"
argv[2] = "S2"
argv[3] = "H9"
argv[4] = "C4"
Inserting these into array is simple:
char args[5][10];
strncpy(args[0], argv[0], 10);
Hello I have a program the receiving parameters from the user. The transmission is performed using pointers.
The code later does not use pointers which creates a problem with what is received. I would be happy if you help me fix the code that will work.
code -
#include <stdlib.h>
#include<string.h>
void order(int n,char argv[99]);
int main(int argc, char** argv)
{
int i,n;
n = argc;
order(n,*argv);
}
void order(int n,char argv[99])
{
int i,j;
char temp;
for(i=1; i < n; i++)
{
for(j = 0 ; j < n - 1; j++)
{
if(argv[j] > argv[j+1])
{
temp=argv[j];
argv[j]=argv[j+1];
argv[j+1]=temp;
}
}
}
system("PAUSE");
for (i = 0; i < n ; i++)
{
printf("%c",argv[i]);
}
}
It appears you are confused about argc and argv.
int argc contains the number of command-line arguments passed to your program, char **argv is an array (null-pointer terminated even) of strings (null-byte terminated character arrays) containing these arguments. This is at odds with your program:
1. There is no reason to limit the length of any one command-line argument to 99 characters.
2. You pass only the first (zero-indexed) command-line argument to order(). This will usually be the name of the program.
3. You then use argc in order(). However, argc is not the length of the first command-line argument. That would be strlen(argv[0]).
This C program I am making reads a set of chars from the command line and stores them using an array (argv[]) like so
main (int argc, char *argv[]) {
int temp;
/*prevents no arguments*/
if (argc==1){
printf("Usage;\t[0 < integers < 9] [operators]\n");
exit(0);
}
int i;
for (i = 0 ; i<argc; i++){
temp = argv[i] - '0';
printf("this is char %d ; %d\n",i, temp);
}
}
But all I get after running it in the command line like so;
program 2 4 1 - +
is random garbage
this is char 0 ; -4195956
this is char 1 ; -4195950
this is char 2 ; -4195948
this is char 3 ; -4195946
this is char 4 ; -4195944
this is char 5 ; -4195942
Is there something wrong with the way I'm casting temp? Or am I just getting the idea of pointers (in *argv[]) wrong?
argv[i] - is just a pointer to C string; you need first element:
temp = argv[i][0] - '0';
char *argv[]
argv is an array of pointers to char. So argv[X] is a pointer to char (for suitable X). So argv[X] - some_integral_value is pointer arithmetic, and returns a pointer (if that subtraction is defined).
To access the first element, you need argv[X][0].
Please note that argv[0] is not the first argument but (usually) the program name. Arguments start at argv[1].
Each element of argv is a string of characters, not a specific character. argv is a multi-dimensional array, and you're only indexing the first dimension. You need to take the first (zeroth) element of each nested array:
temp = argv[i][0] - '0';
For numbers, you can use function atoi(str) as following:
temp = atoi(argv[i]);
Code:
for (i = 0 ; i<argc; i++){
if (argv[i][0] < '0' || argv[i][0] > '9')
printf("Operator = %s\n", argv[i]);
else {
temp = atoi(argv[i]);
printf("this is char %d ; %d\n",i, temp);
}
}
You can use separate char array to store operators..