2017-02-12 10 views
2

У меня был этот код, который изначально читает WAV-файл, чтобы узнать количество образцов в нем. Используя этот размер, я пытался создать массив такого размера. После этого я читал образцы, формируя тот же самый файл .wav и сохранял в этом массиве, но из 762880 образцов он читал только 7500 отсчетов (приблизительно).Ошибка при создании массива в C, размер которого определен во время выполнения

#include<stdio.h> 
#include<conio.h> 
#include<math.h> 
#include<stdlib.h> 

void main(){ 
    FILE *fp; 
    long n,i=0; 
    float *data; 
    FILE* inp =NULL; 
    FILE* oup =NULL; 
    float value =0; 
    signed short ss; 
     /* Open file */ 
    fp = fopen("k1s1.wav", "rb"); 
    fseek(fp, 0L, SEEK_END); 
    n = ftell(fp); 
    n=n/2-22; 
    printf("n:%ld",n); 
    fclose(fp); 


    data=malloc(n*sizeof(float)); 


    inp = fopen("k1s1.wav","rb"); 
    oup = fopen("cs123.txt","wt"); 
    fseek (inp,44,SEEK_SET);// that didn't help getting the right result !! 

    i=0; 
    for(i=0;i<n;i++){ 
     fread(&ss, sizeof(signed short) ,1 , inp); 
     //Now we have to convert from signed short to float: 
     value=((float)ss)/(unsigned)0xFFFF; 
     value= value* 2.0; 
     value= value*100000; 
     value= ceil(value); 
     value= value/100000; 
     fprintf(oup,"%f\n",value); 
     data[i]=value; 
     ///printf("%lf\t",value); 

    } 

    fclose(inp); 
    fclose(oup); 
    printf("done"); 

} 

Когда я удаляю эту строку - «данные [i] = значение;» in for, программы отлично работают, и я могу видеть вывод в файле. Мне нужно сохранить эти значения в массиве, а также для дальнейших вычислений. Что может быть ошибкой?

+1

Существует возможность утверждать, что вы должны проверять ошибки 'fopen()', 'malloc()', 'fread()' вызовов. Однако, если вы получаете разумный размер для 'n', я не сразу вижу проблему. Я не пробовал играть с кодом. Я заметил, что вы можете использовать 'rewind (fp)' или 'fseek (fp, 0L, SEEK_SET);', чтобы не открывать файл '.wav' (используя' fp' вместо 'inp' после этого). Однако это оптимизация, а не причина ваших проблем. –

+0

Является ли компилятор воздействовать на выход? – Paras

+0

Маловероятно, что компилятор будет основным фактором здесь. Код использует стандарт C - помимо включения '', хотя он не использует ни одну из его функций. Ясно, что есть шанс, что вы каким-то образом столкнетесь с проблемой компилятора. Какой компилятор вы используете? (Я только что скомпилировал версию вашего кода с проверкой ошибок на ключевых функциях, и, похоже, проблема не возникла. Первый (только) файл '.wav', который я нашел на моей машине, имел только 6152 образцов в но я не понимаю, почему размер является основным фактором. Я работал на Mac с macOS Sierra 10.12.3 и GCC 6.3.0.) –

ответ

0

Код выглядит нормально. Что вы можете сделать, это проверить результаты от fseek и fread, чтобы подтвердить, что они работают должным образом. Что касается fseek, технически он должен быть передан результат от ftell и не прошел что-то посчитанное (но, вероятно, правильно!).

Я видел в комментариях TurboC. Если это так, убедитесь, что вы построили с использованием «small-code & больших данных». Если вы создаете «малый код & небольших данных», у вас могут быть проблемы, подобные тому, что вы видите с большим количеством данных.

Я бы, наверное, написать что-то вроде этого:

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

#define HEADER  22 
#define INCREMENT  10000 
#define CONVERSION (2.0/65535.0) 

int main() { 
    FILE *inp = NULL, *oup = NULL; 
    float *data = NULL, value; 
    signed short header[HEADER], ss; 
    long i = 0, j = 0; 

    if ((inp = fopen("k1s1.wav", "rb")) && (oup = fopen("cs123.txt","wt"))) { 
     if (fread(header, sizeof(header), 1, inp)) { 
      while (fread(&ss, sizeof(signed short), 1, inp)) { 
       value = ((float)ss) * CONVERSION; 
       if (j == i) { 
        j += INCREMENT; 
        if (!(data = realloc(data, j * sizeof(float)))) { 
         fprintf(stderr, "FAILURE: realloc failure at %ld elements\n", j); 
         return EXIT_FAILURE; 
        } 
       } 
       data[i++] = value; 
       fprintf(oup,"%.5f\n",value); 
      } 
      /* Release any extra memory */ 
      j = i; 
      if (!(data = realloc(data, j * sizeof(float)))) { 
       fprintf(stderr, "FAILURE: realloc failure at %ld elements\n", j); 
       return EXIT_FAILURE; 
      } 
      for (i = 0; i < j; i++) { 
       /* Can analyze data here */ 
      } 
     } else { 
      fprintf(stderr, "FAILURE: header not defined\n"); 
      return EXIT_FAILURE; 
     } 
    } else { 
     fprintf(stderr, "FAILURE: files could not be opened\n"); 
     return EXIT_FAILURE; 
    } 

    /* Okay to use if the arguments are NULL */ 
    free(data); 
    fclose(inp); 
    fclose(oup); 

    return EXIT_SUCCESS; 
} 

Это решение позволяет избежать какой-либо неопределенности относительно того, является ли fseek, ftell, и т.д. работают или нет их не использовать, и проверяет наличие более ошибок так вы можете быть в состоянии, если это не удается в ваших тестовых случаях. Надеюсь это поможет.

+1

Это похоже на комментарий, а не на ответ. –

 Смежные вопросы

  • Нет связанных вопросов^_^