C - 包含结构数组的printf字符串

时间:2015-09-03 19:28:08

标签: c arrays 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;
}

我的问题是,一切都运行正常&#34; asignar&#34;功能,但如果我尝试在该功能外打印车辆的ID,它只会打印垃圾值,但是比索,hora和渡轮等其他值正确打印(在功能之外)

这有效:

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

这不起作用:

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

我的编译器也说代码中没有错误,所以我不知道这里有什么问题

任何人都可以帮助我吗?这会很棒,谢谢:)。

3 个答案:

答案 0 :(得分:0)

首先,您将id声明为int而不是char *。

现在,在声明指针时,一些编译器会为它指定null,这就是你的情况。 执行此操作时:Expression它实际上将字符串分配给指针,而应分配空间(malloc或类似)并使用strcpy。

使用空指针创建结构后,您正在尝试打印它。所有&#34;平坦&#34;诸如int之类的成员将被打印得很好,但是你的字符串,因为它是一个指针,什么都不打印,所以llegada[i].id = id;不会做任何事情

答案 1 :(得分:0)

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

您需要将其声明为 char id[IDLEN] 但是,读取文件时得到的idchar*,编译器在尝试将其分配给llegada[i].id时会抱怨。

为此,您需要使用string.h库进行字符串复制。

以下代码有效。

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

您可以根据需要为其分配空间,而不是静态声明id。下面是一个示例,显示了使用fgetssscanf来处理读取和解析每一行读取。与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;
}

示例输入

$ 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

示例输出

$ ./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