[英]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 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
,而不是char
的pointer 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.