在将文件中的字符串与用户在C中输入的字符串数组进行比较时遇到问题
我试图研究这个问题,但找不到任何对我有帮助的东西。我一直在尝试使用在将文件中的字符串与用户在C中输入的字符串数组进行比较时遇到问题,c,arrays,string,compare,strcmp,C,Arrays,String,Compare,Strcmp,我试图研究这个问题,但找不到任何对我有帮助的东西。我一直在尝试使用fprint进行调试,但我仍然无法找到答案 我是一名中级程序员,如果我能在这里得到一些帮助,我会很高兴的。这是我的密码: int i = 0; const int arraySize = 10; char buf[256]; char str[256]; char buffer[256]; char *beerNames[arraySize] = { }; FILE *names; FILE *percent; i = 0; i
fprint
进行调试,但我仍然无法找到答案
我是一名中级程序员,如果我能在这里得到一些帮助,我会很高兴的。这是我的密码:
int i = 0;
const int arraySize = 10;
char buf[256];
char str[256];
char buffer[256];
char *beerNames[arraySize] = { };
FILE *names;
FILE *percent;
i = 0;
int numBeers = 0;
printf("Please enter a name or (nothing to stop): ");
gets(buf);
while (strcmp(buf, "") != 0) {
beerNames[i] = strdup(buf);
i++;
numBeers++;
if (numBeers == arraySize)
break;
printf("Please enter a name or (nothing to stop): ");
gets(buf);
}
// now open files and look for matches of names: //
names = fopen("Beer_Names.txt", "r");
percent = fopen("Beer_Percentage.txt", "r");
while (fgets(str, sizeof(str) / sizeof(str[0]), names) != NULL) {
fgets(buffer, sizeof(buffer) / sizeof(buffer[0]), percent);
for (i = 0; i < numBeers; i++) {
if (strcmp(str, beerNames[i]) == 0) {
printf("Beer: %s Percentage: %s\n", str, beerNames[i]);
break;
}
}
}
fclose(names);
fclose(percent);
我的Beer_Percentage.txt(缩写)如下所示:
Anchor Porter
Anchor Steam
Anheuser Busch Natural Light
Anheuser Busch Natural Ice
Aspen Edge
Big Sky I.P.A.
Big Sky Moose Drool Brown Ale
Big Sky Powder Hound (seasonal)
Big Sky Scape Goat Pale Ale
Big Sky Summer Honey Ale (seasonal)
Blatz Beer
Blatz Light
Blue Moon
5.6
4.9
4.2
5.9
4.1
6.2
5.1
6.2
4.7
14.7
4.8
0
5.4
names = fopen("Beer_Names.txt", "r");
percent = fopen("Beer_Percentage.txt", "r");
if (!names) {
perror("failed to open Beer_Names.txt");
exit(1);
}
if (!percent) {
perror("failed to open Beer_Percentage.txt");
exit(1);
}
这不是家庭作业,我只是在做一个个人项目,我试图在C上取得更好的成绩。你的问题是,它不会将换行符作为字符串的一部分返回,而会返回
因此,当使用gets读取用户输入的值“Anchor Porter”时,您的字符串看起来像这样“Anchor Porter\0”
,但是当您从带有fgets的文件中读取它时,它的结果是这样的“Anchor Porter\n\0”
,这将不会进行相等的比较。您的问题是没有将换行符作为字符串的一部分返回,而实际上是这样
gets(buf);
因此,当使用gets读取用户输入的值“Anchor Porter”时,您的字符串看起来像这样“Anchor Porter\0”
,但当您从带有fgets的文件中读取它时,它最终会像这样“Anchor Porter\n\0”
,这两个值不会相等
gets(buf);
我知道gets(3)
很方便,我知道这是一个玩具,但请不要使用gets(3)
。使用gets(3)
编写安全代码是不可能的,未来的C库甚至可能不包含此函数。(是的,我知道它是标准化的,但我们希望将来的版本会省略它;POSIX.1-2008已经删除了它。)合理的编译器会提醒您使用它。改用fgets(3)
while (fgets(str, sizeof(str) / sizeof(str[0]), names) != NULL) {
sizeof(char)
定义为1
。这不太可能更改,您也不太可能更改数组的类型。一般来说这没什么大不了的,但是你不能像你想象的那样经常使用这样的构造——你可以在这种情况下使用它,因为str[]
是在这一行的封闭范围内声明的。如果str
作为参数传递,则sizeof(str)
运算符将返回数据指针的大小,而不是数组的大小。不要太习惯这种构造——它不会总是像您所期望的那样工作
names = fopen("Beer_Names.txt", "r");
percent = fopen("Beer_Percentage.txt", "r");
while (fgets(str, sizeof(str) / sizeof(str[0]), names) != NULL) {
fgets(buffer, sizeof(buffer) / sizeof(buffer[0]), percent);
请花时间检查fopen(3)的成功与否。这是一个很好的习惯,如果你提供了一个好的错误消息,它也可能在将来为你节省时间。将fopen()
行替换为以下内容:
Anchor Porter
Anchor Steam
Anheuser Busch Natural Light
Anheuser Busch Natural Ice
Aspen Edge
Big Sky I.P.A.
Big Sky Moose Drool Brown Ale
Big Sky Powder Hound (seasonal)
Big Sky Scape Goat Pale Ale
Big Sky Summer Honey Ale (seasonal)
Blatz Beer
Blatz Light
Blue Moon
5.6
4.9
4.2
5.9
4.1
6.2
5.1
6.2
4.7
14.7
4.8
0
5.4
names = fopen("Beer_Names.txt", "r");
percent = fopen("Beer_Percentage.txt", "r");
if (!names) {
perror("failed to open Beer_Names.txt");
exit(1);
}
if (!percent) {
perror("failed to open Beer_Percentage.txt");
exit(1);
}
您可以将其封装到一个函数中,该函数执行fopen()
,检查返回值,然后打印错误消息并退出或返回文件*
对象
现在,把您带到这里的bug指出,fgets(3)
和gets(3)
以不同的方式处理输入的终止换行。(摆脱的另一个理由是尽快获得(3)
。)
我知道gets(3)
很方便,我知道这是一个玩具,但请不要使用gets(3)
。使用gets(3)
编写安全代码是不可能的,未来的C库甚至可能不包含此函数。(是的,我知道它是标准化的,但我们希望将来的版本会省略它;POSIX.1-2008已经删除了它。)合理的编译器会提醒您使用它。改用fgets(3)
while (fgets(str, sizeof(str) / sizeof(str[0]), names) != NULL) {
sizeof(char)
定义为1
。这不太可能更改,您也不太可能更改数组的类型。一般来说这没什么大不了的,但是你不能像你想象的那样经常使用这样的构造——你可以在这种情况下使用它,因为str[]
是在这一行的封闭范围内声明的。如果str
作为参数传递,则sizeof(str)
运算符将返回数据指针的大小,而不是数组的大小。不要太习惯这种构造——它不会总是像您所期望的那样工作
names = fopen("Beer_Names.txt", "r");
percent = fopen("Beer_Percentage.txt", "r");
while (fgets(str, sizeof(str) / sizeof(str[0]), names) != NULL) {
fgets(buffer, sizeof(buffer) / sizeof(buffer[0]), percent);
请花时间检查fopen(3)的成功与否。这是一个很好的习惯,如果你提供了一个好的错误消息,它也可能在将来为你节省时间。将fopen()
行替换为以下内容:
Anchor Porter
Anchor Steam
Anheuser Busch Natural Light
Anheuser Busch Natural Ice
Aspen Edge
Big Sky I.P.A.
Big Sky Moose Drool Brown Ale
Big Sky Powder Hound (seasonal)
Big Sky Scape Goat Pale Ale
Big Sky Summer Honey Ale (seasonal)
Blatz Beer
Blatz Light
Blue Moon
5.6
4.9
4.2
5.9
4.1
6.2
5.1
6.2
4.7
14.7
4.8
0
5.4
names = fopen("Beer_Names.txt", "r");
percent = fopen("Beer_Percentage.txt", "r");
if (!names) {
perror("failed to open Beer_Names.txt");
exit(1);
}
if (!percent) {
perror("failed to open Beer_Percentage.txt");
exit(1);
}
您可以将其封装到一个函数中,该函数执行fopen()
,检查返回值,然后打印错误消息并退出或返回文件*
对象
现在,把您带到这里的bug指出,
fgets(3)
和gets(3)
以不同的方式处理输入的终止换行。(还有一个原因需要尽快摆脱gets(3)
。gets()也被弃用,因为它无法检查缓冲区溢出。gets()也被弃用,因为它无法检查缓冲区溢出。非常感谢您的建议,我将确保从现在开始这样做!非常感谢你的建议,我会确保从现在起我会这么做!