C 做你不做的事';t循环返回,但让值通过

C 做你不做的事';t循环返回,但让值通过,c,C,我试图制作一个程序,将一个字符串添加到一组字符串中,但对现有字符串部分的检查不起作用。它只是通过do while并直接添加到列表中 void Add(char index[MAXN][24], int *pi) { char name[24]; int n, name_check; do { printf("Add a student : "); fflush(stdin); scanf("%23[^\n]", name);

我试图制作一个程序,将一个字符串添加到一组字符串中,但对现有字符串部分的检查不起作用。它只是通过do while并直接添加到列表中

void Add(char index[MAXN][24], int *pi)
{
    char name[24];
    int n, name_check;
    do {
        printf("Add a student : ");
        fflush(stdin);
        scanf("%23[^\n]", name);
        name_check = 1;
        for (n = 0; n < *pi; n++)
            if (strcmp(name,index[n]) == 0) 
                {
                    printf("Existing name found.\n");
                    name_check = 0;
                    n = *pi - 1;
                }
    } while (!name_check);
    strcpy(index[*pi], Trim(name));
    (*pi)++;
    printf("Added.\n");
}
void添加(字符索引[MAXN][24],int*pi)
{
字符名[24];
int n,name_check;
做{
printf(“添加学生:”);
fflush(stdin);
scanf(“%23[^\n]”,名称);
name_check=1;
对于(n=0;n<*pi;n++)
if(strcmp(名称,索引[n])==0)
{
printf(“找到现有名称。\n”);
name_check=0;
n=*pi-1;
}
}而(!name_check);
strcpy(索引[*pi],修剪(名称));
(*pi)++;
printf(“已添加。\n”);
}

您的问题来自这一行:

将名称一直读到换行符,换行符是而不是read,因为fflush(stdin);不执行任何操作新行仍然可用,因此在第一次调用Add时读取一个名称后,下一次输入仅包含新行,并且没有读取任何内容,因此使用name not initialized具有未定义的行为

将线路更换为

scanf(" %23[^\n]", name);
这样做可以绕过可能的换行符和其他开始输入的空格,这也有很大的优势,在输入以9个空格开始的情况下,读取名称的长度不限制为13

执行最小值,因此删除无用的fflush并修改scanf的格式,并添加修剪,而不执行任何操作:

#include <stdio.h>
#include <string.h>

char * Trim(char *s)
{
      return s;
}

#define MAXN 10

void Add(char index[MAXN][24], int *pi)
{
    char name[24];
    int n, name_check;
    do {
        printf("Add a student : ");
        scanf(" %23s", name);
        name_check = 1;
        for (n = 0; n < *pi; n++)
            if (strcmp(name,index[n]) == 0) 
                {
                    printf("Existing name found.\n");
                    name_check = 0;
                    break;
                }
    } while (!name_check);
    strcpy(index[*pi], Trim(name));
    (*pi)++;
    printf("Added.\n");
}


int main()
{
  char index[MAXN][24];
  int p = 0;
  int i;

  Add(index, &p);
  Add(index, &p);
  for (i = 0; i != p; ++i)
    puts(index[i]);

  return 0;
}
我鼓励您始终检查scanf的值,如果您检查了,您能够检测到它返回0,但第一次发现错误时除外

另一个问题是,scanf不会删除名称末尾的空格,读取名称后,您需要立即对其进行修剪,然后将其与记忆的名称进行比较。在您的代码中,如果我们忘记了换行符not flush,您输入“aze”,然后输入“aze”等,您将保存两次“aze”(当然,所有输入都不带“'”)


因此,您的程序可以简化,例如,您不需要名称,因为您可以读取索引[*pi]直接保存strcpy,name\u check也没用,因为你可以在循环后检查n的值,或者将函数的结尾移到循环中,然后返回等等。

可能它没有打印
找到的现有名称。
也没有。因此
name\u check
1
,循环退出。请回答问题并显示ve给定输入的rbatim输出。解决问题fflush(stdin);不执行任何操作,不执行“n=*pi-1;“就做一个break@TomKarzes是的,就是这样。@hanie OP当然希望相反,不要在数组中重复名称以供您输入,但我认为问题正如@Jabberwocky所描述的。您的代码本身工作正常,但在我尝试更改代码时没有。不幸的是,我的老师禁止使用get和put.get mus“我不能肯定,这是非常危险的,我在回答中谈到了FGET。显然,修剪功能是问题所在,在我清理了乱七八糟的代码后,它就自行修复了。我说,要表示除scanf之外的任何东西,我不知道为什么我的老师不喜欢学生在前面使用东西,但我必须这样做。@Miguel neve”r使用gets,使用fgets。我编辑了我的答案,以防你也不能使用fgets,甚至你也可以使用它。警告:只需调用trim,请阅读我的答案末尾answer@Miguel我再次编辑了我的答案以简化它,立即谈到了“%23s”
#include <stdio.h>
#include <string.h>

char * Trim(char *s)
{
      return s;
}

#define MAXN 10

void Add(char index[MAXN][24], int *pi)
{
    char name[24];
    int n, name_check;
    do {
        printf("Add a student : ");
        scanf(" %23s", name);
        name_check = 1;
        for (n = 0; n < *pi; n++)
            if (strcmp(name,index[n]) == 0) 
                {
                    printf("Existing name found.\n");
                    name_check = 0;
                    break;
                }
    } while (!name_check);
    strcpy(index[*pi], Trim(name));
    (*pi)++;
    printf("Added.\n");
}


int main()
{
  char index[MAXN][24];
  int p = 0;
  int i;

  Add(index, &p);
  Add(index, &p);
  for (i = 0; i != p; ++i)
    puts(index[i]);

  return 0;
}
/tmp % gcc -Wall d.c
/tmp % ./a.out
Add a student : aze
Added.
Add a student : aze
Existing name found.
Add a student : qsd
Added.
aze
qsd
/tmp %