在 printf("%.*s") 中使用指针的差异
Using difference of pointers with printf("%.*s")
我面临的问题与 intptr_t
数据类型和 fprintf()
接受 %.*s
格式参数的方式有关。 %.*s
格式期望字段精度具有类型 int
,也许这本身并不是不合理的。
虽然在这种情况下不是:
#include <stdio.h>
#include <stdint.h>
int main() {
char fname[] = "Some_File.txt";
FILE *write = fopen(fname, "w");
if (write != NULL) {
printf("\n\tType below :\n\n");
char in[501] = ""; char *p;
while (1) {
fgets(in, MAX_LN, stdin);
/*** Region with compiler warnings begins ***/
if ((p = strstr(in, "/end/")) != 0) {
intptr_t o = p - in;
fprintf(write, "%.*s", o, in);
/*** Region with compiler warnings ends ***/
fclose(write);
break;
} else {
fputs(in, write);
}
}
}
}
如果我编译它,它不能很好地与 %.*s
一起使用,编译器会指出:
warning: field precision should have type 'int', but argument has type 'intptr_t' (aka 'long') [-Wformat]
如果我做到了 int o;
,它与 %.*s
配合得很好,但当然不是很理想,编译器也这么说:
warning: implicit conversion loses integer precision: 'long' to 'int' [-Wshorten-64-to-32]
现在,这是演示代码,这里 o
可以容纳的最大大小是 500
,但是,在我的实际代码中,它可以是 10,000
甚至 100,000
(仍然非常接近 32 位 int 的大小,不是吗?)
那么,用最少 的改变,什么可以解决这个最好的?
在 Clang 上编译(在 GCC 上可能非常相似)-Wall -Wextra -pedantic
。
指针差异如p-in
的类型是ptrdiff_t
,而不是intptr_t
。无论如何,在这种情况下,一种替代方法是使用 fwrite
:
if ((p = strstr(in, "/end/")) != NULL) {
size_t len = (size_t)(p - in); // p - in is an offset into data with a size
fwrite(in, sizeof(char), len, write);
fclose(write);
break;
} else {
fputs(in, write);
}
然后添加错误检查。
两个指针的区别是类型ptrdiff_t
。 "...是两个指针相减结果的有符号整数类型;"
// intptr_t o = p-in;
ptrdiff_t o = p - in;
鉴于 char in[501]
中的这两个点,差异也符合 int
。
简单地投。 .*
需要匹配 int
,而不是 intptr_t
或 ptrdiff_t
。
// fprintf(write,"%.*s",o,in);
fprintf(write,"%.*s", (int) o, in);
或一次全部:
fprintf(write,"%.*s", (int) (p - in), in);
我面临的问题与 intptr_t
数据类型和 fprintf()
接受 %.*s
格式参数的方式有关。 %.*s
格式期望字段精度具有类型 int
,也许这本身并不是不合理的。
虽然在这种情况下不是:
#include <stdio.h>
#include <stdint.h>
int main() {
char fname[] = "Some_File.txt";
FILE *write = fopen(fname, "w");
if (write != NULL) {
printf("\n\tType below :\n\n");
char in[501] = ""; char *p;
while (1) {
fgets(in, MAX_LN, stdin);
/*** Region with compiler warnings begins ***/
if ((p = strstr(in, "/end/")) != 0) {
intptr_t o = p - in;
fprintf(write, "%.*s", o, in);
/*** Region with compiler warnings ends ***/
fclose(write);
break;
} else {
fputs(in, write);
}
}
}
}
如果我编译它,它不能很好地与
%.*s
一起使用,编译器会指出:warning: field precision should have type 'int', but argument has type 'intptr_t' (aka 'long') [-Wformat]
如果我做到了
int o;
,它与%.*s
配合得很好,但当然不是很理想,编译器也这么说:warning: implicit conversion loses integer precision: 'long' to 'int' [-Wshorten-64-to-32]
现在,这是演示代码,这里 o
可以容纳的最大大小是 500
,但是,在我的实际代码中,它可以是 10,000
甚至 100,000
(仍然非常接近 32 位 int 的大小,不是吗?)
那么,用最少 的改变,什么可以解决这个最好的?
在 Clang 上编译(在 GCC 上可能非常相似)-Wall -Wextra -pedantic
。
指针差异如p-in
的类型是ptrdiff_t
,而不是intptr_t
。无论如何,在这种情况下,一种替代方法是使用 fwrite
:
if ((p = strstr(in, "/end/")) != NULL) {
size_t len = (size_t)(p - in); // p - in is an offset into data with a size
fwrite(in, sizeof(char), len, write);
fclose(write);
break;
} else {
fputs(in, write);
}
然后添加错误检查。
两个指针的区别是类型ptrdiff_t
。 "...是两个指针相减结果的有符号整数类型;"
// intptr_t o = p-in;
ptrdiff_t o = p - in;
鉴于 char in[501]
中的这两个点,差异也符合 int
。
简单地投。 .*
需要匹配 int
,而不是 intptr_t
或 ptrdiff_t
。
// fprintf(write,"%.*s",o,in);
fprintf(write,"%.*s", (int) o, in);
或一次全部:
fprintf(write,"%.*s", (int) (p - in), in);