1

我有这个数据库,我需要检查一个产品名称是否已经在数据库中,否则我要求用户输入另一个。

问题是这样的:

我正在尝试将结构内的字符串(产品名称)与用户输入的字符串进行比较。

结构体的编码、用户输入部分和搜索方法如下:

产品结构

typedef struct
{
    char    pName[100];
    char    pDescription [100];
    float   pPrice;
    int     pStock;
    int     pOrder;
}product;

checkProduct 方法:

int checkProduct (char nameCheck[100])
{
    product temp;
    p.pName = nameCheck;

    rewind (pfp);
    while (fread(&temp,STRUCTSIZE,1,pfp)==1)
    {
        if (strcmp (temp.pName,p.pName))
        {
            return 1;
        }
    }
    return 0;
}

和用户输入部分[部分代码]:

char nameCheck[100];
gets (nameCheck);
checkProduct (nameCheck);
while (checkProduct == 1)
{
    printf ("Product Already Exists!\n Enter another!\n");
    while (getchar() !='\n')
    {
        continue;
    }
}
p.pName = nameCheck;

现在我遇到以下错误(我使用 ECLIPSE):

在线时 (checkProduct == 1) [在用户输入中找到] 正在给我:“指针和整数之间的比较 - 默认启用”用黄色警告三角形标记

p.pName = nameCheck; 被标记为红十字并停止我的编译说:“从类型'char *'分配给类型'char [100]时不兼容的类型^----在用户输入和比较字符串时都给我带来麻烦.

有什么建议可以解决它,或者我可以如何尊重它?我不明白为什么在结构中 char pName 被标记为 '*' 而在 char[100] 中却不是。

请问有什么简要的解释吗?

先感谢您

编辑:用以下一些修改代码后:这是产品部分的输入名称;

char *nameCheck;
        nameCheck = "";
        fgets(nameCheck,sizeof nameCheck, stdin);

        checkProduct (nameCheck);

        int value = checkProduct (nameCheck);
        while (value == 1)
        {
            printf ("Product Already Exists!\n Enter another!\n");
            while (getchar() !='\n')
            {

            }
        }
        strcpy (p.pName, nameCheck);

这是新的 checkName 方法

int checkProduct (char *nameCheck)
{
    product temp;
    strcpy (p.pName, nameCheck);

    rewind (pfp);
    while (fread(&temp,STRUCTSIZE,1,pfp)==1)
    {
        if (strcmp (temp.pName,p.pName) == 0)
        {
            return 1;
        }
    }
    return 0;
}
4

2 回答 2

3
p.pName = nameCheck; 

当您尝试将一个数组的地址分配给另一个数组时是错误的。您可能想要的是复制它。

改为使用strcpy()

strcpy(p.pName, nameCheck);

while (checkProduct == 1)

由于 checkProduct 是一个函数,因此上述条件将始终为 false,因为函数的地址不会等于 1。您可以将返回值存储在另一个整数中,如下所示:

int value = checkProduct(nameCheck);
while (value == 1)
/* rest of the code */

或者更简单地说:

while ( checkProduct(nameCheck) == 1 ) {
...

注意 - 我没有检查整个代码,除了这个之外可能还有其他错误。顺便说一句,如果你是编程新手,你可以从教科书中的小例子开始,然后再研究稍微复杂的东西。

于 2012-12-21T19:04:56.143 回答
0
int checkProduct (char nameCheck[100])

请注意,类型签名是谎言。签名应该是

int checkProduct(char *nameCheck)

因为函数期望和接收的参数是指向 a 的指针char,或者,为了向用户记录参数应该是指向以 0 结尾的char数组的第一个元素的指针

int checkProduct(char nameCheck[])

数组永远不会作为参数传递给函数,作为函数参数,并且在大多数情况下[例外是当数组是 的操作数sizeof_Alignof地址运算符&时] 被转换为指向第一个元素的指针。

    {
        product temp;
        p.pName = nameCheck;

数组不可赋值。唯一可以在 a 左侧有一个数组名称的情况=是在声明数组的位置进行初始化。

你可能想要

strcpy(p.pName, nameCheck);

那里。

        rewind (pfp);
        while (fread(&temp,STRUCTSIZE,1,pfp)==1)
        {
            if (strcmp (temp.pName,p.pName))

strcmp如果第一个参数按字典顺序小于第二个参数,则返回负值;如果两个参数相等,则返回 0;如果第一个参数按字典顺序大于第二个参数,则返回正值。

你可能想要

if (strcmp(temp.pName, p.pName) == 0)

那里。

    gets (nameCheck);

永远不要使用gets. 这是非常不安全的(并且已从上一个标准中的语言中删除,是的)。采用

fgets(nameCheck, sizeof nameCheck, stdin);

但是如果有足够的空间,它会将换行符存储在缓冲区中,所以如果存在的话,你必须用它覆盖它0

如果您在 POSIX 系统上并且不需要关心可移植性,则可以使用getline()读取一行而不存储尾随换行符。

    checkProduct (nameCheck);

您检查产品是否已知,但丢弃结果。将其存储在变量中。

    while (checkProduct == 1)

checkProduct是一个函数。几乎在所有情况下,函数指示符都会转换为指针,因此会出现有关指针和整数比较的警告。您的意思是与您应该在上面存储的调用的值进行比较。

    {
        printf ("Product Already Exists!\n Enter another!\n");
        while (getchar() !='\n')

您读取字符而不存储它们。所以你永远不会改变 的内容nameCheck,然后陷入无限循环。

        {
            continue;
        }

如果循环主体中的唯一语句是continue;,则应将主体留空。

    }
    p.pName = nameCheck;

再一次,您不能分配给数组。


关于编辑,

char *nameCheck;
nameCheck = "";
fgets(nameCheck,sizeof nameCheck, stdin);

nameCheck已从数组更改为指针。这意味着sizeof nameChecknow 没有给出char可以存储在数组中的 s 的数量,而是指向 的指针的大小char,这与它所指向的内容无关(通常在 32 位系统上为 4,在 64 位系统上为 8 )。

你让那个指针指向一个字符串字面""量,这就是崩溃的原因。尝试修改字符串文字是未定义的行为,并且通常会导致崩溃,因为现在字符串文字通常存储在内存的只读段中。

你应该把它留在

char nameCheck[100];
fgets(nameCheck, sizeof nameCheck, stdin);

然后你可以用它sizeof nameCheck来告诉fgets它可以读取多少个字符,或者,你可以有一个指针和malloc一些内存,

#define NAME_LENGTH 100
char *nameCheck = malloc(NAME_LENGTH);
if (nameCheck == NULL) {
    // malloc failed, handle it if possible, or
    exit(EXIT_FAILURE);
}
fgets(nameCheck, NAME_LENGTH, stdin);

无论哪种方式,在获得输入后,如果有换行符,请删除换行符:

size_t len = strlen(nameCheck);
if (len > 0 && nameCheck[len-1] == '\n') {
    nameCheck[len-1] = 0;
}
// Does windows also add a '\r' when reading from stdin?
if (len > 1 && nameCheck[len-2] == '\r') {
    nameCheck[len-2] = 0;
}
于 2012-12-21T19:24:00.937 回答