如何从一个非常长的C ++字符串中生成char * kmers

时间:2012-01-25 22:04:58

标签: c++ string memory char

我有一个非常长的字符串对象,我想在其中引用窗口[0,19],[1,20],.....,[980,1000]作为{{1 }}

让我们调用字符串char x[20]。我试过了

foo

并迭代,但我收到了不兼容的类型错误,因为x = &foo[i] 的类型为&foo[i]

如何使用char *引用字符串foo内存的20-char块?

更哲学地说,char x[20]char *x如果后者不是空终止会有什么区别?

一个目标是不必通过为所有新字符创建全新的内存块来获得2倍的内存要求。

4 个答案:

答案 0 :(得分:1)

看一下llvm的StringRef课程。从本质上讲,它只包含两个指针,即开始和结束。你可以做这样的事情,例如:

std::string source = "... something really long ...";
const char * b = source.c_str();
llvm::StringRef window(b + 100, 20);

window现在是指source的一部分的实体。您可以在其上调用begin()end()来获取迭代器。您可以像普通字符串一样打印它,如下所示:

std::cout << window;

它提供了各种其他常见的字符串操作,您可以在docs中看到。

答案 1 :(得分:1)

char * p是指向应该包含字符的内存的指针。隐含的数据没有结束。 char a[100]是100个字符的内存部分。编译器已知a的结尾访问多维数组和错误检查函数参数。 &amp; a [0]或只是a(元素0的地址)与char *基本相同。

a或p的用户必须以某种方式知道长度:

1)另外提供长度参数。例如:sizeof(a)(以字节为单位)。 我还想使用numof(a),它可以通过添加以下元素而不是字节大小: #define numof(X) (sizeof(X)/sizeof(*X)) 您也可以使用另一个指向结尾的指针来停止。而不是长度。

2)告诉用户p什么时候停止的一些内容或规则。例如:*p == 0(空)

这是C / C ++的强大灵活性来源(如果误用,也会带来危险)。


a)更改数组的用户也有一个长度限制或指向end的停止位置。 如果最后一个块尺寸过小,您可能还需要进行空终止检查。

b)一次只处理一个数据块。然后你只新增了1个额外的20个char数组。 或者,如果您可以确保没有其他线程同时使用该阵列,您可以暂时更改空终止:

// array is assumed to be a multiple of 20 plus 1 more for null
char * ptr = array;
while ( ptr < array + sizeof(array)-1 )
{
  char * end = ptr + 20; // we will stop here
  char save_char = *end; // save the character there
  *end = 0; // put in temporary null
  ProcessBlock( ptr ); // now null terminated !
  *end = save_char; // restore the array
  ptr = end; // end of this block is start of next
}

答案 2 :(得分:0)

只做

int window_size = 20;
for (size_t i = 0; i < foo.size() - window_size; ++i)
{
    const char* x = foo.data() + i;
    // Do something with x[0] to x[window_size - 1]
}

答案 3 :(得分:0)

您收到“不兼容的类型错误”的原因是x&foo[i]属于不同类型。考虑一下:

  • foo属于char[]类型(即char的数组)
  • 因此foo[i]的类型为char
  • 因此&foo[i]属于char*类型(即指向char的指针)

char* xchar x[20]之间的区别在于,在第一种情况下,x是指向char的指针,在第二种情况下,它是char的数组。在第一种情况下,您可以将指针指向进程内存中的任何char。在第二个中,x通常表现得像指针,但它总是指向数组的开头。

假设foo大小是窗口大小的倍数,您可以像这样遍历窗口:

char foo[FOO_SIZE];
for (unsigned i = 0; i < FOO_SIZE; i += WINDOW_SIZE) {
    char first_char = foo[i];
    char last_char = foo[i + WINDOW_SIZE - 1]; // Warning: if foo size is not multiple of window size, this may exceed foo in the last window
}

此外,您自己的代码可能很好,只需从&foo[i]中删除&符号即可。请注意[]已经取消引用指针,因此不需要额外的&