【问题标题】:How to use strncpy with a for-loop in C?如何在 C 中将 strncpy 与 for 循环一起使用?
【发布时间】:2013-11-22 18:09:36
【问题描述】:

我正在编写一个程序,它将获取文件中的每 3 个数字并将它们转换为它们的 ASCII 符号。所以我想我可以将这些数字读入一个字符数组,然后将每 3 个元素设为第二个数组中的 1 个元素,将它们转换为 int,然后将它们打印为 char。

但是,我坚持采用每 3 个元素。这是我这部分的代码 sn-p:

char arry[] = "073102109109112"; <--example string read from a file
char arryNew[16] = {0};

for(int i = 0; i <= sizeof(arryNew); i++){
strncpy(arryNew, arry, 3);
arryNew[i+3]='\0';
puts(arryNew);
}

这段代码给我的是前 3 个数字,十五次。我尝试将 i 增加 3,这给了我前 3 个数字 5 次。如何使用 strncpy 编写一个 for 循环,以便在复制 n 个字符后移动到下一个 n 个字符?

【问题讨论】:

  • strncpy(arryNew, arry+i*3, 3); ?并删除arryNew[i+3]='\0';
  • 这行得通!几乎!它在正确的073,102,109等之后打印出一些随机字符。为什么?
  • @supersaidso 你能包含输出吗?
  • 073 102 109 109 112(奇怪的箭头东西不能复制)@
  • 嗯,在我设置 arryNew[5] 而不是 arryNew[16] 之后,那些随机字符消失了。想知道为什么!

标签: c for-loop strncpy


【解决方案1】:

你总是将指针传递给数组的开头,所以你总是会得到相同的结果。您必须包含循环计数器才能进入下一个块:

strncpy(arryNew, &arry[i*3], 3);

这里有问题:

 arryNew[i+3]='\0';

首先,你不需要每次都设置空字节,因为这无论如何都不会改变。此外,您会损坏内存,因为您使用i+3 作为索引,因此当您达到 14 和 15 时,它将超出数组边界。

您的arrayNew 必须更长,因为您的原始数组是 16 个字符,而您的目标数组也是。如果您打算在其中有几个 3char 字符串,那么您的目标必须有 5*4 个字符,因为每个字符串也有 0 字节。

当然,您还必须在此处使用索引。现在的写法,当i达到14和15时,会越过数组边界写。

所以你似乎想要做的(从你的描述中不确定)是:

char arry[] = "073102109109112"; <--example string read from a file
char arryNew[20] = {0};

for(int i = 0; i <= sizeof(arry); i++)
{
  strncpy(&arryNew[i*4], &arry[i*3], 3);
  puts(&arryNew[i*4]);
}

或者,如果您只想打印单个字符串,那么您可以这样做:

char arry[] = "073102109109112"; <--example string read from a file
char arryNew[4] = {0};

for(int i = 0; i <= sizeof(arry); i++)
{
  strncpy(arryNew, &arry[i*3], 3);
  puts(arryNew);
}

【讨论】:

  • sizeof(arry)strlen("073102109109112") + 1 或 16。arry[i*3] 可以变成 arry[16*3]。这是你的意图吗?
  • 原字符串有5+3个字符。如果 OP 打算将其复制到每个 3 个字符的单独字符串中,则新数组的大小必须为 5*4,因为每个新字符串都有 0 字节。不过,我不清楚,如果 OP 只是想打印出每个 3char 包或想要将所有包作为单独的字符串,因为 OP 写 make every 3 elements 1 element in a second array
【解决方案2】:

让事情变得更简单:你的目标字符串不会改变。

char arry[] = "073102109109112"; <--example string read from a file
char target[4] = {0};

for(int i = 0; i < strlen(arry) - 3; i+=3)
{
  strncpy(target, arry + i, 3);
  puts(target);
}

解码:

start at the beginning of arry
copy 3 characters to target
(note the fourth element of target is \0)
print out the contents of target
increment i by 3
repeat until you fall off the end of the string.

【讨论】:

    【解决方案3】:

    一些问题。

    // Need to change a 3 chars, as text, into an integer.
    arryNew[i] = (char) strtol(buf, &endptr, 10);
    
    // char arryNew[16] = {0};
    // Overly large.
    arryNew[6] 
    
    // for(int i = 0; i <= sizeof(arryNew); i++){
    // Indexing too far.  Should be `i <= (sizeof(arryNew) - 2)` or ...
    for (i=0; i<arryNewLen; i++) {
    
    // strncpy(arryNew, arry, 3);
    // strncpy() can be used, but we know the length of source and destination, 
    //   simpler to use memcpy()
    // strncpy(buf, a, sizeof buf - 1);
    memcpy(buf, arry, N);
    
    // arryNew[i+3]='\0';
    // Toward the loop's end, code is writing outside arryNew.
    // Lets append the `\0` after the for() loop.
    
    // int i
    size_t i;  // Better to use size_t (or ssize_t) for array index.
    

    建议:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int main() {
      char Source[] = "073102109109112"; // example string read from a file
    
      const int TIW = 3; // textual integer width
      // Avoid sprinkling bare constants about code.  Define in 1 place instead.
    
      const char *arry = Source;
      size_t arryLen = strlen(arry);
      if (arryLen%TIW != 0) return -1;  // is it a strange sized arry?
      size_t arryNewLen = arryLen/TIW;
      char arryNew[arryNewLen + 1];
      size_t i;
    
      for (i=0; i<arryNewLen; i++) {
        char buf[TIW + 1];
        // strncpy(buf, a, sizeof buf - 1);
        memcpy(buf, arry, TIW);
        buf[TIW] = '\0';
        char *endptr; // Useful should OP want to do error checking
        // TBD: test if result is 0 to 255
        arryNew[i] = (char) strtol(buf, &endptr, 10);
        arry += TIW;
      }
    
      arryNew[i] = '\0';
      puts(arryNew);  // prints Ifmmp
      return 0;
    }
    

    【讨论】:

      【解决方案4】:

      您可以使用此代码来完成您的任务,即将给定的 char 数组转换为 ascii 值的形式。

      char arry[] = "073102109109112";
      char arryNew[16] = {0};
      int i,j=0;
      for(i = 0; i <= sizeof(arryNew)-2; i+=3)
      {
      arryNew[j]=arry[i]*100+arry[i+1]*10+arry[i+2]*1;
      j++;
      arryNew[j+1]='\0';
      puts(arryNew);
      }
      

      【讨论】:

        猜你喜欢
        • 2023-03-27
        • 1970-01-01
        • 2012-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-24
        • 1970-01-01
        相关资源
        最近更新 更多