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]).
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;
}
i am tring to read in a series of network addresses similar to
168.12.110.25
64.113.134.35
217.158.91.183
102.130.129.146
215.116.26.223
81.162.78.0
19.204.25.222
245.124.138.157
137.249.183.201
106.61.236.67
106.71.236.60
106.81.240.63
168.14.111.27
168.17.111.27
215.116.26.220
137.249.111.202
137.246.111.202
and store them into netoworks, that has to be a two dimensional array.
//declare libraries
#include <stdio.h>
#include <stdlib.h>
//declare other functions/files to be used in the program
void print_fun(void);
int sort_fun(void);
void read_fun(void);
//read command line input and store the information
int main(int argc, char** argv){
unsigned char networks[argc][4];
int arg = 0;
//convert command line argument to int
arg = atoi(argv[1]);
for (int j =0; j<1; ++j){
if(argc == 1)
{
printf("ERROR ERROR, you messed up\n");
}
else
{
// hold network addresses in a 2-d array, with 4 unsig char
for(int k = 0; k<arg; ++k){
for (int i =0; i<4; ++i){
scanf("%hhu",&networks[k][i]);
printf("%hhu",networks[k][i]);
}
printf("\n");
}}}
//sort array
42 //count networks
//print info about the array
}
i am wondering what i am doing wrong. i need to store the information coming in from the file into networks, the scanf is not storing the complete information of each address.
the new output
[p18d541#csci112 program1]$ ./main 17 < inp17.txt
1680640
0000
11000
0000
2481141048
25512700
194000
2000
2311131048
25512700
2919640
17000
1601131048
25512700
1000
0000
20818640
how do i change my code to store the network properly.
EDIT
with a quick update to the code of adding a period on the scan and print.
//declare libraries
#include <stdio.h>
#include <stdlib.h>
//declare other functions/files to be used in the program
void print_fun(void);
int sort_fun(void);
void read_fun(void);
//read command line input and store the information
int main(int argc, char** argv){
unsigned char networks[argc][4];
int arg = 0;
//convert command line argument to int
arg = atoi(argv[1]);
for (int j =0; j<1; ++j){
if(argc == 1)
{
printf("ERROR ERROR, you messed up\n");
}
else
{
// hold network addresses in a 2-d array, with 4 unsigned char
for(int k = 0; k<arg; k++){
for (int i =0; i<4; i++){
scanf("%hhu.", &networks[k][i]);
printf("%hhu.\",networks[k][i]);
}
printf("\n");
}}}
//sort array
//count networks
//print info about the array
}
and the new output is,
[p18d541#csci112 program1]$ ./main 17 < inp17.txt
1681211025
6411313435
21715891183
102130129146
21511626223
81162780
1920425222
245124138157
137249183201
1066123667
1067123660
1068124063
Segmentation fault (core dumped)
or it has thousands of output.
it is random
scanf is having a hard time parsing the periods between the numbers, and it's causing it to behave in unexpected ways. Try this instead:
scanf("%hhu.",&networks[k][i]);
printf("%hhu",networks[k][i]);
You've also got an issue in your declaration of array size:
unsigned char networks[argc][4];
argc is how many arguments were passed into the function, not the actual value you passed. This means your array is going to be the wrong size, likely resulting in a segfault. Try this instead:
int arg = 0;
//convert command line argument to int
arg = atoi(argv[1]);
//declared AFTER we have the value we want
unsigned char networks[arg][4];
Right, this is (the last) assignment for my C introduction web class.
The assignment presents the main program, does not explain anything about it and tells you to write a function to print and sum the array in it.
However I don't really understand what is going on in the main program.
Translated for your convenience;
Source code:
#include <stdio.h>
#include <stlib.h>
void print_count(int *, int);
int main(int argc, char *argv[]) {
int x, sum = 0, size = 0, array[5];
if (argc == 6) {
/* Program name and parameters received from command line */
for (x = 0; x < argc - 1; x++) {
array[x] = atoi(argv[x + 1]);
}
print_count(array, size);
} else {
printf("Error\n");
}
return 0;
}
Now I am completely clueless as to how to start writing the program requested and what variables to call/how to write the function.
Edit3: completed exercise
void print_count(int *array, int size) {
int i;
int sum = 0;
printf("Elements: ");
for (i = 0; i <= size; i++) {
printf("%d ", (array[i]);
sum = sum += array[i]);
}
printf("\nSum = %d ", sum);
return 0;
}
I would like to understand what is going on in the main program and preferably come to an answer on how to actually write the function by myself.
This:
array[5] = atoi(argv[x+1]);
is clearly wrong, it always tries to assign to array[5] which is out of bounds. It should be:
array[x] = atoi(argv[x + 1]);
This converts the x + 1:th argument from string format into an integer, and stores that in array[x]. If you're not familiar with the standard function atoi(), just read the manual page.
So if you start the program like this:
./myprogram 1 2 3 4 5
That has 6 arguments (the first is the name itself), and will end up with array containing the numbers one through five.
Then in the summing function, the first line should be something like:
void print_count(int *array, int size)
so that you give names to the arguments, which makes them usable in the function. Not providing names is an error, I think.
And it doesn't need to "interact" with main() more than it already does; main() calls print_count(), passing it a pointer to the first element of array and the length of the array, that's all that's needed to compute the sum.
Your print_count function has a few issues:
The loop runs one step too far: i should vary between 0 and size-1 included. The standard idiom for this loop is:
for (i = 0; i < size; i++) {
...
Incrementing sum is simply done with:
sum += array[i];
There is an extra ( on the first printf line.
You should print a newline after the output.
Returning 0 from a void function is invalid.
Here is a corrected version:
void print_count(int *array, int size) {
int i;
int sum = 0;
printf("Elements: ");
for (i = 0; i < size; i++) {
printf("%d ", array[i]);
sum += array[i]);
}
printf("\nSum = %d\n", sum);
}
the following proposed code:
cleanly compiles.
explains what is being accomplished at each step of the 'main()' function.
properly outputs error messages to 'stderr'.
implements the typical method to announce an error in the number of command line parameters.
Now the proposed code with explanatory comments:
#include <stdio.h> // printf(), fprintf()
#include <stdlib.h> // atoi(), exit(), EXIT_FAILURE
void print_count(int *, int);
int main(int argc, char *argv[])
{
if (argc != 6)
{
fprintf( stderr, "USAGE: %s int1 int2 int3 int4 int5\n", argv[0] );
exit( EXIT_FAILURE );
}
// implied else, correct number of arguments
// only declare variables when they are needed
int array[5];
// place each command line parameter into 'array',
// except program name
// I.E. skip the program name in argv[0]
for( int i = 1; i < argc; i++ )
{
// array[] index starts at 0, but loop counter starts at 1
array[i-1] = atoi(argv[i]);
} // end for( each value pointed at by argv[], except program name )
// print sum of command line parameters to stdout
int size = argc-1; // number of command line parameters after program name
print_count(array, size);
return 0;
} // end function: main
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);
}
}
My program grabs command line arguements with argc and argv[]. My question is how can I find the length of argv[1][i].
My code that grabs length of argv[]
int my_strlen(char input[]){
int len = 0;
while(input[len] != '\0'){
++len;
}
return len;
}
but when I try to find argv[1][len] I get a subscripted value is neither array nor pointer:
my attempt
int my_strlen(char input[]){
int len = 0;
while((input[1][len] - '0') != '\0'){
++len;
}
return len;
}
FULL CODE:
#include <stdio.h>
#include <math.h>
int my_strlen(char input[]);
int main(int argc, char *argv[]){
int length = 0;
length = my_strlen(argv[1]);
long numberArr[length];
int i, j;
for(i = 0; i < length; i++){
numberArr[i] = argv[1][i] - '0';
}
return 0;
}
int my_strlen(char input[]){
int len = 0;
while((input[1][len] - '0') != '\0'){
++len;
}
return len;
}
Thanks for any help in advance!
I think you're confused about the argv content. The OS will pass a number of ASCIIZ strings, such that invoking my_program with arguments ala...
my_program first second third
...is similar to having the following declaration in your program...
int argc = 4;
const char* argv[4] = { "my_program", "first", "second", "third" };
Hence, when you index into argv[1][i] you're getting the i-th character in the string "first". That's only valid for values of i between 0 (which yields 'f'), and 5 (which indexes to the terminating NUL character '\0').
So, there no two-dimensional N*M array, but there is an array of pointers-to-(array-of-char). You can invoke the normal strlen() function as in strlen(argv[1]) to find out the number of characters in each argument. Only argc tells you the total number of elements in argv.
Does that help?
In main, you're passing argv[1] to my_strlen. That means my_strlen just receives a normal, single-dimension string. It doesn't need to do input[1][len], just input[len].