0

I am new with programming, after searching and searching, i got some code to work (partially), i can create a struct but i can't print string fields :/

#include <stdio.h>
#define MAX 100

struct vehiculos{
 float peso;
 int hora;
 char *id;
 int ferry;
};

void asignar(struct vehiculos llegada[MAX] ...) { // Here i have more parameters, but they are useless in this question...
  int id,i;
  i=0;
  while(!feof(input_file)){
    fscanf(input_file,"%f %d %s %d",&llegada[i].peso,&llegada[i].hora,id,&llegada[i].ferry);
    llegada[i].id = id;
    i++;
   }
}

int main(){

  struct vehiculos llegada[MAX];
  FILE *entrada;
  entrada = fopen("proy1.txt","r");
  asignar(llegada...);

return 0;
}

My problem is that everything works fine in that "asignar" function, but if i try to print the vehicle's id outside that function, it just print garbage values, however other values like peso, hora and ferry are printed correctly (outside the function)

This works:

void asignar(...){
  ...
  printf("%s", llegada[i].id);
  ...
}

This doesn't work:

int main(){
  ...
  printf("%s", llegada[i].id);
  ...
}

Also my compiler says that there are no errors in the code, so i don't know what is the problem here

Can anyone help me? it would be great, Thanks :)

Macr1408
  • 785
  • 7
  • 9

3 Answers3

0

First, you declared id as an int instead of char*.

Now, when declaring a pointer, some compilers assign null to it, and that is your case. When you do this: llegada[i].id = id; it dosen't actually assign the string to the pointer, instead you should allocate space (malloc or similar) and use strcpy.

After creating your struct with null pointer, you are trying to print it. All "flat" members such as int will be printed just fine, but your string, as it is a pointer will print nothing, so printf("%s", llegada[i].id); won't do a thing

CIsForCookies
  • 12,097
  • 11
  • 59
  • 124
0

In the best case you may get some random garbage. However, most likely your program will just segfault: Your codes declares id, but doesn't allocate space for it.

You need to declare it as char id[IDLEN] But then, the id you get when reading the file is a char* and the compiler will complain when trying to assign it to llegada[i].id.

For this to work, you need to make a string copy using the string.h library.

The following code works.

#include <stdio.h>
#include <string.h>
#define MAX 100
#define IDLEN 80
struct vehiculos{
 float peso;
 int hora;
 char id[IDLEN];
 int ferry;
};

void asignar(struct vehiculos llegada[MAX], FILE* input_file) { // Here i have more parameters, but they are useless in this question...
  char id[IDLEN];
  int i;
  i=0;
  while(!feof(input_file)){
    fscanf(input_file,"%f %d %s %d",&llegada[i].peso,&llegada[i].hora,id,&llegada[i].ferry);
    strcpy(llegada[i].id , id);
    i++;
   }
}

int main(){

  struct vehiculos llegada[MAX];
  FILE *entrada;
  entrada = fopen("proy1.txt","r");
  asignar(llegada,entrada);
  printf("%s\n",llegada[0].id);

return 0;
}
MASL
  • 929
  • 1
  • 11
  • 25
0

Rather than statically declaring id, you can also allocate space for it as needed. Below is an example that shows the use of fgets and sscanf to handle reading and parsing each line read. It has several advantages over fscanf (most notably here allowing you to read and allocate id as needed). Let me know if you have questions:

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

#define MAX 100
#define MAXL 256

struct vehiculos {
    float peso;
    int hora;
    char *id;
    int ferry;
};

void asignar (struct vehiculos *llegada, FILE *fp, int *idx)
{                               // Here i have more parameters, but they are useless in this question...
    char line[MAXL] = {0};
    char idbuf[MAXL] = {0};

    while (fgets (line, MAXL, fp)) {

        sscanf (line, "%f %d %s %d", &llegada[*idx].peso, &llegada[*idx].hora,
                idbuf, &llegada[*idx].ferry);

        llegada[*idx].id = strdup (idbuf);

        (*idx)++;
    }

//     while (!feof (input_file)) {
//         fscanf (input_file, "%f %d %s %d", &llegada[i].peso, &llegada[i].hora,
//                 id, &llegada[i].ferry);
//         llegada[i].id = id;
//         i++;
//     }

}

int main (int argc, char **argv)
{
    FILE *entrada = argc > 1 ? fopen (argv[1], "r") : stdin;
    if (!entrada) {
        fprintf (stderr, "error: failed to open input for reading.\n");
        return 1;
    }

    int i, n = 0;
    struct vehiculos llegada[MAX] = {{0,0,NULL,0}};

    asignar (llegada, entrada, &n);

    if (entrada != stdin) fclose (entrada);

    for (i = 0; i < n; i++)
        printf (" llegada[%2d]  peso: %3.2f  hora: %2d  id: %8s  ferry: %d\n",
                i, llegada[i].peso, llegada[i].hora, llegada[i].id, llegada[i].ferry);

    for (i = 0; i < n; i++)
        free (llegada[i].id);

    return 0;
}

Sample Input

$ cat dat/vehiculos.txt
6.80 4 sal_135 2
8.20 3 jim_023 4
5.45 5 sam_101 6
6.75 3 bil_002 16

Example Output

$ ./bin/struct_no_alloc dat/vehiculos.txt
 llegada[ 0]  peso: 6.80  hora:  4  id:  sal_135  ferry: 2
 llegada[ 1]  peso: 8.20  hora:  3  id:  jim_023  ferry: 4
 llegada[ 2]  peso: 5.45  hora:  5  id:  sam_101  ferry: 6
 llegada[ 3]  peso: 6.75  hora:  3  id:  bil_002  ferry: 16
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85