读取整数字符串并使用它们创建数组

时间:2017-05-18 17:10:29

标签: c arrays string pointers

我想从stdin读取一个整数字符串,然后检查字符串中的所有内容是否为整数,然后在int数组中添加它们的值。我希望这发生在用户决定停止之前。在第一个循环中没问题,但在第二个循环不起作用,没有任何内容被读取,“你只需要输入数字!”打印并退出程序。也许fgets不起作用? 这是我的代码:

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

int main() 
{
    char str[200], *token, *rest;
    int *numbers;
    int number, size = 0, index=0, i, answer;
    bool hasOnlyNums=true;

        do {
        printf("Enter a sequence of integers: ");
        fgets(str,200,stdin);
        printf("The string you entered is %s\n",str);
        rest = (char*) malloc(200 * sizeof (char));
        strcpy(rest, str);
        numbers = (int *) malloc(sizeof (int));

        while ((token = strtok_r(rest," ", &rest))) {
            if (atoi(token) != 0) {

                size++;
                number = atoi(token);
                numbers = (int *) realloc(numbers, size * sizeof (int));
                *(numbers + index) = number;
                index++;

            } else {
                hasOnlyNums = false;
                break;
            }
        }


        if (!hasOnlyNums) {
            printf("you have to enter only numbers!\n");
            break;
        }

        printf("\nType 0 for exit or any number to continue.\n");
        scanf("%d", &answer);

        free(numbers);
        free(rest);
        size = 0;
        index=0;
        memset(str,0,200);

    } while (answer != 0);

    return 0;
}

2 个答案:

答案 0 :(得分:1)

我在这里看到很多问题,但现在可能阻止你的问题是你错误地使用了strtok_r()。尝试这样的循环:

# this variable is for the use of strtok, don't use it for anything else
char *tokstate;

# initialize strtok and get the first token
token = strtok_r(rest, " ", &tokstate);
while(token != NULL) {
    # you got a token
    # do something with token

    # this is the last thing in your loop
    # passing NULL to strtok tells it to continue working on the string
    # you initialized it with.  It has the pointer to where it left off 
    # stored in tokstate so it doesn't need to know about rest anymore. 
    token = strtok_r(NULL, " ", &tokstate);
}

答案 1 :(得分:0)

问题在于您使用strtok_r的方式。

第一次调用strtok_r时,第一个参数指向要解析的字符串。在后续调用中,第一个参数应为NULL。此外,您正在传递保存指针的rest地址,这是要解析的字符串。这会修改rest,以便在您拨打free时,它不会指向同一个地方。如上所述,这也不是使用此功能的正确方法。

您需要为第三个参数使用单独的指针。此外,您应该在循环之前使用非null第一个参数调用strtok_r,然后在末尾使用null第一个参数调用它。

char *saveptr;
token = strtok_r(rest," ", &saveptr);
do {
    ...
} while ((token = strtok_r(NULL," ", &saveptr)));