I have the following code (only necessary lines posted). Here I copy the first 44 bytes of a WAVE file (PCM, i.e. Linear quantization). And the problem is in displaying char[4]
records of a sturct.
我有下面的代码(只有必要的行)。这里我复制一个波文件的前44字节(PCM,即线性量化)。问题是显示一个sturct的char[4]记录。
Can't figure it out, though was trying to understand what is the reason but with no result.
我搞不懂,只是想弄明白是什么原因,但是没有结果。
QUESTION: Why do I have to use precision modifier %.*s
to display only first 4 symbols of char[N]
instead of just printing char[4]
variable using %s
?
问题:为什么我必须使用精度修改器%。*s只显示char[N]的前4个符号,而不是仅仅使用%s打印char[4]变量?
BUT if I write modifiers to %s
--> %.4s
the printf()
function prints everthing properly: "RIFF", "WAVE", "fmt ", "data". It just displays only first 4 symbols of each char[4]
record. But what's about symbols that were not displayed?
但是如果我写入修饰符到%s——> %。printf()函数正确地打印所有内容:“RIFF”、“WAVE”、“fmt”、“data”。它只显示每个char[4]记录的前4个符号。但是没有显示的符号是什么呢?
I get the following with %s
:
我得到以下%s:
Enter input and output filenames (with no extension):
europe_-_final_countdown
europe_-_final_countdown_out
Opening file: "europe_-_final_countdown.wav" has been successfully opened.
*********************************
ChunkID: RIFF4?AWAVEfmt // instead of "RIFF"
ChunkSize: 54629940
Format: WAVEfmt // instead of "WAVE"
SubChunk1ID: fmt // here is "fmt " -> ok
SubChunk1Size: 16
AudioFormat: 1
NumChannels: 2
SampleRate: 44100
ByteRate: 176400
BlockAlign: 4
BitsPerSample: 16
SubChunk2ID: data?A // instead of "data"
SubChunk2Size: 54629904
*********************************
Process returned 0 (0x0) execution time : 34.554 s
Press ENTER to continue.
So here is the code:
这里是代码:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAX_NAME_LENGTH 255
typedef unsigned short byte2;
typedef unsigned int byte4;
struct header
{
// totally 44 bytes; endian (all the rest are little)
// RIFF
char ChunkID[4]; // big
byte4 ChunkSize;
char Format[4]; // big
// fmt
char SubChunk1ID[4]; // big
byte4 SubChunk1Size;
byte2 AudioFormat;
byte2 NumChannels;
byte4 SampleRate;
byte4 ByteRate;
byte2 BlockAlign;
byte2 BitsPerSample;
// data
char SubChunk2ID[4]; // big
byte4 SubChunk2Size;
};
struct header hdr;
int main()
{
char nameInput[MAX_NAME_LENGTH];
char nameOutput[MAX_NAME_LENGTH];
printf("Enter input and output filenames (with no extension):\n");
scanf("%s", nameInput);
strcat(nameInput, ".wav");
//printf("nameInput: %s", nameInput);
scanf ("%s", nameOutput);
strcat(nameOutput, ".wav");
//printf("nameInput: %s", nameOutput);
/// Opening the input file.
FILE *input = fopen(nameInput, "rb");
if (input == NULL)
{
printf ("Opening file: Couldn’t open file %s; %s.\n",
nameInput, strerror (errno));
exit (EXIT_FAILURE);
}
else
printf("Opening file: \"%s\" has been successfully opened.\n",
nameInput);
/// copying header (first 44 bytes) to `hdr`
char buf[44];
fread(&hdr, 1, sizeof(buf), input);
/// hdr
printf("\n*********************************\n");
printf(" ChunkID: %s\n", hdr.ChunkID ); // Contains the letters "RIFF" in ASCII.
printf(" ChunkSize: %d\n", hdr.ChunkSize ); // 36 + SubChunk2Size (which we don't mention)
printf(" Format: %s\n", hdr.Format ); // Contains the letters "WAVE"
printf(" SubChunk1ID: %s\n", hdr.SubChunk1ID ); // Contains the letters "fmt "
printf(" SubChunk1Size: %d\n", hdr.SubChunk1Size ); // 16 for PCM. This is the size of the rest of the Subchunk which follows this number.
printf(" AudioFormat: %d\n", hdr.AudioFormat ); // PCM = 1 (i.e. Linear quantization). Values other than 1 indicate some form of compression.
printf(" NumChannels: %d\n", hdr.NumChannels ); // Mono = 1, Stereo = 2, etc.
printf(" SampleRate: %d\n", hdr.SampleRate ); // 8000, 44100, etc.
printf(" ByteRate: %d\n", hdr.ByteRate ); // == SampleRate * NumChannels * BitsPerSample/8
printf(" BlockAlign: %d\n", hdr.BlockAlign ); // == NumChannels * BitsPerSample/8. The number of bytes for one sample including all channels.
printf(" BitsPerSample: %d\n", hdr.BitsPerSample ); // 8 bits = 8, 16 bits = 16, etc.
printf(" SubChunk2ID: %s\n", hdr.SubChunk2ID);
printf(" SubChunk2Size: %d\n", hdr.SubChunk2Size);
printf("\n*********************************\n");
/// ...
return 0;
}
1 个解决方案
#1
5
The %s
format specifier causes printf
to print a null-terminated string. Your string isn't null-terminated.
%s格式说明符导致printf打印以null结尾的字符串。你的字符串不是以null结尾。
When printf
tries to print a null-terminated string, it simply prints characters until it encounters a zero byte. In your case this causes the data after the intended end of the string to be interpreted as characters and printed, until a zero byte is encountered.
当printf试图打印一个以null结尾的字符串时,它只是打印字符,直到遇到一个零字节。在您的情况下,这将导致数据在字符串的预期结束后被解释为字符并打印,直到遇到一个0字节。
#1
5
The %s
format specifier causes printf
to print a null-terminated string. Your string isn't null-terminated.
%s格式说明符导致printf打印以null结尾的字符串。你的字符串不是以null结尾。
When printf
tries to print a null-terminated string, it simply prints characters until it encounters a zero byte. In your case this causes the data after the intended end of the string to be interpreted as characters and printed, until a zero byte is encountered.
当printf试图打印一个以null结尾的字符串时,它只是打印字符,直到遇到一个零字节。在您的情况下,这将导致数据在字符串的预期结束后被解释为字符并打印,直到遇到一个0字节。