具有停止条件的数组

时间:2016-05-30 20:15:05

标签: c arrays

任务是:用户键入char数组,当最后两个值与第一个和第二个插入值匹配时,程序停止,然后它仅打印插入的int值。 / p>

例如,我输入:1,2,f,5,2,g,s,d,c,3,1,2

获得1,2,5,3

这就是我现在所拥有的

int main()
{
    setlocale(LC_ALL, "RUS");
    char* A;
    int i = 2, N;

    //making an array
    A = (char*)malloc(2 * sizeof(char));
    printf("Enter an array   \n");

    //entering the first value
    scanf_s("%c", &A[0]);
    //second value
    scanf_s("%c", &A[1]);

    //next values
    while (!(A[i - 1] == A[0] && A[i] == A[1]))
    {
        i++;
        A = (char*)realloc(A, (i + 1)*sizeof(char));
        scanf_s("%c", &A[i]);
    } 


    system("pause");
    return 0;
}

所以现在只有当第一个值匹配并且什么都不打印时它才会停止。我真的很困惑

1 个答案:

答案 0 :(得分:0)

您可以避免动态分配,只关注任务的逻辑。虽然您可以使用scanf来阅读字符输入,但使用面向字符的输入函数(例如getchar)可以更好地提供服务。

也就是说,您似乎想要读取stdin中的字符,只在数组中存储唯一数字,然后如果用户输入与数组中存储的前两个元素匹配的数字,则打印存储的值在数组和退出。 (如果我有任何错误,请在评论中告诉我)

首先,使用scanf读取字符可能有点挑剔,具体取决于分隔字符的值。但是,由于您只关心存储数字,这使事情变得更容易。

为了避免处理malloc,只需设置一些合理的限制来调整数组大小并检查存储的元素。您只需要一个简单的#define即可。例如:

#define MAXE 128

将定义一个常量MAXE(对于最大元素),在填充数组时进行测试。只需记下您添加到数组中的元素的数量,如果达到限制,请退出。

您希望继续读取字符,直到满足以下两个条件之一:(1)您已向数组添加128个值而没有退出条件,或者(2)输入的最后两个字符与{{中的数字存储区匹配1}}和a[0]。要设置您的阅读,您可以执行以下操作:

a[1]

注意: while (n < MAXE && scanf ("%c", &c) == 1) { ... 您可以避免不可移植的getchar()功能问题,以及_s系列函数的其他陷阱。使用scanf而不是将getchar()声明为c类型,将char声明为类型c,然后将您的作业更改为{{1}如下:

int

读完一个角色后,(无论怎样),你想测试它是否是一个数字,如果不是你没有存储它,它不能成为退出条件的一部分。因此,如果它不是数字,您可以简单地获取下一个字符:

c

注意: while (n < MAXE && (c = getchar()) != EOF) { 提供可用于代替人工检查的 if (c < '0' || '9' < c) continue; 功能。

您希望存储前两位数,并且在这两位数之后,您希望存储输入的任何新数字(尚未存储),因此您需要针对先前存储的所有数字测试当前数字以确保它是独特的数字。虽然您可以通过多种方式对逻辑进行编码,但在这种情况下,测试循环必须在决定存储当前数字之前测试所有存储的值。在这种情况下,以及在需要在嵌套循环中打破控制的情况下,低ctype.h语句是您最好的朋友。如果数字是重复的,则isdigit()只会跳过通过作业的goto标签:

goto

拼图的最后一部分是退出条件。这有点棘手(但只是解决了),因为你知道你不会在数组中存储前面的(或Leffler,倒数第二个)值以进行测试(它对于数组来说是非唯一的)。诀窍就是从最后一次迭代中保存字符以进行测试。 (可能在一个名为dupes的变量中)。现在您可以编写退出子句:

        if (n > 1)
            for (i = 0; i < n; i++)
                if (c == a[i])
                    goto dupe;
        a[n++] = c;
        dupe:;

总而言之,您可以执行以下操作:

last

您如何处理打印和错误情况取决于您。上面的内容只是关于如何覆盖你的基础的想法。

注意: gcc没有实现可选的 if (n > 2 && a[0] == last && a[1] == c) break; 功能,因此如果需要,您可以将更改回#include <stdio.h> #define MAXE 128 int main (void) { char a[MAXE] = "", c, last = 'a'; int i, n = 0; printf ("Enter an array\n"); while (n < MAXE && scanf ("%c", &c) == 1) { if (c < '0' || '9' < c) continue; if (n > 1) for (i = 0; i < n; i++) if (c == a[i]) goto dupe; a[n++] = c; dupe:; if (n > 2 && a[0] == last && a[1] == c) break; last = c; } if (n < 3) { fprintf (stderr, "error: minimum of 3 values required.\n"); return 1; } if (n == MAXE) { fprintf (stderr, "warning: limit of values reached.\n"); return 1; } printf ("Values in array: "); for (i = 0; i < n; i++) putchar (a[i]); putchar ('\n'); return 0; }

示例使用/输出

_s

仔细看看,如果您有任何疑问,请告诉我。

接受任何字符作为终止/仅存储唯一数字

如果您所解释的逻辑是跟踪前两个字符,无论它们是否为数字并允许任何字符作为前两个输入序列的终止检查,最简单的方法是简单地处理将输入的前两个字符存储在一个单独的数组(或两个变量)中,并检查针对它们输入的每个字符序列。

添加此类型检查只需稍微重新排列原件中的条件,以便在考虑仅存储阵列中的数字之前对输入的任何字符进行一些检查。

注意:添加了scanf_s(字符数)变量以跟踪输入的字符数,并添加$ ./bin/exitonmatch Enter an array 1 2 f 5 2 g s d c 3 1 2 Values in array: 1253 数组以保存输入的前两个字符。

例如:

cc
上面使用

注意: first,但如果您愿意,可以替换第一个示例中的 char a[MAXE] = "", first[TSTA] = "", last = 'a'; int c, cc = 0, i, n = 0; printf ("Enter an array\n"); while (n < MAXE && (c = getchar()) != EOF) { if (c < ' ') continue; /* skip non-print chars */ if (cc < 2) /* fill first[0] & [1] */ first[cc] = c; /* check term condition */ if (++cc > 2 && first[0] == last && first[1] == c) break; last = c; /* set last */ if (c < '0' || '9' < c) /* store only numbers */ continue; if (n > 1) /* skip duplicates */ for (i = 0; i < n; i++) if (c == a[i]) goto dupe; a[n++] = c; /* digit and not a dupe - store it */ dupe:; }

示例使用/输出

这里有前两个字符getcharscanf,尽管不是数字,但仍作为终止序列。

a