将由空格分隔的数字字符串转换为int数组

时间:2017-09-07 14:25:49

标签: c

我试图构建一个递归函数,该函数获取一个字符串(char数组),该字符串应包含由空格或制表符分隔的数字,以及应插入的数字量,并将每个数字插入到int数组中。 我不能为这个函数使用任何循环,只能递归。 两个数字之间的空格和制表符数量未知。 (虽然char数组是1000个字符缓冲区) 我使用gets_s作为输入字符串。 如果字符串中存在错误的字符或插入的数字的数量不正确,则该函数将打印错误并重新启动(再次清除任何循环)。 允许使用+/-符号和前导零(001)。

到目前为止,我有一个函数获取一个包含有效数字的char数组,并将其值返回为int(例如{'-','1','5','\0'}将返回-15)。

将字符串转换为int数组以便在程序中使用此数组的最佳方法是什么?

由于

3 个答案:

答案 0 :(得分:1)

在我写的评论中:

  

这种"不使用最合适的工具来解决问题。问题应该是你的红旗;你的资源,无论它是什么,都在教你以不恰当的方式解决问题。为什么在现实世界中,任何人都不会在C中使用循环?或者,如果作者想要教授函数式编程,为什么他们会使用非函数式语言? 获得更好的书籍

尽管如此,我发现自己在回答......

首先,他们在技术上都是循环!当你说无法使用任何循环时,我会收集你,你实际上指的是程序循环(即从goto构建的循环,whiledo...whilefor),而不是功能循环(由递归函数应用程序构建)。他们在技术上都是循环,而且由于C是一种过程语言,你应该使用程序循环。尽管如此...

有一个模式!只需观察和复制模式,就可以将程序循环转换为功能循环。也就是说,每个程序循环都有一个等效的功能循环,它们最终看起来非常相似。寻找下面的模式。

这是一个包含基本程序循环的函数:

void procedural_loop_on_str(char const *source, size_t source_position, int *dest, size_t dest_position) {
    while (source[source_position] != '\0') {
        source_position++;
    }
}

......这里它是一个功能循环:

void functional_loop_on_str(char const *source, size_t source_position, int *dest, size_t dest_position) {
    if (source[source_position] != '\0') {
        source_position++;
        functional_loop_on_str(source, source_position, dest, dest_position);
    }
}

两段代码看起来非常相似,不是吗?任何程序循环都可以基于这种观察而简单地转换为功能等价物;所有你要做的就是添加填充循环的额外代码。作为练习,请考虑隔离此代码中相同的部分。它们通常位于两段代码中的相同位置;他们不难发现!事实上,这些差异是并排的:

    while ...                                  if ...
                                                   functional_loop_on_str...

当需要回溯时,唯一的困难就出现了,这与这个问题无关。因此,您应该能够编写过程版本并轻松地将其转换为功能版本。请允许我开始你:

void procedural_loop_on_str(char const *source, size_t source_position, int *dest, size_t dest_position) {
    while (source[source_position] != '\0') {
        int value, nbytes, success = sscanf(source + source_position, "%d%n", &value, &nbytes);
        if (!success) { nbytes = 1; }
        else { /* XXX: You do this part!
                *      You need to do something with value, dest and dest_position */
        }
        source_position += nbytes;
    }
}

...在这里它被复制模式翻译成我们的功能版

void functional_loop_on_str(char const *source, size_t source_position, int *dest, size_t dest_position) {
    if (source[source_position] != '\0') {
        int value, nbytes, success = sscanf(source + source_position, "%d%n", &value, &nbytes);
        if (!success) { nbytes = 1; }
        else { /* XXX: You do this part!
                *      You need to do something with value, dest and dest_position */
        }
        source_position += nbytes;
        functional_loop_on_str(source, source_position, dest, dest_position)
    }
}

注意两个例子之间实际上有多少变化;大多数模式仍然存在!回想一下上面的练习?那么,你可以在这里做同样的事情,发现在从程序转换为功能时,在同一个地方进行了相同的更改。

我认为,如果您阅读了一本关于函数式编程的(更好的)书和一本关于C编程的(更好的)书籍,或者甚至自己创建这些基本示例来观察模式,这种模式对您来说是显而易见的。尽管如此,我坚持自己的信念:

  1. 你不应该在C或任何程序语言中使用功能循环,但具体来说不是 C;如果C是为日常功能循环而设计的,那么标准中就有优化保证。如果您的导游另有指导,请考虑选择一本新的指南,例如带有巨型蓝色" C"的书,由C Kernighan& S的创始人编写。 Richie(选择第二版)。我会让你找到那个。
  2. 您不应该使用过程语言来学习功能元素。这是一个明智的做法。考虑方案;那里有一本非常好的NICE"向导书"关于Scheme!
  3. 无论哪种方式,您似乎需要一本更好的书

答案 1 :(得分:0)

将指向整数数组末尾的指针作为函数的参数传递,并作为指向字符串中当前字符的指针。如果不是空格,请将数字添加到int数组并增加int指针。增加char指针appropriat reaurless和recurse。我假设你可以处理将字符串转换为int的问题,如果没有,有很多帖子可以帮助你。

答案 2 :(得分:0)

sscanf听起来像你需要的工具。这是我会使用的那个。您可以递归地将字符串读入int数组。我还会创建一个包含501个位置的int数组,因为这是你可以获得的最大数量的int(如果每个int只是一个数字,并且它们之间只有一个空格)。

或者您可以使用atoi