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

标签 c arrays file menu structure

我对编程还比较陌生。我正在尝试显示在以前基于用户创建的文件中找到的所有数据(用户必须在单个条目中输入产品代码、产品名称和产品价格)。 我的代码有一个包含 3 个选项的菜单:

  1. 显示文件中的所有数据(仅使用选项 2 中的最后一个条目。实际上,我故意让程序像这样工作,因为我不知道如何打印文件中的所有数据)
  2. 向该文件添加数据(100% 正常工作)
  3. 退出(100% 工作)

PS:当我重新打开程序后尝试使用选项(1)时,它只显示垃圾。有办法解决这个问题吗? PS2:抱歉我英语不好,我不是母语。

这里我展示了整个代码:

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

    }
  }
}

最佳答案

文件的第一行将是 fprintf 中的内容:

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

当您到达 case 1 中的这一行时,文件将从其开头(第一行)打开:

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

所以这个fscanf:

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

将尝试从第一行读取llu:

CODIGO DE PRODUCTO  NOMBRE DE PRODUCTO  PRECIO DE PRODUCTO

但会立即失败,因为它找不到 llu,因此您不会扫描文件中的任何内容(尝试检查 fscanf 的返回值并你会看到它是0)。

<小时/>

为什么你会看到打印垃圾?

因为,正如我所说,fscanf 失败了,因此您的程序将打印结构内的任何垃圾值,因为您尚未在代码开头初始化它。

尝试将结构体的成员初始化为零,您将看到程序打印零。

<小时/>

所以...尝试挽救大部分代码和逻辑,我能想到的一种解决方法是创建一个名为 last_product 的 char 数组,例如和 fgets 从文件直到结束,因此读入缓冲区的最后一个条目将是文件的最后一行。

然后你printf last_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");
  }

我还没有分析或测试您的整个代码,但这应该足以让您继续下去。

PS:如果您愿意,您可以将其 sscanf 放入您的 struct 中,而不是像我那样只打印 last_product然后打印struct内容。

关于C - 如何将(来自基于用户的输入)各种字符串存储在结构内的数组中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41085282/

相关文章:

java - 从文件加载的字符串中删除转义字符

C# 从 URL 中读取文件信息

linux - 创建 Linux Bash 脚本来复制文件并创建目录

c - 在 C 程序中嵌入 Rust 任务?

java - 从数组到数组创建新对象

arrays - 在 Swift 中创建具有两种变量类型的二维数组数组

javascript - 如何通过 post 请求将形状像某些 JSON 对象数组的字符串传递给数组

c - 如何在 C 中使用动态矩阵

c++ - 将单声道编译为静态库

c - 结构 |结构/union 的不完整类型错误