c 我如何 return 从二进制文件中读取字符的奇偶校验
c How can i return a parity of char read from binary file
int parity (char msg[1400]) {
int parity = 0;
int i,j;
char c;
for(i=0;i<strlen(msg);i++) {
for(j=0;j<8;j++) {
c = msg[i];
int bit = (c>>j)&1;
parity ^= bit;
}
}
return parity;
}
这个函数return效果不错,下一个例子:
char* msg = malloc(sizeof(char*)*1400);
strcpy(msg,"some string");
int parity = parity(msg);
对于下一个示例,结果不好:
char* msg = malloc(sizeof(char*)*1400);
FILE *fp;
fp = fopen(filename,"r"); //filename is a binary file
while( !feof(fp) ){
fread(msg,1399,sizeof(char),fp);
int parity = parity(msg); //--> the result isn't well
//.......
}
当我从文件中读取时,我看到 strlen(msg) 在每一步(192,80,200...等)都是可变的。我必须为第二个示例更改 "parity" 函数。有什么建议吗?
我会完全避免 feof()
- fread()
告诉您它读取了多少字节。你还说它是一个二进制文件,但你正在使用字符串函数 - 它们不会起作用。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define BUFMAX 1400
int main(void){
unsigned char buffer[BUFMAX];
int i, bit, len, parity = 0;
FILE *fp;
if ((fp = fopen("myfile.dat", "rb")) == NULL) {
printf("Cannot open file\n");
return 1;
}
while ((len = fread(buffer, 1, BUFMAX, fp))) {
for (i=0; i<len; i++) {
for (bit=0; bit<CHAR_BIT; bit++) {
parity ^= (buffer[i] & 1);
buffer[i] >>= 1;
}
}
}
fclose (fp);
printf ("Parity = %d\n", parity);
return 0;
}
除了奇偶校验之外还有其他问题,但让我们专注于那个。
查找所有字节的奇偶校验,一次 1 个字节而不是一次 1 个位。接下来:char
的奇偶校验。如果 char
是 8 位,则需要 3 次迭代。 (log2(CHAR_BIT))
int parity(const char msg[], size_t len) {
// XOR all bytes together
unsigned par = 0;
while (len > 0) {
par ^= msg[--len];
}
// Find char parity
unsigned width = CHAR_BIT;
do {
par ^= par >> (width/2);
width -= width/2;
} while (width > 1);
// Only return Least Significant Bit
return parity % 2;
}
#define Width 1400
char msg[Width];
fread(msg, Width, sizeof *msg, fp);
int par = parity(msg, Width);
如果数组的长度是sizeof(unsigned)
的倍数。速度提高了 4 倍 (sizeof unsigned/sizeof char
)。
int parity_u(const unsigned msg[], size_t unsigned_len) {
// XOR all unsigned together
unsigned par = 0;
while (len > 0) {
par ^= msg[--len];
}
// Find unsigned parity
unsigned width = sizeof *msg * CHAR_BIT;
do {
par ^= par >> (width/2);
width -= width/2;
} while (width > 1);
// Only return Least Significant Bit
return parity % 2;
}
#define Width (1400/sizeof(unsigned))
unsigned msg[Width];
fread(msg, Width, sizeof *msg, fp);
int par = parity_u(msg, Width);
int parity (char msg[1400]) {
int parity = 0;
int i,j;
char c;
for(i=0;i<strlen(msg);i++) {
for(j=0;j<8;j++) {
c = msg[i];
int bit = (c>>j)&1;
parity ^= bit;
}
}
return parity;
}
这个函数return效果不错,下一个例子:
char* msg = malloc(sizeof(char*)*1400);
strcpy(msg,"some string");
int parity = parity(msg);
对于下一个示例,结果不好:
char* msg = malloc(sizeof(char*)*1400);
FILE *fp;
fp = fopen(filename,"r"); //filename is a binary file
while( !feof(fp) ){
fread(msg,1399,sizeof(char),fp);
int parity = parity(msg); //--> the result isn't well
//.......
}
当我从文件中读取时,我看到 strlen(msg) 在每一步(192,80,200...等)都是可变的。我必须为第二个示例更改 "parity" 函数。有什么建议吗?
我会完全避免 feof()
- fread()
告诉您它读取了多少字节。你还说它是一个二进制文件,但你正在使用字符串函数 - 它们不会起作用。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define BUFMAX 1400
int main(void){
unsigned char buffer[BUFMAX];
int i, bit, len, parity = 0;
FILE *fp;
if ((fp = fopen("myfile.dat", "rb")) == NULL) {
printf("Cannot open file\n");
return 1;
}
while ((len = fread(buffer, 1, BUFMAX, fp))) {
for (i=0; i<len; i++) {
for (bit=0; bit<CHAR_BIT; bit++) {
parity ^= (buffer[i] & 1);
buffer[i] >>= 1;
}
}
}
fclose (fp);
printf ("Parity = %d\n", parity);
return 0;
}
除了奇偶校验之外还有其他问题,但让我们专注于那个。
查找所有字节的奇偶校验,一次 1 个字节而不是一次 1 个位。接下来:char
的奇偶校验。如果 char
是 8 位,则需要 3 次迭代。 (log2(CHAR_BIT))
int parity(const char msg[], size_t len) {
// XOR all bytes together
unsigned par = 0;
while (len > 0) {
par ^= msg[--len];
}
// Find char parity
unsigned width = CHAR_BIT;
do {
par ^= par >> (width/2);
width -= width/2;
} while (width > 1);
// Only return Least Significant Bit
return parity % 2;
}
#define Width 1400
char msg[Width];
fread(msg, Width, sizeof *msg, fp);
int par = parity(msg, Width);
如果数组的长度是sizeof(unsigned)
的倍数。速度提高了 4 倍 (sizeof unsigned/sizeof char
)。
int parity_u(const unsigned msg[], size_t unsigned_len) {
// XOR all unsigned together
unsigned par = 0;
while (len > 0) {
par ^= msg[--len];
}
// Find unsigned parity
unsigned width = sizeof *msg * CHAR_BIT;
do {
par ^= par >> (width/2);
width -= width/2;
} while (width > 1);
// Only return Least Significant Bit
return parity % 2;
}
#define Width (1400/sizeof(unsigned))
unsigned msg[Width];
fread(msg, Width, sizeof *msg, fp);
int par = parity_u(msg, Width);