c - fgets 在 C 中导致无限循环

标签 c for-loop fgets

看来我对 fgets() 的实现在这里是不正确的,非常感谢一些额外的眼睛来检查我所做的事情!

这是代码

int main(int argc, const char* argv[]){
    int numIntegers;
    char buffer[20];
    int intArray[10];
    //if no argument is passed in, terminate
    if (argc == 1){
            printf("no argument given, terminating..\n");
            return EXIT_FAILURE;
    }
    else{
            numIntegers = atoi(argv[1]);
            //we only want numbers greater than 0
            if (numIntegers <= 0){
                    printf("# must be greater than 0\n");
                    return EXIT_FAILURE;
            }
            else{
                    printf("Enter %d integer values to place in array: \n", numIntegers);
                    for (int i = 0; i < numIntegers; i++){
                            fgets(buffer, numIntegers, stdin);
                            intArray[i] = atoi(buffer);
                            printf("Index is = %d \n", i);
                    }
            }
    }

    //for (int i =0; i < numIntegers; i++){
    //      printf("Index[%d] = %d \n", i, intArray[i]);
    //}
}

这是输出,除整数外没有其他文本的行是用户输入。注意 i 的值是如何重置的。仅当我给出的初始参数大于 10 时才会出现此问题。无论出于何种原因,它都会将 for 循环变成无限循环。

$ ./a.out 11
Enter 11 integer values to place in array:
5
Index is = 0
2
Index is = 1
1
Index is = 2
2
Index is = 3
3
Index is = 4
4
Index is = 5
123
Index is = 6
123
Index is = 7 
123
Index is = 8
1
Index is = 9
2
Index is = 2
2
Index is = 3
3
Index is = 4
5
Index is = 5
1
Index is = 6
12
Index is = 7

最佳答案

您正在使用

fgets(buffer, numIntegers, stdin);

第二个参数应该是缓冲区的大小——在你的例子中是 20。这至少是一个明显的问题......

下一个问题:您允许 numIntegers 大于 10 - 因此您将写入超出 intArray 末尾的值。也需要解决这个问题......

if(numIntegers > 10) {
  printf("cannot have number greater than 10!\n");
  // abort, retry, ignore...
}

事实上 - 这是您的代码,已解决错误:请注意为 BUFSIZEMAXNUM 使用定义的大小,这样您就不必更改如果您改变主意,它会出现在多个地方...

#include <stdio.h>
#define BUFSIZE 20
#define MAXNUM 10
#define EXIT_FAILURE 0

int main(int argc, const char* argv[]){
    int i, numIntegers;
    char buffer[BUFSIZE];
    int intArray[MAXNUM];
    //if no argument is passed in, terminate
    if (argc == 1){
            printf("no argument given, terminating..\n");
            return EXIT_FAILURE;
    }
    else{
            numIntegers = atoi(argv[1]);
            //we only want numbers greater than 0
            if (numIntegers <= 0 || numIntegers > MAXNUM){
                    printf("# must be greater than 0 and less than %d!\n", MAXNUM);
                    return EXIT_FAILURE;
            }
            else{
                    printf("Enter %d integer values to place in array: \n", numIntegers);
                    for (i = 0; i < numIntegers; i++){
                            fgets(buffer, BUFSIZE, stdin);
                            intArray[i] = atoi(buffer);
                            printf("Index is = %d \n", i);
                    }
            }
    }
 }

最后 - 您可能想知道为什么您的整数计数器似乎“重置”了?好吧 - 你的 intArray 是堆栈上的 10 个整数 block ;当您声明循环变量 i 时,它占据内存中的 next 位置(因为 int intArray[10]; 是最后一次变量在你到达 for 循环之前声明) - 当你“索引”到 intArray[10] (一个你不允许的内存位置访问,但你还是做了)。您碰巧输入了值 2 - 因此,i 被重置为 2...

如果您在程序开始时声明了 i(就像我所做的那样,因为我的编译器默认情况下不“执行”C99 - 我已经那么老了!),问题会以不同的方式出现——或者根本没有。

关于c - fgets 在 C 中导致无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19258828/

相关文章:

C -FILE I/O 分段故障核心已转储?

c - 没有将分配内存的实际大小获取到指针

arrays - 在 Swift 2.2 中附加数组时使用 'subscript' 不明确

C 编程,从文件中读取整数并将其重写为字母

c - 获取字符串并转换为 double

C程序打印文件中的第一行和最后n行,我做错了什么?

C代码注入(inject)

c - 程序将运行 while 循环,但不会运行函数

c - 在一行中使字符串为空

Java 默默地无法从数组打印