如何从包含字符和整数的行解析整数

时间:2016-04-20 03:02:23

标签: c++ c

对于C / C ++赋值,我需要输入一个输入行,从字符'开始,然后是UP TO 3个单独的整数。我的问题是,没有载体,我不知道如何计算未知数量的整数(1-20)。

例如,测试输入看起来像:

s 1 12 20

有人建议我使用cin.getline并将整行作为一个字符串,但是我怎么知道每个整数在字符数组中的位置,因为可能有单个或两个数字,更不用说数字了所述字符串中的整数?

4 个答案:

答案 0 :(得分:0)

从该行的内容构造std::istringstream,然后继续使用operator>>int,直到fail()为止,将每个整数填充到{{1} (最初使用std::vector后,一次,以照顾主角)。

答案 1 :(得分:0)

您可以使用动态内存分配来模拟向量。最初使用int *a = new int[2];

创建一个大小为2的数组

当此数组填满时,创建一个大小为double的新数组,复制新数组并将其重新分配给新数组。继续这样做,直到满足要求为止。

修改 所以通过字符串流获取数字,如果数组填满,你可以这样做:

int changeArr(int *a, int size){
    int *b = new int[size*2];
    for(int i=0;i<size;i++){
        b[i] = a[i];
    }
    a = b;
    return size*2;
}

int getNos(istringstream ss){
    int *a = new int[2];
    int cap = 2, i=0, number;
    while(ss){
        if(i>=cap){
            cap = changeArr(a, cap);
        }
        ss >> a[i];
        i++;
    }
}

我已经跳过关于第一个角色的部分,但我想你可以处理它。

答案 2 :(得分:0)

由于不允许使用向量,因此在创建数组之前,您需要找出行中有多少个数字。

我不会只给你整个代码,因为这是作业,但我会告诉你我将采取什么措施来解决你的问题。

如果您的行总是如下所示:“s number”或“s number number”或“s number number number”,那么您可以通过计算空格来轻松找到行中的数字!

任何字符串中都有一个空格,其中一个数字(在s和该数字之间),并且每个数字后面的第一个空格还有一个空格。

所以让我们计算空间!

int countSpaces(string s) {
    int count = 0;

    for (int i = 0; i < s.size(); i++) {
        if (s[i] == ' ') {
            count++;
        }
    }

    return count;
}

传递这些字符串:

string test1 = "s 123 4 99999";
string test2 = "s 1";
string test3 = "s 555 1337";

countSpaces函数会给我们:

3
1
2

有了这些信息,我们可以创建一个具有正确大小的数组来保存每个值!

修改

现在我意识到你在抓住字符串中的数字时遇到了麻烦。

我会做的是使用上面的方法来查找行中的数字。然后,我将使用std::string.find()函数来确定字符串中的任何空格的位置和位置。

所以我们说我们有一行:s 123 45 678

countSpaces会告诉我们我们有3个号码。

然后我们创建一个数组来保存我们的三个数字。我也会切断s部分,这样你就不用再担心了。请注意,您可以使用std::stoi将字符串转换为数字!

现在我们可以在find(' ')不返回-1时循环。

在我们的循环中,我会将子串从0到第一个空格,如下所示:

num = std::stoi( myLine.substr(0, myLine.find(' ') )

然后你可以切断刚才使用的部分:

myLine = myLine.substr( myLine.find(' ') );

这将从字符串的前面抓取一个数字,然后从字符串中删除该数字,并在字符串中仍有空格时重复该过程。

编辑:

如果不保证每个数字之间有一个空格,则可以在执行此方法之前删除多余的空格,或者可以在countSpaces循环期间执行此操作。那时,调用函数countNums等更有意义。

删除空间段并用一个空格替换它们的示例函数:

void removeExtraSpaces(string s) {
    bool inSpaces = (s[0] == ' ');

    for (int i = 1; i < s.size(); i++) {

        if (s[i] == ' ') {

            if(inSpaces) {
                s.erase(i); 
            } else { 
                inSpaces = true;
            }

        } else if(inSpaces) {
            inSpaces = false;
        }

    }
}

答案 3 :(得分:0)

没有载体,你有几种方法。 (1)一次读取整行,标记strtokstrsep,或(2)使用strtol内置的标准功能向下走的字符串将值与指针和结束指针参数分隔给函数。

由于您知道格式,因此您可以轻松使用。 1&amp; 2上面做了同样的事情,你只是使用strtol中的工具将标记化转换一步到一个数字。下面是一个简短的示例,用于处理每行上后跟未知位数的字符串:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>

enum { BASE = 10, MAXC = 512 };

long xstrtol (char *p, char **ep, int base);

int main (void) {

    char buf[MAXC] = "";

    while (fgets (buf, MAXC, stdin)) {   /* for each line of input */
        char *p, *ep;   /* declare pointers */
        p = buf;        /* reset values */
        errno = 0;

        printf ("\n%s\n", p); /* print the original full buffer */

        /* locate 1st digit in string */
        for (; *p && (*p < '0' || '9' < *p); p++) {}
        if (!*p) {  /* validate digit found */
            fprintf (stderr, "warning: no digits in '%s'\n", buf);
            continue;
        }

        /* separate integer values */
        while (errno == 0)
        {   int idx = 0;
            long val;
            /* parse/convert each number in line into long value */
            val = xstrtol (p, &ep, BASE);
            if (val < INT_MIN || INT_MAX < val) {   /* validate int value */
                fprintf (stderr, "warning: value exceeds range of integer.\n");
                continue;
            }
            printf ("  int[%2d]: %d\n", idx++, (int) val);  /* output int */

            /* skip delimiters/move pointer to next digit   */
            while (*ep && *ep != '-' && (*ep < '0' || *ep > '9')) ep++;
            if (*ep)
                p = ep;
            else
                break;
        }
    }

    return 0;
}

/** a simple strtol implementation with error checking.
 *  any failed conversion will cause program exit. Adjust
 *  response to failed conversion as required.
 */
long xstrtol (char *p, char **ep, int base)
{
    errno = 0;

    long val = strtol (p, ep, base);

    /* Check for various possible errors */
    if ((errno == ERANGE && (val == LONG_MIN || val == LONG_MAX)) ||
        (errno != 0 && val == 0)) {
        perror ("strtol");
        exit (EXIT_FAILURE);
    }

    if (*ep == p) {
        fprintf (stderr, "No digits were found\n");
        exit (EXIT_FAILURE);
    }

    return val;
}

xstrtol函数只是将正常的错误检查移动到一个函数来整理代码的主体)

示例输入

$ cat dat/varyint.txt
some string 1, 2, 3
another 4 5
one more string 6 7 8 9
finally 10

示例使用/输出

$ ./bin/strtolex <dat/varyint.txt

some string 1, 2, 3

  int[ 0]: 1
  int[ 1]: 2
  int[ 2]: 3

another 4 5

  int[ 0]: 4
  int[ 1]: 5

one more string 6 7 8 9

  int[ 0]: 6
  int[ 1]: 7
  int[ 2]: 8
  int[ 3]: 9

finally 10

  int[ 0]: 10

您可以提供一些整理,但此方法可用于可靠地解析未知数量的值。仔细看看,如果您有任何问题,请告诉我。