你能改变指针指向的大小吗?

时间:2012-04-16 19:31:52

标签: c++ pointers strncpy

例如,如果指针指向一个字符数组,其中显示“你好,你好吗?”而且你只希望指针指向Hello。我传入一个char指针,当我cout它,它读取整个数组。我尝试使用for循环来减小大小,当它达到''时会中断。但我没有运气搞清楚。有任何想法吗?

const char *infile(char * file )
{
    cout<<file<<endl;  //this prints out the entire array
    int j;
    for(j=0;j<500; j++)
    {
        if(file[j]==' ')
           break;
    }
    strncpy(file, file,  j);
    cout<<file<<endl;  //how to get this to print out only the first word
}

11 个答案:

答案 0 :(得分:2)

如果源字符串的第一个strncpy()字节中没有一个,则

j不会附加空终止符。而你的情况则没有。

我认为您要做的是手动将第一个空格更改为\0

for (j = 0; j < 500; j++) {
  if (file[j] == ' ') {
    file[j] = '\0';
    break;
  }
}

答案 1 :(得分:2)

首先,避免 strtok(就像它主要是瘟疫一样)。这有点令人不愉快,但有时在C中是合理的。我还没有看到我称之为在C ++中使用它的理由。

其次,处理这个问题最简单的方法(假设您使用的是C ++)就是使用字符串流:

void infile(char const *file) 
{
    std::strinstream buffer(file);
    std::string word;
    buffer >> word;
    std::cout << word;
}

另一种可能性是使用std :: string中内置的一些函数:

void infile(char const *file) {
    std::string f(file);
    std::cout << std::string(f, 0, f.find(" "));
}

...现在我想起来,可能比stringstream版本的东西简单一些。

答案 2 :(得分:1)

char*指针实际上只指向一个char对象。如果该对象碰巧是字符串的第一个(或任何)元素,则可以使用指针算法来访问该字符串的其他元素 - 这就是字符串(C样式字符串,而不是C ++ - 样式{{1}通常访问对象。

(C风格)字符串只是一个由空字符终止的字符序列(&#39; std::string&#39;)。 (\0终结符之后的任何内容都不是字符串的一部分。)所以字符串'\0'由这个字符序列组成:

"foo bar"

如果要将字符串从{ 'f', 'o', 'o', ' ', 'b', 'a', 'r', '\0' } 更改为仅"foo bar",一种方法是将空格字符替换为空字符:

"foo"

{ 'f', 'o', 'o', '\0', ... } 不是语法的一部分;它代表仍然存在的字符(...'b''a''r'),但不再是字符串的一部分。

由于您使用的是C ++,因此使用'\0'可能会好得多;它更强大,更灵活,让您不必担心终结器,内存分配和其他细节。 (当然,除非本练习的目的是学习C风格的字符串是如何工作的。)

请注意,此会修改 std::string指向的字符串,并且调用者可以看到该更改。你可以通过制作字符串的本地副本(这需要为它分配空间,然后释放该空间)来避免这种情况。同样,file使这种事情更容易

最后,这个:

std::string

在几个级别上都很糟糕。使用重叠的源和目标调用strncpy(file, file, j); 具有未定义的行为;几乎任何事情都可能发生。 strncpy()并不一定在目的地提供适当的NUL终结符。从某种意义上说,strncpy()并不是一个字符串函数。你可能最好不要假装它不存在。

See my rant on the topic

答案 3 :(得分:0)

这与指针的大小无关。 指针的大小始终与特定类型相同。

Strtok可能是最好的解决方案(使用strtok的代码会在每次遇到空格,“,”,点或“ - ”时将字符串分解为子字符串。

char str[] ="- This, a sample string.";
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str," ,.-");
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (NULL, " ,.-");
  }

来源:CPP STRTOK

答案 4 :(得分:0)

这样做会容易得多

 if(file[j]==' ') {
   file[j] = 0;
   break;
   ..

  // strncpy(file, file,  j);

答案 5 :(得分:0)

使用strtok可能会让您的生活更轻松 用''作为分隔符拆分字符串,然后打印从strtok获得的第一个元素。

答案 6 :(得分:0)

答案 7 :(得分:0)

如果您要问的是“我可以动态调整此指针指向的内存块”,那么......不是真的,不是。 (您必须创建所需大小的新块,然后复制字节,删除第一个块等)。

如果您只是想“打印第一个单词”,那么将空格位置的字符设置为0.然后,当您输出文件*指针时,您将获得第一个单词(一切都是\ 0。)(阅读null terminated strings以获取有关为什么以这种方式工作的更多信息。)

但这一切都取决于你所做的事情有多少是一个例子来证明你想要解决的问题。如果你真的“分裂字符串”,那么你至少要查看来使用strtok

答案 8 :(得分:0)

为什么不一次输出每个角色,然后在击中空格后中断。

const char *infile(char * file )
{
  cout<<file<<endl;  //this prints out the entire array
  int j;

  for(j=0;j<500; j++)
  {
    if(file[j]==' ')
       break;
    cout<<file[j];
  }

  cout<<endl;
}

答案 9 :(得分:0)

如果您使用malloc分配了char *指向的空间,则可以使用realloc更改大小。

char * pzFile = malloc(sizeof("Hello how are you?" + 1));
strcpy(pzFile, "Hello how are you?");
realloc(pzFile, 6);
pzFile[6] = '\0';

请注意,如果未设置空指针,则使用该字符串可能会导致问题。

如果您只是想缩短字符串,那么您所要做的就是将空终止符设置为位置6.分配的空间大于所需的空间,但只要它不短,就可以了。

我强烈建议大多数你想做的是将字符串复制到空格。

char * pzInput = malloc(sizeof("Hello how are you?" + 1));
strcpy(pzInput, "Hello how are you?");
char * pzBuffer = malloc(BUFFER_SIZE);

char * pzSrc = pzInput;
char * pzDst = pzBuffer;
while (*pzSrc && ' ' != *pzSrc)
  *(pzDst++) = *(pzSrc++);
*pzDst = '\0';

这也最终导致pzSrc指向字符串的其余部分供以后使用!

答案 10 :(得分:0)

std::copy(file, std::find(file, file+500, ' '),
          std::ostream_iterator<char>(std::cout, ""));