为什么我的for循环中的strncpy无效?

时间:2015-01-16 15:24:45

标签: c loops strncpy

我试图将一个字符串拆分成多个小字符串(nb大小)。 但它并不像我想的那样工作:

 #include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
int main(int argc, char *argv[]) {
  char *source = argv[1];
  int taille=0;
  int i=0;
  int k;
  int nb = 5;
  char dest[strlen(source)/nb][nb];
  while(i<strlen(source))
  {
    char *src = &source[i];
    strncpy(dest[taille],src,nb);
    i=i+nb;
    taille++;
  }

    for(k = 0 ; k <8;k++)
  {
    printf("\t%s\n",dest[k]);
  }
}

这是跟踪:

jerome@debian:~/codeFTP/code/serveur$ ./a.out " bonjour cocoman, tu me donne20 balles?"
     bonjour cocoman, tu me donne20 balles?
    our cocoman, tu me donne20 balles?
    ocoman, tu me donne20 balles?
    n, tu me donne20 balles?
     me donne20 balles?
    onne20 balles?
    0 balles?
    les?

但最奇怪的是,如果我拿出一段时间(或者,我已经尝试过两者),它可以工作(通过起飞而我的意思是用适当的值而不是使用循环来写8次strncpy) 。 谢谢你的兴趣。

2 个答案:

答案 0 :(得分:3)

strncpy不会终止字符串。你自己需要这样做。当你打印第一个时,printf永远不会找到null并开始打印内存中跟随它的任何内容。因为它们在一个数组中,所以它看到的下一个字节是下一个字符串的第一个字节。这将继续,直到它到达最后一个字符串,该字符串为空,因为strncpy实际上看到了源字符串的结尾。

您需要更改声明,以便为空字符每个字符串再保留一个字节:

char dest[strlen(source)/nb][nb + 1];

然后在复制后手动空终止每个子字符串:

dest[taile][nb] = 0;

我不确定为什么展开循环工作 - 当你重写它时,你的其他逻辑可能会略有改变。

编辑补充说:另外,正如Gopi在答案中所说,你找到字符串数量的数学结果会减少。如果字符串长度不是nb的完美倍数,那么你的数组太小而且你正在调用未定义的行为。最简单的解决方案是在该维度上添加一个。你的循环是安全的,因为它基于strlen,而不是你计算的子串的数量。

char dest[strlen(source)/nb + 1][nb + 1];

答案 1 :(得分:1)

存在潜在问题

strlen(source)/nb作为索引,与strlen(source)相比,这将包含最少的行,而您正在执行以下操作

  while(i<strlen(source))
  {
    char *src = &source[i];
    strncpy(dest[taille],src,nb);
    i=i+nb;
    taille++;
  }

现在dest[taille]必然是数组越界访问,并确保

strncpy()没有\0终止字符串。

基本情况:传递一些长度小于5的字符串,你有UB。您的代码中存在多个此类潜在错误。