如何从包含字符和整数的行中解析出整数
How to parse out integers from a line with characters and integers
对于C/C++赋值,我需要取一个输入行,从字符"s"开始,后跟最多3个独立的整数。我的问题是,如果没有向量,我不知道如何计算未知数量的整数(1-20)。
例如,测试输入看起来像:
s 1 12 20
有人建议我使用cin.getline,并将整行作为一个字符串,但我怎么知道每个整数在字符数组中的位置,因为可能是单位数或双位数,更不用说所述字符串中的整数数量了?
根据行的内容构造一个std::istringstream
,然后继续将operator>>
使用到int
中,直到fail()
s,将每个整数填充到std::vector
中(在最初使用operator>>
一次以处理前导字符之后)。
您可以使用动态内存分配来模拟向量。最初使用int *a = new int[2];
创建一个大小为2的数组
当此数组填满时,制作一个大小为原来两倍的新数组,将旧数组复制到新数组中,并将a重新分配给新数组。继续这样做,直到达到要求为止。
编辑因此,通过字符串流获取数字,如果数组填满,可以执行以下操作:
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++;
}
}
我跳过了关于第一个角色的部分,但我想你可以应付。
如果没有向量,您有几种方法。(1) 一次读取整行,并用strtok
或strsep
标记该行,或者(2)使用strtol
中内置的标准功能沿字符串向下遍历,该字符串使用指向函数的指针和结束指针参数分隔值。
既然你知道格式,你可以很容易地使用任何一种。两者都是1&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%sn", 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]: %dn", 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 foundn");
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
您可以提供一些整理,但此方法可以用于可靠地解析未知数量的值。仔细看一下,如果你有任何问题,请告诉我。
由于不允许使用向量,因此您需要先找出行中有多少数字,然后才能创建一个数组来容纳它们。
我不会只给你完整的代码,因为这是家庭作业,但我会告诉你我会做什么来解决你的问题。
如果你的台词总是这样:;s数";或";s数";或";s数";,然后你可以通过计算空格很容易地找到行中的数字!
在任何有一个数字的字符串中(在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;
}
}
}
- 有没有办法生成一个包含平方的序列,这些平方加起来就是一个整数平方?
- 如果变量数据包含大于 vector 所有元素的整数,则仅在视觉工作室上接收"矢量下标超出范围"?
- 如何包含整数之间的空格作为输出
- int64_t 不包含 13 位整数
- 我无法显示包含整数最大值的索引. 但我可以显示数组中整数的最高值
- 如何在 c++ 中解析包含整数的字符串并检查是否大于最大值
- 对包含整数的文本文件进行排序时,必须逐行进行排序
- 如何声明包含整数数组的对象
- 我需要声明一个包含整数向量的 4x4 矩阵
- C++ 如何格式化包含可变整数的文本行,使其在给定宽度内右对齐?
- 如何将 32 位无符号整数分配给包含 32 位的位字段
- 给定一个包含 n 个整数和一个整数 x 的未排序数组 A,重新排列 A 中的元素
- 如何在C 中正确定义包含科学符号的整数矢量
- 当我使用我的向量名称后跟包含整数变量的括号时,括号是什么意思
- 当我<int>推送包含整数的字符串时,如何修复被推回向量的垃圾值
- 不能在 c++ 中的字符串中包含整数
- 如何在 C++ 中包含整数输入的前面的 0
- 使用包含每个重复数量的列表生成重复,上升整数的顺序,并用推力
- 我正在尝试读取一个包含字符串和整数的二进制文件..并打印出与字符串对应的整数
- 如何打印包含整数和整数集的std::映射