1

I am trying to set up an struct with many values using command line. I give those attributes when I execute the programme in the Ubuntu 18.04ls terminal of MS store. However I'm getting a problem because I cannot get access to those attributes written on the terminal.

This is my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TAMANIOMAXIMO 20

struct persona {
  char nombre[TAMANIOMAXIMO];
  int edad;
  float ingresos;
}

main (int argc, char *argv[]) {
  printf("%d\n", argc);
  
  char nameProf[] = "";
  stpcpy(nameProf, argv[1]);
  int edadProf = atoi(argv[2]);
  float ingresosProf = atof(argv[3]);
  struct persona profesor = {nameProf, edadProf, ingresosProf};
  
  struct persona alumno;
  
  strcpy(alumno.nombre,"Juan");
  alumno.edad=19;
  alumno.ingresos=11.777;
  
  printf("Los ingresos conjuntos de alumnno y profesor son %f\n",alumno.ingresos+profesor.ingresos);
  exit(1);
} 

The result of that execution is this one:

./a.out james 10 12
-691680792
Los ingresos conjuntos de alumnno y profesor son 11.777000

I don't know why the parameter argc (which store the number of elements of argv) has this length. I try to remove the definition of the struct 'persona' which is before main function and everything is correct. The content of argv[1], argv[2] and argv[3] is not the given as parameter in command line, argv[0] do not store "./a.out" as it should store.

dreamcrash
  • 47,137
  • 25
  • 94
  • 117
diegogs_
  • 97
  • 9

4 Answers4

3

Because you forgot a ; after the struct, the compiler thinks that struct is the return type of main.

You should also have int main instead of just main.

A good start to fix the problems in your project is to turn on the warnings of your compiler (e.g., -Wall and -Werror) .

dreamcrash
  • 47,137
  • 25
  • 94
  • 117
Gnoom
  • 183
  • 6
2

For the closing braces of the definition of struct persona, change } to }; to end the declaration.

Change main (int argc, char *argv[]) to int main(int argc, char *argv[]). The missing semicolon and int resulted in a perverse declaration of main that likely interfered with passing arguments to it, resulting in the argc parameter being obtained incorrectly.

In char nameProf[] = "";, the array size is taken from the initializer "", so it has one element, a terminating null character. Because it has only one element, the stpcpy into it corrupts memory, causing your program to misbehave. You could change the definition to char nameProf[TAMANIOMAXIMO] = "";. However, this array is not needed, so just delete it and the stpcpy after it.

In struct persona profesor = {nameProf, edadProf, ingresosProf};, you cannot initialize an array (the nombre member) with another named array (nameProf). (You can initialize arrays of char with string literals, but that is not what you want here.) Just name nameProf to {0} to initialize the array to zeros for the moment. Then, after this line, copy the name into the array member, with strcpy(profesor.nombre, argv[1]);. (This is why nameProf is not needed; you can just copy the command-line argument directly into the structure member.)

Turn on warnings in your compiler and pay attention to them.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
2

If we compile your program without any changes, but pass -Wall -Werror to gcc, we get this:

$ gcc -Wall -Werror -o scratch main.c
main.c:7:1: error: return type of 'main' is not 'int' [-Werror,-Wmain-return-type]
struct persona {
^
main.c:7:1: note: change return type to 'int'
struct persona {
^~~~~~~~~~~~~~
int
main.c:20:30: error: incompatible pointer to integer conversion initializing 'char' with an expression of type 'char [1]' [-Werror,-Wint-conversion]
  struct persona profesor = {nameProf, edadProf, ingresosProf};
                             ^~~~~~~~
main.c:20:30: error: suggest braces around initialization of subobject [-Werror,-Wmissing-braces]
  struct persona profesor = {nameProf, edadProf, ingresosProf};
                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                             {                               }
3 errors generated.

So, just by passing those flags to GCC, you get all the information you need to fix your program.

2

Your program has multiple problems that make its behavior is undefined. It is unclear to me why that undefined behavior manifests specifically as an unexpected value being printed, but that is well within the realm of possible UB.

Among the issues are

  1. As @Gnoom points out in their answer, you have omitted a semicolon after the declaration of struct persona and additionally omitted the return type for main. The result is a syntactically correct declaration of a function that returns a struct persona, but main is required to return int.

  2. This declaration:

    char nameProf[] = "";
    

    Declares charName as an array just long enough to hold an empty string, including the terminator -- that is, just one byte. That's not enough to accommodate the name you later try to read into it, so you overrun that buffer.

  3. The initialization in this declaration ...

    struct persona profesor = {nameProf, edadProf, ingresosProf};
    

    ... does not have the effect you expect. Just as you cannot assign one array to another via the = operator, you cannot initialize the elements of an array or member array by putting the identifier of an array variable in an initializer corresponding to that member.

Your compiler ought to be warning you about at least some of these, and you should make a habit of reading compiler warnings and making sure you understand what they are telling you. Until you have more experience, you should assume that every warning indicates a problem that needs to be resolved lest your program fail to work correctly.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • I expect the `struct` return type of `main` resulted in generating code in which the called routine expects a hidden argument that would contain the address for the struct value to be written to. This bumps the regular arguments down one spot, so `argc` was taken from the wrong register. – Eric Postpischil Feb 11 '21 at 14:26
  • That's entirely plausible, @EricPostpischil. I'm sure that or something similar is indeed what happened, but I am disinclined to assert such specifics in this answer. They would necessarily be speculative, and they are tangential to the main issue. – John Bollinger Feb 11 '21 at 15:28