繁体   English   中英

我的循环不会检查C中数组的所有元素

[英]My Loop Won't Check All Elements Of Array in C

#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) 但是,当我逐个元素地循环时,它在第二个元素之后冻结。 我的测试数据是“ aaaa”,并显示“ aaaa”,因此我知道我的前两个功能可以正常工作。 我进入循环,它遍历第一个元素,打印“作品”,然后冻结。 :/

多重错误

void getString(char *a[])

应该

void getString(char a[])

由于您要发送的array of char的基地址,而不是array of pointer to chararray 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 ,而不是charpointer to char

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

注意:使用main()的标准定义

int main(void) //if no command line arguments.

如果输入的是11个字符的字符串,则应该这样做:

char originalString[12] = { 0 };

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

这可能就是为什么在您的函数getString(...) ,指针超出了数组范围并可能调用未定义的行为。

最后,您的getString(...)函数原型应该是

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

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

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

就目前而言,您无法防止11 character数组溢出(这意味着您的用户最多可以输入10 characters再加上一个字符以空格结尾 )。 为了防止用户输入超过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.

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

这个

  char originalString[11] = { 0 };

跟着这个

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

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

您将char类型的对象传递给接受char *的函数

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

 int determinIfConvert(char *a)

字符串不过是一组以N结尾的字符集,因此,如果您希望在字符串中包含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个字符。 如果发生溢出,则会修剪其余的输入,并将“ \\ 0”分配给第12个字节。

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

if (a == 97)

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

请记住,您可能需要包括string.h标头才能使用islower()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM