Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在将文件中的字符串与用户在C中输入的字符串数组进行比较时遇到问题_C_Arrays_String_Compare_Strcmp - Fatal编程技术网

在将文件中的字符串与用户在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()也被弃用,因为它无法检查缓冲区溢出。非常感谢您的建议,我将确保从现在开始这样做!非常感谢你的建议,我会确保从现在起我会这么做!