【问题标题】:format ’%s’ expects argument of type ’char *’格式“%s”需要“char *”类型的参数
【发布时间】:2013-12-05 05:17:50
【问题描述】:

为了锻炼我的 C 编程技能,我正在尝试自己编写 strncpy 函数。这样做我不断遇到错误,最终解决了大部分错误,我没有进一步的灵感继续前进。

我收到的错误是:

ex2-1.c:29:3: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
   printf("The copied string is: %s.\n", stringb);

问题是这是一个非常常见的错误,并且它也已经在 SO 上进行了描述,只是我似乎无法应用其他人已经指出的提示。我知道我在打印变量时使用了错误的类型,当我使用 %d 格式时,它会返回一个整数,这可能是第一个字符的 ASCII 值,因为它在增加最大数时不会改变要复制的字节数。

使用 GDB,我发现当完成 while 循环的迭代时 b 变量包含正确的字符串,但我似乎仍然无法打印它。

我可能缺乏关于 C 语言的基本知识,对于提出这个新手问题(再次),我深表歉意。如果您能提供反馈或指出我的代码中的其他缺陷,我将不胜感激。

#include <stdlib.h>
#include <stdio.h>

void strmycpy(char **a, char *b, int maxbytes) {
  int i = 0;
  char x = 0;

  while(i!=maxbytes) {
  x = a[0][i];
  b[i] = x;
  i++;
  }

  b[i] = 0;

}


int main (int argc, char **argv) {
  int maxbytes = atoi(argv[2]);
  //char stringa;
  char stringb;
  if (argc!=3 || maxbytes<1) {
        printf("Usage: strmycpy <input string> <numberofbytes>. Maxbytes has to be more than or equal to 1 and keep in mind for the NULL byte (/0).\n");
        exit(0);
     } else {

  strmycpy(&argv[1], &stringb, maxbytes);
  printf("The copied string is: %s.\n", stringb);

  }

  return 0;
}

【问题讨论】:

  • stringbchar,而不是 char*
  • stringb 是一个 char(当传递给 printf() 时会提升为一个 int)。您需要将其声明为适当大小的数组。确实,“再一次”。
  • %s 需要以 nul-char 结尾的字符序列的地址。您传递的是一个字符,而不是字符序列的地址,当然也不是以 nul-char 结尾的字符。

标签: c string printf strcpy strncpy


【解决方案1】:

charchar* 之间存在细微差别。第一个是单个字符,而后者是指向char 的指针(它可以指向可变数量的char 对象)。

%s 格式说明符确实需要一个 C 风格的字符串,它不仅应该是 char* 类型,而且还应该是空终止的(参见 C string handling)。如果要打印单个字符,请改用%c

至于程序,假设我认为你想要的就是你想要的,试试这样:

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

static void strmycpy(char *dest, const char *src, size_t n) {
    char c;
    while (n-- > 0) {
        c = *src++;
        *dest++ = c;
        if (c == '\0') {
            while (n-- > 0)
                *dest++ = '\0';
            break;
        }
    }
}

int main(int argc, char *argv[]) {
    size_t maxbytes;
    char *stringb;

    if (argc != 3 || !(maxbytes = atoll(argv[2]))) {
        fprintf(
            stderr,
            "Usage: strmycpy <input string> <numberofbytes>.\n"
            "Maxbytes has to be more than or equal to 1 and keep "
            "in mind for the null byte (\\0).\n"
        );
        return EXIT_FAILURE;
    }

    assert(maxbytes > 0);
    if (!(stringb = malloc(maxbytes))) {
        fprintf(stderr, "Sorry, out of memory\n");
        return EXIT_FAILURE;
    }

    strmycpy(stringb, argv[1], maxbytes);
    printf("The copied string is: %.*s\n", (int)maxbytes, stringb);
    free(stringb);

    return EXIT_SUCCESS;
}

但坦率地说,这是非常基础的,以至于解释可能只会导致写一本关于 C 的书。所以如果你只是读一本已经写好的书,你会好很多。有关优秀 C 书籍和资源的列表,请参阅 The Definitive C Book Guide and List

希望对您有所帮助。祝你好运!

【讨论】:

  • 轻微?对不起。这让我发笑。
  • @WhozCraig:是的,区别只在于星号,能有多大是对的:)
  • 差异可以忽略不计。 :P
  • 对于 OP 的参考,花一些时间在documentation for printf() 中使用格式说明符。值得花时间学习它们。
  • 您当然是指指向char 的指针。指向数组的指针是另一种野兽。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-10
  • 2018-11-03
  • 1970-01-01
  • 1970-01-01
  • 2016-09-14
  • 1970-01-01
相关资源
最近更新 更多