C - printf字符串数组的结构。

时间:2021-09-22 11:11:19

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 :/

我是编程新手,在搜索和搜索之后,我得到了一些代码(部分),我可以创建一个struct,但我不能打印字符串字段:/

#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)

我的问题是,在这个"asignar"函数中,所有东西都可以正常工作,但是如果我试图在函数之外打印车辆的id,它就会打印出垃圾值,但是其他值,比如peso, hora和ferry,都是正确打印的(函数之外)

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 :)

谁能帮我吗?那太好了,谢谢。

3 个解决方案

#1


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.

在最好的情况下,你可能会得到一些随机的垃圾。然而,您的程序很可能只是segfault:您的代码声明id,但没有为它分配空间。

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.

您需要将它声明为char id[IDLEN],但是当您读取文件时得到的id是char*,当试图将它分配给llegada[i].id时,编译器会报错。

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

要使其工作,您需要使用该字符串复制一个字符串。h图书馆。

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;
}

#2


0  

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

首先,您将id声明为int,而不是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.

现在,当声明一个指针时,一些编译器会给它赋空值,这就是你的情况。当你这样做的时候:llegada[i]。id = id;它实际上不会将字符串分配给指针,而是应该分配空间(malloc或类似的)并使用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

在使用空指针创建结构体之后,您将尝试打印它。所有“平”的成员,例如int,将会被打印的很好,但是您的字符串,因为它是一个指针将不会打印任何东西,所以printf(“%s”,llegada[i].id);不会做一件事

#3


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:

您也可以根据需要为它分配空间,而不是静态声明id。下面是一个示例,展示了如何使用fget和sscanf处理每行读取和解析。与fscanf相比,它有几个优点(最显著的是,允许您根据需要读取和分配id)。如果你有问题,请告诉我:

#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

#1


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.

在最好的情况下,你可能会得到一些随机的垃圾。然而,您的程序很可能只是segfault:您的代码声明id,但没有为它分配空间。

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.

您需要将它声明为char id[IDLEN],但是当您读取文件时得到的id是char*,当试图将它分配给llegada[i].id时,编译器会报错。

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

要使其工作,您需要使用该字符串复制一个字符串。h图书馆。

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;
}

#2


0  

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

首先,您将id声明为int,而不是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.

现在,当声明一个指针时,一些编译器会给它赋空值,这就是你的情况。当你这样做的时候:llegada[i]。id = id;它实际上不会将字符串分配给指针,而是应该分配空间(malloc或类似的)并使用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

在使用空指针创建结构体之后,您将尝试打印它。所有“平”的成员,例如int,将会被打印的很好,但是您的字符串,因为它是一个指针将不会打印任何东西,所以printf(“%s”,llegada[i].id);不会做一件事

#3


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:

您也可以根据需要为它分配空间,而不是静态声明id。下面是一个示例,展示了如何使用fget和sscanf处理每行读取和解析。与fscanf相比,它有几个优点(最显著的是,允许您根据需要读取和分配id)。如果你有问题,请告诉我:

#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