【问题标题】:How do I use a function correctly?如何正确使用函数?
【发布时间】:2017-08-19 07:18:03
【问题描述】:

我正在练习 C 函数、malloc、realloc 和文件。 该程序仍处于开始阶段,但完成后它应该执行用户决定的不同任务:主函数要求用户输入一个将其连接到程序不同功能的数字。

我的问题是函数“CaricaFile()”应该让用户输入文件名,加载这个记录了不同温度和时间的文件,并将这些数据加载到动态数组中;每次函数启动时,它都不允许我插入任何文件名,并且程序会继续出现“无效参数”错误。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define NOME_FILE_MAX 25

typedef struct {
    short int ore;
    short int minuti;
    float temperatura;
}t_rilevazione;

t_rilevazione *rilevazioni;
int i = -1;
int dimrilevazione = sizeof(t_rilevazione);

int CaricaFile() {
    char nome_file[NOME_FILE_MAX];
    printf("Inserire il nome del file da caricare, estensione compresa: ");
    fgets(nome_file, NOME_FILE_MAX, stdin);
    for (int q = 0; nome_file[q] != '\0'; q++) {
        if (nome_file[q] == '\n') nome_file[q] = '\0';
    }
    FILE *input_stream = fopen(nome_file, "r");
    if (input_stream == NULL) {
        perror("Impossibile trovare il file");
        return 0;
    }
    else {
        rilevazioni = malloc(dimrilevazione);
        if (rilevazioni = NULL) {
            perror("Problema con l'allocazione della memoria");
            return 0;
        }
        i = 0;
        while (feof(input_stream) != 1) {
            fscanf(input_stream, "%d:%d\n", &rilevazioni[i].ore, &rilevazioni[i].minuti);
            fscanf(input_stream, "%f", &rilevazioni[i].temperatura);
            realloc(rilevazioni, (i + 1 * dimrilevazione));
            if (rilevazioni == NULL) {
                perror("Problema con la riallocazione della memoria");
                return 0;
            }
            i++;
        }
        fclose(input_stream);
        printf("File caricato con successo.\n");

        return 1;
    }
}

int StampaVettore() {
    if (i >= 0) {
        int p;
        printf("I parametri registrati sono...\n");
        for (p = 0; p != i; p++) {
            printf("%d:%d\n%f\n", rilevazioni[p].ore, rilevazioni[p].minuti, rilevazioni[p].temperatura);
        }
        return 1;
    }
    else {
        printf("Nessun valore registrato.\n");
        return 0;
    }
}

int OrdinaVettore() {

}

int CalcolaMedia() {

}

int RicercaOrario() {

}

int SalvataggioFile() {

}

int main(void) {
    short int op;
    do {
        printf("Di seguito le operazioni che e' possibile effetuare con il programma:\n");
        printf("[1] Carica un file di testo\n");
        printf("[2] Stampa i record acquisiti dal file\n");
        printf("[3] Ordina il vettore dei record del file\n");
        printf("[4] Calcola la media delle temperature\n");
        printf("[5] Ricerca un determinato orario\n");
        printf("[6] Salva su file i record del programma\n");
        printf("[0] Esci dal programma\n");
        printf("Digitare il numero corrispondente all'operazione desiderata.\n");
        do {
            scanf("%d", &op);
            if (op < 0 || op > 6) {
                printf("Operazione non consentita. Riprovare\n");
            }
        } while (op < 0 || op > 6);
        if (op == 1) CaricaFile();
        if (op == 2) StampaVettore();
        if (op == 3) OrdinaVettore();
        if (op == 4) CalcolaMedia();
        if (op == 5) RicercaOrario();
        if (op == 6) SalvataggioFile();
        if (op == 0) printf("Uscita in corso...");
    } while (op != 0);
    return 0;
}

奇怪的是,如果我单独将 CaricaFile 函数作为 Main 函数带到它自己的程序中,它可以毫无问题地工作(至少,有一些问题,但那是因为我仍然不能很好地理解如何使用动态数组等)

我能做什么?谢谢

【问题讨论】:

  • 您是否使用过像 GDB 这样的调试器来查看问题所在?您还可以指出它给出了哪些错误消息。
  • while (feof(input_stream) != 1) { stackoverflow.com/q/5431941/905902
  • 您好,感谢您的回答;事实是,即使使用 Visual Studio 2017 作为 IDE(所以我使用它的调试器)也不会显示真正的错误,因为程序编译没有任何问题,它不会崩溃等,但它只是跳过 fgets ,不要求用户插入文件名,并给出“无效参数”错误

标签: c function malloc dynamic-arrays realloc


【解决方案1】:

一个错误是您将int 读入shortscanf

short int op;
...
scanf("%d", &op);

这会调用未定义的行为,因为指向的类型与格式说明符不匹配。另一个错误是您没有测试来自scanf 的返回值。

【讨论】:

  • 谢谢,我用一半的“h”修复它,所以“%hd”
  • @RaiN 我会使用int op;,因为如果你使用short,你不会得到任何东西并且输入更多。 int 是 C 语言中的自然机器字长。
【解决方案2】:

'realloc(rilevazioni, (i + 1 * dimrilevazione));'

realloc 返回一个值 - 您应该在手册页或 Google 中查找 realloc 并注意。仔细查看上面的调用。事实上,它不可能修改按值传递的 'rilevazioni' 参数。

另外,你为什么要把 'dimrilevazione' 乘以 1?这不会改变它的价值,所以浪费打字............(想想!)。

另外,我在任何地方都看不到任何 free() 调用?

【讨论】:

  • 您好,我的想法是在每个周期结束时重新分配一个“dimrilevazione”,因此“i”元素必须保留存储在数组中的记录数并同时相乘它适用于dimrilevazione,这样我每次需要的空间时都应该重新分配(至少我希望如此);然而,我从 0 开始,它总是比我需要的空间少 1 个数字,所以我的想法是做 (i+1) * (dimrilevazione):即使当 i = 1 它应该重新分配我需要的空间,但它似乎我没有正确执行此操作(?)
  • 好的,我应该让“i”从 1 开始,所以在第一个周期它重新分配 2 * dimrilevazione,谢谢你注意到这一点
  • 请在手册页中查找 realloc(),尤其是返回的值!。然后谷歌“C 运算符优先级” - 再次查看您的代码,“(i+1)*(dimrilevazione)”不是您在问题中发布的内容:(
猜你喜欢
  • 2014-04-22
  • 2021-02-03
  • 2011-12-22
  • 2016-12-21
  • 2010-11-16
  • 1970-01-01
  • 2011-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多