c++ - C语言不执行循环体

查看:148
本文介绍了c++ - C语言不执行循环体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

RT如图所示代码中frames打印出结果为100,但是代码却不执行循环体,仔细检查过循环体里面没有break。return等语句,请问一下问题出在哪啊?(取消142行注释能够正打印出0到99)

#include <stdio.h>  
#include <stdint.h>  
#include <stdlib.h>  
  
struct WAV_Format {  
    uint32_t ChunkID;   /* "RIFF" */  
    uint32_t ChunkSize; /* 36 + Subchunk2Size */  
    uint32_t Format;    /* "WAVE" */  
  
    /* sub-chunk "fmt" */  
    uint32_t Subchunk1ID;   /* "fmt " */  
    uint32_t Subchunk1Size; /* 16 for PCM */  
    uint16_t AudioFormat;   /* PCM = 1*/  
    uint16_t NumChannels;   /* Mono = 1, Stereo = 2, etc. */  
    uint32_t SampleRate;    /* 8000, 44100, etc. */  
    uint32_t ByteRate;  /* = SampleRate * NumChannels * BitsPerSample/8 */  
    uint16_t BlockAlign;    /* = NumChannels * BitsPerSample/8 */     
    uint16_t BitsPerSample; /* 8bits, 16bits, etc. */  
  
    /* sub-chunk "data" */  
    uint32_t Subchunk2ID;   /* "data" */  
    uint32_t Subchunk2Size; /* data size */  
};   

//Data Chunk
//    ==================================
//    |       |所占字节数|  具体内容   |
//    ==================================
//    | ID    |  4 Bytes |   'data'    |
//    ----------------------------------
//    | Size  |  4 Bytes |             |
//    ----------------------------------
//    | data  |          |             |
//    ----------------------------------
//             图5 Data Chunk
//
//    Data Chunk是真正保存wav数据的地方,以'data'作为该Chunk的标示。然后是
//数据的大小。紧接着就是wav数据。根据Format Chunk中的声道数以及采样bit数,
//wav数据的bit位置可以分成以下几种形式:
//    ---------------------------------------------------------------------
//    |   单声道    |    取样1    |    取样2    |    取样3    |    取样4    |
//    |--------------------------------------------------------------------
//    |  8bit量化   |    声道0    |    声道0    |    声道0    |    声道0    |
//    ---------------------------------------------------------------------
//    |   双声道    |          取样1            |           取样2           |
//    |--------------------------------------------------------------------
//    |  8bit量化   |  声道0(左)  |  声道1(右)  |  声道0(左)  |  声道1(右)  |
//
//
//    ----------------------------------------------------------------------                                      
//
//    |   单声道    |    取样1                  |            取样2           |
//    |---------------------------------------------------------------------
//    | 16bit量化   |    声道0       |  声道0   |    声道0       |  声道0    |
//    |             | (低位字节)  | (高位字节)  | (低位字节)     | (高位字节)|
//    -----------------------------------------------------------------------
//
//    |   双声道    |    取样1                         |            取样2             |
//    |-------------------------------------------------------------------------------
//    | 16bit量化   |    声道0(左)  |  声道0(左)   |    声道1(左) |  声道1(右)|
//    |             | (低位字节)      | (高位字节)     | (低位字节)     | (高位字节)  |
//    ---------------------------------------------------------------------------------

struct BLOCK_16bit_2channel {
    uint8_t channel_left_low;
    uint8_t channel_left_high;
    uint8_t channel_right_low;
    uint8_t channel_right_high;
};
struct DATA_BLOCK {
    char strData[4]; // 'd' 'a' 't' 'a'
    uint32_t dwDataSize;
//    BLOCK_16bit_2channel block
};
  
int main(void)  
{  
    FILE *fp = NULL;  
    struct WAV_Format wav;  
    struct DATA_BLOCK data;  
    struct BLOCK_16bit_2channel block;  
  
    fp = fopen("test.wav", "rb");  
    if (!fp) {  
        printf("can't open audio file\n");  
        exit(1);  
    }  
  
    fread(&wav, 1, sizeof(struct WAV_Format), fp);  
  
    printf("length:%d(10),0x%x, \n\n", sizeof(struct WAV_Format), sizeof(struct WAV_Format));  // 44
    printf("ChunkID \t%x\n", wav.ChunkID);  
    printf("ChunkSize \t%d\n", wav.ChunkSize);  
    printf("Format \t\t%x\n", wav.Format);  
    printf("Subchunk1ID \t%x\n", wav.Subchunk1ID);  
    printf("Subchunk1Size \t%d\n", wav.Subchunk1Size);  
    printf("AudioFormat \t%d\n", wav.AudioFormat);  
    printf("NumChannels \t%d\n", wav.NumChannels);  
    printf("SampleRate \t%d\n", wav.SampleRate);  
    printf("ByteRate \t%d\n", wav.ByteRate);  
    printf("BlockAlign \t%d\n", wav.BlockAlign);  
    printf("BitsPerSample \t%d\n", wav.BitsPerSample);  
    printf("Subchunk2ID \t%x\n", wav.Subchunk2ID);  
    printf("Subchunk2Size \t%d\n", wav.Subchunk2Size);  
    
//    fread(&data, 1, sizeof(struct DATA_BLOCK), fp);  
//    printf("dwDataSize \t%x\n", data.dwDataSize);  
    
    char data_block;
    uint16_t lh;
    uint16_t ll;
    uint16_t rh;
    uint16_t rl;
    
    struct Spectrum {
        unsigned int s1;
        unsigned int s2;
        unsigned int s3;
        unsigned int s4;
        unsigned int s5;
        unsigned int s6;
        unsigned int s7;
        unsigned int s8;
    };
    
//    unsigned short sample;
    
      if (wav.BitsPerSample == 16) {
          if (wav.NumChannels == 2) {
              int i;
              
              long count = wav.Subchunk2Size / sizeof(struct BLOCK_16bit_2channel);
              int duration = count / wav.SampleRate; // 采样数量除以每秒采样率等于持续秒数 
              short fps = 10; // frequency
              int frames = duration * fps;
              int readSamplePer = wav.SampleRate / fps; // 每秒读取采样数量 
              int readBytesPer = sizeof(struct BLOCK_16bit_2channel) * readSamplePer; // 每秒读取字节数 
              short width = 80;
              int total = fps * wav.SampleRate / width;
              
              int left, right;
//              for (int s=0; s<frames; ++s)printf("\n%d\n", s);
                printf("\nframe:%d\n", frames);
              for (int s=0; s<frames; ++s) {
                printf("\n%d\n", s);
                struct Spectrum spectrum;
//              fread(&sample, 1, readSamplePer, fp);
                  for (int r=0; r<readBytesPer; ++r) {
                      fread(&block, 1, readBytesPer, fp);
                      lh = block.channel_left_high;
                    ll = block.channel_left_low;
                    rh = block.channel_right_high;
                    rl = block.channel_right_low;
                    left = (lh << 4) | ll;
                    right = (rh << 4) | rl;
                    uint32_t sample = (left + right) / 2;
                      printf("\n%d\n", sample);
                    
                      if (sample < 4096 * 1) {
                          ++spectrum.s1;
                      }
                      if (sample < 4096 * 2) {
                          ++spectrum.s2;
                      }
                      if (sample < 4096 * 3) {
                          ++spectrum.s3;
                      }
                      if (sample < 4096 * 4) {
                          ++spectrum.s4;
                      }
                      if (sample < 4096 * 5) {
                          ++spectrum.s5;
                      }
                      if (sample < 4096 * 6) {
                          ++spectrum.s6;
                      }
                      if (sample < 4096 * 7) {
                          ++spectrum.s7;
                      }
                      if (sample < 4096 * 8) {
                          ++spectrum.s8;
                      }
                      
                }
                  printf("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", spectrum.s1, spectrum.s2, spectrum.s3, spectrum.s4, spectrum.s5, spectrum.s6, spectrum.s7, spectrum.s8);
            }
//            for (i=0; i<count; i+=frequency) {
//                fread(&block, 1, sizeof(struct BLOCK_16bit_2channel), fp);
//                lh = block.channel_left_high;
//                ll = block.channel_left_low;
//                rh = block.channel_right_high;
//                rl = block.channel_right_low;
//                left = (lh << 4) | ll;
//                right = (rh << 4) | rl;
////                printf("%d:\t%d\t%d\n", i, left, right);
//            }
//            printf("\ni:%d,count:%d\n", i, count);
//            system("cls");
        } 
    }
  
    fclose(fp);  
  
    return 0;  
}  

解决方案

首先

循环体执行了。
log上有个0,说明第一次s=0的时候进入循环了。

然后

看起来像是没有执行,是因为程序崩溃了。
最后的报错信息process excited after ... with return value 3221225477

崩溃的原因

出问题的应该是第149行的fread(&block, 1, readBytesPer, fp);
作为buff的block,其长度只有一个struct BLOCK_16bit_2channel
但是读取的长度readBytesPer = sizeof(struct BLOCK_16bit_2channel) * readSamplePer,其中readSamplePer的值为22050*10
读取长度远远超出buff,内存读写越界了,导致最后程序崩溃。

这篇关于c++ - C语言不执行循环体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆