简体   繁体   English

C-如何(通过基于用户的输入)将各种字符串存储在结构内部的数组中?

[英]C - How can I store (from user-based input) various strings in an array inside a structure?

I'm relatively new to programming. 我是编程新手。 I'm trying display all the data found in a previous user-based created file (user has to enter product code, product name and product price in a single entry). 我正在尝试显示在以前的基于用户的创建文件中找到的所有数据(用户必须在一个条目中输入产品代码,产品名称和产品价格)。 My code has a menu with 3 options: 我的代码有一个包含3个选项的菜单:

  1. Show all the data from the file (working only with the last entry from the option 2. Actually, I made the program to work intentionally like that, because I can't figure out how to print ALL the data in the file) 显示文件中的所有数据(仅与选项2中的最后一个条目一起使用。实际上,我使程序有意地那样工作,因为我不知道如何打印文件中的所有数据)
  2. Add data to that file (working 100%) 将数据添加到该文件(工作100%)
  3. Exit (working 100%) 退出(工作100%)

PS: When I try to use the option (1) after re-opening the program, it displays just garbage. PS:重新打开程序后尝试使用选项(1)时 ,它仅显示垃圾内容。 Is there a way to solve this problem? 有办法解决这个问题吗? PS2: Sorry about my bad usage of the english language, I'm not native. PS2:对不起我对英语的不良使用,我不是母语。

Here I display the whole code: 在这里显示整个代码:

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

typedef struct
{

  unsigned long long codigo_producto;
  char nombre_producto[60];
  float precio_producto;

} datos_de_productos;

int i;

main()
{

  datos_de_productos datos;

  char U = 233;
  char o = 162;
  int x = 0;
  int tam;
  FILE *p_datos;

  p_datos = fopen("datos.txt", "a");
  fseek(p_datos, 0, SEEK_END);
  tam = ftell(p_datos);
  if (tam == 0)
  {
    p_datos = fopen("datos.txt", "w");
    fprintf(p_datos,
        "CODIGO DE PRODUCTO\tNOMBRE DE PRODUCTO\tPRECIO DE PRODUCTO\n\n\n");
    fclose(p_datos);
  }

  while (x != 3)
  {

    system("cls");
    system("color 84");
    printf("****** MEN%c PRINCIPAL ******\n\n", U);
    printf("(1) - Ver el %cltimo producto ingresado en esta sesi%cn\n", U, o);
    puts("(2) - Agregar datos");
    puts("(3) - SALIR\n");
    menu_principal: printf("Por favor, ingrese la opci%cn deseada: ", o);
    scanf("%i", &x);

    switch (x)
    {

    case 1:

      system("cls");
      system("color 84");
      p_datos = fopen("datos.txt", "r");
      if (fopen == NULL )
      {
        exit(1);
      }
      if (fopen != NULL )
      {
        printf(
            "CODIGO DE PRODUCTO\tNOMBRE DE PRODUCTO\tPRECIO DE PRODUCTO\n\n\n");
        fscanf(p_datos, "%llu %s %f", &datos.codigo_producto,
            datos.nombre_producto, &datos.precio_producto);
        printf("%llu\t\t%s\t\t%.2f\n", datos.codigo_producto,
            datos.nombre_producto, datos.precio_producto);
        fclose(p_datos);
        puts("\n\n");
        system("pause");
        system("color 0E");
      }

      break;

    case 2:

      system("cls");
      puts("Se ingresaran los datos con el siguiente prototipo:\n");
      puts("codigo_producto | nombre_producto | precio_producto\n");
      puts("Ejemplo: '1763482 Placa_de_video 749.99'\n");
      printf(
          "(n%ctese que se usan guiones bajos para separar las palabras)\n\n",
          o);
      system("pause");
      system("cls");
      system("color 0E");
      puts("codigo_producto | nombre_producto | precio_producto\n");
      scanf("%llu %s %f", &datos.codigo_producto, datos.nombre_producto,
          &datos.precio_producto);
      p_datos = fopen("datos.txt", "a");
      if (fopen == NULL )
      {
        exit(1);
      }
      if (fopen != NULL )
      {
        fprintf(p_datos, "%llu\t\t%s\t\t%.2f\n", datos.codigo_producto,
            datos.nombre_producto, datos.precio_producto);
        fclose(p_datos);
        system("color 84");
        puts("\nProducto cargado correctamente.");
        system("pause");
      }

      break;

    case 3:

      system("cls");
      system("color 0F");
      puts("Nos\t\t\t\t\t\t\t\tby viciecal");
      sleep(1);
      puts("Re");
      sleep(1);
      puts("Vimos");
      sleep(1);
      puts("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t\t\t\t\t\t\t\t\tputo");

      break;

    default:

      goto menu_principal;

      break;

    }
  }
}

The first line of your file will be what's inside this fprintf : 文件的第一行将是此fprintf内部的内容:

fprintf(p_datos,
        "CODIGO DE PRODUCTO\tNOMBRE DE PRODUCTO\tPRECIO DE PRODUCTO\n\n\n");

When you get to this line inside case 1 , the file will be opened at its start (first line): 当您到达case 1这一行时,该文件将在其开头(第一行)打开:

p_datos = fopen("datos.txt", "r");

so this fscanf : 所以这个fscanf

fscanf(p_datos, "%llu %s %f", &datos.codigo_producto,
            datos.nombre_producto, &datos.precio_producto);

will try to read a llu from this first line: 会尝试从第一行读取一个llu

CODIGO DE PRODUCTO  NOMBRE DE PRODUCTO  PRECIO DE PRODUCTO

but will fail immediately because it won't find the llu , so you won't scan anything from the file (try to check the return value of fscanf and you'll see it will be 0 ). 但是会因为找不到llu而立即失败,因此您将不会扫描文件中的任何内容(尝试检查fscanf的返回值,您会看到它为0 )。


Why do you see garbage getting printed? 为什么看到垃圾被打印出来?

Because, as I said, fscanf failed, so your program will print whatever garbage values were inside your struct, seeing that you haven't initialized it at the beginning of your code. 正如我所说,因为fscanf失败,所以您的程序将打印出结构中的任何垃圾值,因为您尚未在代码开始时对其进行初始化。

Try to initialize your struct's members to zero and you'll see the program printing zeroes. 尝试将您的结构的成员初始化为零,您会看到程序打印零。


So... trying to salvage the majority of your code and your logic, one workaround I can think of would be to create a char array called last_product for example and fgets from the file until it's end, so the last entry read into the buffer will be the last line of the file. 因此,...试图挽救大部分代码和逻辑,我可以想到的一种解决方法是创建一个名为last_product的char数组,并从文件中获取fgets直到结束,因此最后一项读入缓冲区将是文件的最后一行。

Then you printf the last_product , like this: 然后,你printflast_product ,就像这样:

case 1:

  p_datos = fopen("datos.txt", "r");
  if (p_datos == NULL )
  {
    exit(1);
  }
  if (p_datos != NULL )
  {
    char last_product[100];
    while (fgets(last_product, 100, p_datos) != NULL)
        ;
    printf(
        "CODIGO DE PRODUCTO\tNOMBRE DE PRODUCTO\tPRECIO DE PRODUCTO\n\n\n");
    printf("%s", last_product);
    fclose(p_datos);
    puts("\n\n");
  }

I haven't analyzed or tested your entire code, but this should be enough to get you going. 我尚未分析或测试您的整个代码,但这足以让您继续前进。

PS: If it pleases you, rather than just printing last_product like I've done, you can sscanf from it into your struct and then print the struct contents. PS:如果你高兴的话,而不是仅仅打印last_product喜欢我所做的,你可以sscanf从它进入您的struct ,然后打印的struct内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM