My Loop不会在C中检查数组的所有元素

时间:2016-04-07 04:28:28

标签: c arrays loops for-loop

#define _CRT_SECURE_NO_WARNINGS

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

void displayString (const char *sPtr);
void getString (char *[]);
int determinIfConvert (char);

int main ()
{
    char originalString[11] = { 0 };
    char convertedString[11];
    getString (originalString);
    displayString (originalString);

    // this loop runs through the "originalString" to check for the char: 'a'
    for (int i = 0; i < 11; i++) {
        determinIfConvert (originalString[i]);
    }
    system ("pause");
}

void getString (char *a[])  // this function gets a string
{
    printf ("enter 11 char string: \n");
    scanf ("%s", a);
}

// this program displays the inputstring
void displayString (const char *sPtr)
{
    for (; (*sPtr != '\0'); ++sPtr) {
        printf ("%c", *sPtr);
    }
}

int determinIfConvert (char *a)
{
    if (a == 97)            // this is a test condition. The goal is to
                            // check for all lowercase, but now i'm
                            // only entering "aaaaa"
    {
        printf ("Works");   // if it prints multiple"works"
                            // then i can continue my program
                            // but it only prints ONE "works" and freezes.
    }

}

目前,main()的For循环问题没有完成。目标是输入一个字符串,然后检查小写字符。这将使用函数DeterminIfConvert(char)完成。但是,当我按元素遍历循环元素时,它会在第二个元素之后冻结。我的测试数据是&#34; aaaa&#34;并打印出&#34; aaaa,&#34;所以我知道我的前两个功能工作正常。我进入循环,它通过第一个元素,打印&#34;工作&#34;然后冻结:/

6 个答案:

答案 0 :(得分:1)

多重错误

void getString(char *a[])

应该是

void getString(char a[])

由于您发送的是array of char的基地址,而不是array of pointer to char

char *a[];  // array of pointer to char
char a[];   // array of char
 int determinIfConvert(char *a)

应该是

int determinIfConvert(char a)

由于您发送的是char,而不是pointer to char

char * a;    // pointer to char
char a;      // char

注意: 使用main()

的标准定义
int main(void) //if no command line arguments.

答案 1 :(得分:1)

如果您输入的是11-char字符串,那么您应该这样做:

char originalString[12] = { 0 };

这是因为您还需要一个字符来存储空字符'\0'

这可能就是为什么在你的函数getString(...)中,指针超出数组边界并且可能会调用未定义的行为。

最后,getString(...)的函数原型应为

void getString(char a[]); //without the *

答案 2 :(得分:1)

除了其他答案之外,您还可以在其他几个方面改进代码。

避免在代码中使用幻数(例如11)。而是为字符串#define MAXC 11中的最大字符定义常量,或者使用enum代替enum { MAXC = 11 };

目前的情况是,您无法防止11 character数组溢出(这意味着您的用户只能输入10 characters以及 nul-terminated 的空间字符)。为了防止用户输入超过10的内容,您应该在scanf中使用字段宽度说明符:

    scanf ("%10s", a);

这并不能解决scanf的问题。您必须每次都检查返回,以确保发生预期的转换次数,例如:

if (scanf ("%10s", a) != 1) {
    fprintf (stderr, " -> error: invalid input.\n");
    exit (EXIT_FAILURE);
}

那样更好,但是使用%s,您无法读取包含空格的字符串,并且您仍然在输入缓冲区中留下尾随'\n'。如果用户输入"my dog",则仅存储"my"。要解决部分问题,您可以使用格式说明符"%10[^\n]%*c"。但是,如果用户在没有其他输入的情况下按 [Enter] ,则必须防止无限循环。要解决所有问题,并防止将尾随换行符保留在输入缓冲区中,您可以使用以下内容:

int getString (char *a)  // this function gets a string
{
    int c, rtn = 0;
    printf ("enter string (10 char or less): ");
    while ((rtn = scanf ("%10[^\n]%*c", a)) != 1) {
        if (rtn == EOF)
            break;
        fprintf (stderr, " -> error: invalid input, try again..\n");
        printf ("enter string (10 char or less): ");
        /* flush input buffer - to avoid endless loop */
        while ((c = getchar()) != '\n' && c != EOF) {}
    }

    return rtn;
}

所有这些都使用scanf来解决用户输入的困难。更好的方法可能是使用fgets(或getline)来读取完整的输入行。

无论您使用scanf还是fgets等等,您都必须花一点时间和精力编写输入处理程序,以确保您尝试覆盖用户可以输入的所有方式。 fgets以下仅用于提供替代方案。您还应该选择一种返回类型,以便判断您是否已成功接收输入。它也许是一个有用的回报,例如所输入的长度等等。

其他答案已解决了指针间接问题的其余部分。把它们放在一起,你可以做类似的事情:

#define _CRT_SECURE_NO_WARNINGS

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

#define MAXC 11

void displayString (const char *sPtr);
int getString (char *);
int determinIfConvert (char);

int main (void)
{
    char originalString [MAXC] = "";
    // char convertedString[MAXC] = "";  /* currently unused */
    if (!getString (originalString)) {
        fprintf (stderr, "error: getString failed.\n");
        return 1;
    }
    displayString (originalString);

    // this loop runs through the "originalString" to check for the char: 'a'
    for (int i = 0; i < 11; i++) {
        determinIfConvert (originalString[i]);
    }
    system ("pause");
    return 0;          /* main() is type 'int' and returns a value */
}

int getString (char *a)  // this function gets a string
{
    char *p = a;
    int c;
    size_t len = 0;

    printf ("enter string (10 char or less): ");
    for (;;) {
        p = fgets (a, MAXC, stdin);
        if (!p) break;          /* handle [CTRL+D]  */
        if (*p == '\n') {       /* handle empty str */
            fprintf (stderr, " -> error: invalid input, try again..\n");
            printf ("enter string (10 char or less): ");
            continue;
        }
        /* trim newline/flush input buffer */
        len = strlen (p);
        if (len && a[len - 1] == '\n')
            a[--len] = 0;
        else  /* user entered more than 10 chars */
            while ((c = getchar()) != '\n' && c != EOF) {}
        break;
    }

    return (int) len;
}

// this program displays the inputstring
void displayString (const char *sPtr)
{
    for (; *sPtr; sPtr++) {
        printf ("%c", *sPtr);
    }
    putchar ('\n');
}

int determinIfConvert (char a)
{
    if (a == 97)
        printf ("Works\n");
    return 0;
}

示例使用/输出

$ ./bin/getdispstr
enter string (10 char or less): my dog has fleas
my dog has
Works

$ ./bin/getdispstr
enter string (10 char or less):
 -> error: invalid input, try again..
enter string (10 char or less): my dog has fleas, my cat has none.
my dog has
Works

使用CTRL + D(EOF)

$ ./bin/getdispstr
enter string (10 char or less): error: getString failed.

有很多方法可以做到这一点,这只是一个例子。查看所有答案,如果您有任何疑问,请告诉我。

答案 3 :(得分:0)

这个

  char originalString[11] = { 0 };

接下来是

for (int i = 0; i < 11; i++)
    {
        determinIfConvert(originalString[i]);
    }

造成了这个问题。您看到char数组没有index 0后的元素。是的,我相信你想要尝试的东西 getString(originalString);似乎想要从用户输入中获取originalString,这在您的情况下未正确执行。

答案 4 :(得分:0)

char 类型的对象传递给接受 char *

的函数
 char originalString[11] = { 0 };
 determinIfConvert(originalString[i]);

 int determinIfConvert(char *a)

答案 5 :(得分:0)

一个字符串只是一个空终止的字符集,所以如果你想在你的字符串中有11个字符,你应该为你的字符分配12个字节 数组,即你可以改变:

char originalString[11] = { 0 };

char originalString[12] = ""; 

/* Here is the string is empty but because you use double quotes  
 * compiler understands that you are initializing a string, so '\0' is auto  
 * appended to the end of it by the compiler to mark the end of the string.
 */

convertedString[11]将其更改为

的情况也是如此
char convertedString[12] = ""; 

更改

void getString(char *a[]); 

void getString(char a[]); //char *a is also fine

更改

int determinIfConvert(char *a)

int determinIfConvert(char a) // You wish to check a character

您可能希望替换

scanf("%s", a);

fgets(a,12,stdin);

因为scanf无法检查溢出但fgets可以。在这里,字符串中最多可包含11个字符。如果发生溢出,则修剪输入的其余部分并且&#39; \ 0&#39;被分配到第12个字节。

您可能希望使用islower函数来检查字符是否为小写。所以你可以改变

if (a == 97)

if (islower(a)) // check if a character is lowercase.

请注意,您可能需要添加string.h标头才能使用islower()