我是否以正确的方式使用 strncmp 和 fgets?
Am I using strncmp and fgets in the right way?
我是一名尝试学习 C 的初级程序员。目前我正在参加 class 并分配了一个项目,我设法很快完成了它,至少是它的主要部分。不过,我在围绕 main() if 函数进行编码时遇到了一些麻烦,因为我开始使用一些新函数(即 fgets 和 strncmp)。现在,我的代码可以在我的编译器中运行,但不能在任何在线编译器中运行。所以我想知道我是否做错了什么,或者是否有任何方法可以改进它。
感谢任何帮助或贡献,谢谢!
下面是代码,加密和解密函数是main之前的前两个函数,我相信大部分乱七八糟的shortcut-code可能是这里。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * Encrypt(char sentence[])
{
int primes[12] = {1,2,3,5,7,11,13,17,19,23,29,31};
int x = 0;
int counter = 0;
int ispositive = 1;
while(sentence[x] != 0)
{
if (counter == 0)
{
ispositive = 1;
}
else if(counter == 11)
{
ispositive = 0;
}
if (ispositive == 1)
{
sentence[x] = sentence[x] + primes[counter];
counter++;
}
else if (ispositive == 0)
{
sentence[x] = sentence[x] + primes[counter];
counter--;
}
x++;
}
return sentence;
}
char * Decrypt(char sentence[])
{
int primes[12] = {1,2,3,5,7,11,13,17,19,23,29,31};
int x = 0;
int counter = 0;
int ispositive = 1;
while(sentence[x] != 0)
{
if (counter == 0)
{
ispositive = 1;
}
else if(counter == 11)
{
ispositive = 0;
}
if (ispositive == 1)
{
sentence[x] = sentence[x] - primes[counter];
counter++;
}
else if (ispositive == 0)
{
sentence[x] = sentence[x] - primes[counter];
counter--;
}
x++;
}
return sentence;
}
int main()
{
char message[100];
char input[7];
char *p;
int c;
int condition = 1;
while(condition == 1)
{
printf("Would you like to Encrypt or Decrypt a message? (Type TurnOff to end the program) \n \n");
fgets(input,7, stdin);
fflush(stdin);
if (!strncmp(input,"Encrypt",strlen(input)))
{
printf("\n \n Enter the message you want to Encrypt below: \n \n");
fgets(message, 100, stdin);
Encrypt(message);
printf("\n Your encrypted message is: ");
printf("%s", message);
fflush(stdin);
printf("\n \n");
}
else if (!strncmp(input,"Decrypt",strlen(input)))
{
printf("\n \n Enter the message you want to Decrypt below: \n \n");
fgets(message, 100, stdin);
Decrypt(message);
printf("\n Your Decrypted message is: ");
printf("%s", message);
fflush(stdin);
printf("\n \n");
}
else if (!strncmp(input,"TurnOff",strlen(input)))
{
printf("\n \n Thank you for using the program! \n \n");
condition = 0;
}
else
{
printf("That's not a valid input \n \n");
}
}
}
在 printf 之后,您执行 fflush(stdin) 而不是必须执行 fflush(stdout)。因为您正在打印输出。输出打印在标准输出中。因此,您必须刷新 stdout 缓冲区而不是 stdin 缓冲区。
您可以使用 strcmp 而不是 strncmp。因为在这里你正在比较输入数组中的孔字符。所以,strcmp 就够了。
strcmp(输入,"Encrypt").
strcmp 或 strncmp 函数获取数组中的输入,最多为 null 或您声明的字符串的大小。
输入数组的大小太小。
让我们输入如下。
Encrypt\n
sureshkumar\n
在这里,您首先在 main 函数中使用 fgets 读取最多 "Encrypt" 它不会跳过 '\n'。
'\n' 是从另一个 fgets 读取的。因此,它没有得到加密消息 "sureshkumar".
所以,你必须修改你的代码。您将增加输入数组的大小。
并检查如下条件。
if(strcmp(input, "Encrypt\n") == 0)
{
/*
You will do what you want
*/
}
你可以使用上面的方式,或者你可以读取输入并将输入数组中的'\n'覆盖为'\0',然后像你之前那样进行比较。但是你必须使用strcmp。因为数组大小增加了。
这是使用fgets的正确方法。使用 fgets 是读取新行。
您必须为字符数组使用空字符。因为这是字符数组所必需的。
您使用 strcmp() 和 fgets() 的主动性很好,但需要以下理解:
1. fgets() 最多将 size-1 个字符写入缓冲区,然后以 '\0' 结束。在你的情况下,
fgets(input,7, stdin);
您提供了输入 "Encrypt"/"Decrypt"/"TurnOff"
但是
'input' 缓冲区得到的数据为 "Encryp"/"Decryp"/"TurnOf"
因为 size=7(只读取 (7-1)=6 个字符,fgets() 为 '\0' 字符保留的最后位置)。
您的 strncmp() 调用将与您当前的代码一起正常工作,因为对于 strncmp(),要比较的长度
n = strlen(输入) = 6;
6 个字符在 "Encrypt"/"Decrypt"/"TurnOff" 的所有三种情况下均匹配良好。
总结是您当前的代码可以正常工作,但违反了您的实际意图。您实际上想要阅读和比较选项字符串的全长。
编辑完成:修改建议:
#define SIZE 9 <-- EDIT : Change done here, instead of 7, size = 9 is used
to allow reading '\n' so that it does not affect
fgets() read in successive iteration
char input[SIZE];
fgets(input, SIZE, stdin); // read str is e.g. "Encrypt\n"
input[SIZE-2] = '[=11=]'; // To replace '\n' with '[=11=]'
同样,使用 fgets() 读入 'message' 数组时需要小心。
我是一名尝试学习 C 的初级程序员。目前我正在参加 class 并分配了一个项目,我设法很快完成了它,至少是它的主要部分。不过,我在围绕 main() if 函数进行编码时遇到了一些麻烦,因为我开始使用一些新函数(即 fgets 和 strncmp)。现在,我的代码可以在我的编译器中运行,但不能在任何在线编译器中运行。所以我想知道我是否做错了什么,或者是否有任何方法可以改进它。
感谢任何帮助或贡献,谢谢!
下面是代码,加密和解密函数是main之前的前两个函数,我相信大部分乱七八糟的shortcut-code可能是这里。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * Encrypt(char sentence[])
{
int primes[12] = {1,2,3,5,7,11,13,17,19,23,29,31};
int x = 0;
int counter = 0;
int ispositive = 1;
while(sentence[x] != 0)
{
if (counter == 0)
{
ispositive = 1;
}
else if(counter == 11)
{
ispositive = 0;
}
if (ispositive == 1)
{
sentence[x] = sentence[x] + primes[counter];
counter++;
}
else if (ispositive == 0)
{
sentence[x] = sentence[x] + primes[counter];
counter--;
}
x++;
}
return sentence;
}
char * Decrypt(char sentence[])
{
int primes[12] = {1,2,3,5,7,11,13,17,19,23,29,31};
int x = 0;
int counter = 0;
int ispositive = 1;
while(sentence[x] != 0)
{
if (counter == 0)
{
ispositive = 1;
}
else if(counter == 11)
{
ispositive = 0;
}
if (ispositive == 1)
{
sentence[x] = sentence[x] - primes[counter];
counter++;
}
else if (ispositive == 0)
{
sentence[x] = sentence[x] - primes[counter];
counter--;
}
x++;
}
return sentence;
}
int main()
{
char message[100];
char input[7];
char *p;
int c;
int condition = 1;
while(condition == 1)
{
printf("Would you like to Encrypt or Decrypt a message? (Type TurnOff to end the program) \n \n");
fgets(input,7, stdin);
fflush(stdin);
if (!strncmp(input,"Encrypt",strlen(input)))
{
printf("\n \n Enter the message you want to Encrypt below: \n \n");
fgets(message, 100, stdin);
Encrypt(message);
printf("\n Your encrypted message is: ");
printf("%s", message);
fflush(stdin);
printf("\n \n");
}
else if (!strncmp(input,"Decrypt",strlen(input)))
{
printf("\n \n Enter the message you want to Decrypt below: \n \n");
fgets(message, 100, stdin);
Decrypt(message);
printf("\n Your Decrypted message is: ");
printf("%s", message);
fflush(stdin);
printf("\n \n");
}
else if (!strncmp(input,"TurnOff",strlen(input)))
{
printf("\n \n Thank you for using the program! \n \n");
condition = 0;
}
else
{
printf("That's not a valid input \n \n");
}
}
}
在 printf 之后,您执行 fflush(stdin) 而不是必须执行 fflush(stdout)。因为您正在打印输出。输出打印在标准输出中。因此,您必须刷新 stdout 缓冲区而不是 stdin 缓冲区。
您可以使用 strcmp 而不是 strncmp。因为在这里你正在比较输入数组中的孔字符。所以,strcmp 就够了。
strcmp(输入,"Encrypt").
strcmp 或 strncmp 函数获取数组中的输入,最多为 null 或您声明的字符串的大小。
输入数组的大小太小。
让我们输入如下。
Encrypt\n sureshkumar\n
在这里,您首先在 main 函数中使用 fgets 读取最多 "Encrypt" 它不会跳过 '\n'。
'\n' 是从另一个 fgets 读取的。因此,它没有得到加密消息 "sureshkumar".
所以,你必须修改你的代码。您将增加输入数组的大小。
并检查如下条件。
if(strcmp(input, "Encrypt\n") == 0)
{
/*
You will do what you want
*/
}
你可以使用上面的方式,或者你可以读取输入并将输入数组中的'\n'覆盖为'\0',然后像你之前那样进行比较。但是你必须使用strcmp。因为数组大小增加了。
这是使用fgets的正确方法。使用 fgets 是读取新行。
您必须为字符数组使用空字符。因为这是字符数组所必需的。
您使用 strcmp() 和 fgets() 的主动性很好,但需要以下理解:
1. fgets() 最多将 size-1 个字符写入缓冲区,然后以 '\0' 结束。在你的情况下,
fgets(input,7, stdin);
您提供了输入 "Encrypt"/"Decrypt"/"TurnOff"
但是
'input' 缓冲区得到的数据为 "Encryp"/"Decryp"/"TurnOf"
因为 size=7(只读取 (7-1)=6 个字符,fgets() 为 '\0' 字符保留的最后位置)。
您的 strncmp() 调用将与您当前的代码一起正常工作,因为对于 strncmp(),要比较的长度
n = strlen(输入) = 6;
6 个字符在 "Encrypt"/"Decrypt"/"TurnOff" 的所有三种情况下均匹配良好。
总结是您当前的代码可以正常工作,但违反了您的实际意图。您实际上想要阅读和比较选项字符串的全长。
编辑完成:修改建议:
#define SIZE 9 <-- EDIT : Change done here, instead of 7, size = 9 is used
to allow reading '\n' so that it does not affect
fgets() read in successive iteration
char input[SIZE];
fgets(input, SIZE, stdin); // read str is e.g. "Encrypt\n"
input[SIZE-2] = '[=11=]'; // To replace '\n' with '[=11=]'
同样,使用 fgets() 读入 'message' 数组时需要小心。