所以我想用C语言制作一个脚本来显示奇偶校验位。基本上,我需要输入一个转换后的字符的二进制值,然后作为输出,我应该有输入+1或0(10是奇偶校验位,0是偶数,1是不偶数)。我就是不能让它工作。我要么得到相同的输入,要么得到一些疯狂的错误。谁能帮我一下?谢谢
这是我的剧本
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main (){
char msg_bit_input[128];
char msg_bit_output[128];
char caruno='1';
int i;
int one;
printf("Insert the byte: ");
scanf("%s", msg_bit_input);
strcpy (msg_bit_output, msg_bit_input);
for(i=0;i<8;i++){
if(msg_bit_input[i]==caruno){
one--;
}
}
if(one%2==0){
//byte is even
strcat (msg_bit_output, msg_bit_input);
} else if(one%2==1){
//byte is uneven
strcat (msg_bit_output, msg_bit_input);
}
printf("The result is: %s", msg_bit_output);
return (EXIT_SUCCESS);
}
让它工作所需的最小改动是。
one
计数器。one++
不应该是 one--
).\n
)中。printf
的输出。经过修复,它是。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main (){
char msg_bit_input[128];
char msg_bit_output[128];
char caruno='1';
int i;
int one = 0;
printf("Insert the byte: ");
scanf("%s", msg_bit_input);
strcpy (msg_bit_output, msg_bit_input);
for(i=0;i<8;i++){
if(msg_bit_input[i]==caruno){
one++;
}
}
if(one%2==0){
//byte is even
strcat (msg_bit_output, "0");
} else if(one%2==1){
//byte is uneven
strcat (msg_bit_output, "1");
}
printf("The result is: %s", msg_bit_output);
return (EXIT_SUCCESS);
}
在网上试一试。https:/onlinegdb.comBk30ef1s8。.
但这个程序是不必要的复杂。首先,不需要使用单独的输出和输入:你是按原样取输入,然后加一个奇偶位。我们简化为。
//...
int main (){
char bits[128];
char caruno='1';
int i;
int one = 0;
printf("Insert the byte: ");
scanf("%s", bits);
for(i=0;i<8;i++){
if(bits[i]==caruno){
one++;
}
}
if(one%2==0){
//byte is even
strcat (bits, "0");
} else if(one%2==1){
//byte is uneven
strcat (bits, "1");
}
printf("The result is: %s", bits);
return (EXIT_SUCCESS);
}
试试吧: https: /onlinegdb.comS1UwWMksU
然后,我们注意到,偶数均等性的检验只能有两种结果--它们是替代物,所以如果结果不是偶数,我们就知道它一定是奇数,所以不需要检查。
//...
if (one%2==0)
//byte is even
strcat (bits, "0");
else
//byte is odd
strcat (bits, "1");
//...
试试吧: https:/onlinegdb.comSkrc-Gki8
的使用。caruno
变量是不必要的:它几乎不是一个 "神奇的常数",我们很清楚它的含义。
int main (){
char bits[128];
int i;
int one = 0;
printf("Insert the byte: ");
scanf("%s", bits);
for(i=0;i<8;i++){
if(bits[i]=='1'){
one++;
}
}
//...
试试吧。https: /onlinegdb.comByAA-MkjU
然后我们注意到 scanf
无法知道它接收输入的缓冲区有多长。如果用户提供较长的输入。scanf
会很高兴地溢出那个缓冲区,并在堆栈中乱写乱画。我们希望程序在面对不好的输入时能够健壮地运行--这只是对 scanf
格式参数,提供宽度。有一个 注意事项: scanf
将始终在输入中附加零结束符,所以我们需要提供缓冲区大小减1,为零留出空间。
scanf("%127s", bits);
试试吧 https:/onlinegdb.comSJJrqMyj8
而现在我们也注意到,我们并没有真正测试输入字符串中是否有空间来追加输出。我们可以不追加输出,而是单独打印。
int main (){
char bits[128];
int i;
int one = 0;
char result;
printf("Insert the byte: ");
scanf("%127s", bits);
for(i=0;i<8;i++){
if(bits[i]=='1'){
one++;
}
}
if (one%2==0)
result = '0'; //byte is even
else
result = '1'; //byte is odd
printf("The result is: %s%c", bits, result);
return (EXIT_SUCCESS);
}
试试吧 https: /onlinegdb.comBk0w9M1iU
可以说,将输入限制在8位似乎没有必要--你从来没有检查过它。如果有必要,我们可以明确地检查它。
假设我们不关心输入是否正好是8位:我们将返回输入的任何位,并附加一个奇偶校验位。我们通过循环不超过 i
,但使用指向字符串缓冲区的指针,并将该字符与 '\0'
- 这就是我们应该中断循环的空结束符。注意,我们应该在这里断开循环。 迭代器(即 bufp
指针)可以指向 const char
,因为我们不打算让循环修改字符。
这时我们也可以检测到包含除 0
或 1
. 我们增加 error
函数来打印错误输出。我们也可以摆脱 string.h
头包含,因为我们没有使用该头的任何字符串操作。
#include <stdio.h>
#include <stdlib.h>
int error(const char *message)
{
fprintf(stderr, "\nError: %s.\n", message);
return EXIT_FAILURE;
}
int main (){
const char bits[128];
char *bitp;
int one = 0;
char result;
printf("Enter one or more binary bits: ");
scanf("%127s", bits);
for (bitp = bits; *bitp != '\0'; ++bitp)
{
if (*bitp == '1')
++one;
else if (*bitp != '0')
return error("invalid input");
}
if (one%2==0)
result = '0'; //byte is even
else
result = '1'; //byte is odd
printf("The result is: %s%c", bits, result);
return (EXIT_SUCCESS);
}
试试吧 https:/onlinegdb.comB1Ux-XyiI
现在我们应该测试是否处理了另一个输入错误条件--输入流是否过早结束。这可以在windows上通过按Ctrl-Z然后按Enter键触发(这将输入流关闭到控制台进程),或者在Unix上按Ctrl-D触发。
在onlinegdb中,你可以通过在控制台窗口中按^D触发这个错误条件,在你按完 Run
节目。
最后,利用更多的现代C语言特性将是一个好主意:你应该在接近使用点的地方声明和初始化变量,这样它们更容易被跟踪。在 result
变量可以使用三元运算符表达式进行初始化,表达式的形式为:: condition ? value_if_true : value_if_false
. 整个表达式变成了 value_if_true
如果条件评价为真,或 value_if_false
如果条件评估为false。这有助于在声明时进行初始化。
#include <stdio.h>
#include <stdlib.h>
int error(const char *message)
{
fprintf(stderr, "\nError: %s.\n", message);
return EXIT_FAILURE;
}
int main()
{
char bits[128];
printf("Enter one or more binary bits: ");
scanf("%127s", bits);
int ones = 0;
for (const char *bitp = bits; *bitp != '\0'; ++bitp)
{
if (*bitp == '1')
++ones;
else if (*bitp != '0')
return error("invalid input");
}
char result = (ones%2==0) ? '0' /*even*/ : '1' /*odd*/;
printf("The result is: %s%c", bits, result);
return EXIT_SUCCESS;
}
试试吧 https:/onlinegdb.comSJ1DbmJi8
有一点我不是特别喜欢,那就是容易出现bug的重复的 buf
在变量声明和 scanf
的格式字符串。
让我们试试来自 本回答并将输入的字符串因子化成一个单独的函数。
#include <stdio.h>
#include <stdlib.h>
int error(const char *message)
{
fprintf(stderr, "\nError: %s.\n", message);
return EXIT_FAILURE;
}
void scan_string(char *buffer, unsigned length) {
char format[12]; // Support max int value for the format %<num>s
snprintf(format, sizeof(format), "%%%ds", length - 1); // Generate format
scanf(format, buffer);
}
int main()
{
char bits[128];
printf("Enter one or more binary bits: ");
scan_string(bits, sizeof(bits));
int ones = 0;
for (const char *bitp = bits; *bitp != '\0'; ++bitp)
{
if (*bitp == '1')
++ones;
else if (*bitp != '0')
return error("invalid input");
}
char result = (ones%2==0) ? '0' /*even*/ : '1' /*odd*/;
printf("The result is: %s%c", bits, result);
return EXIT_SUCCESS;
}