【问题标题】:Print only x coordinate out of x y z from given database file using C使用 C 从给定数据库文件中仅打印 x y z 中的 x 坐标
【发布时间】:2014-08-12 00:50:40
【问题描述】:

我想打印我的输出,其中只打印出 x 坐标。

      1.  printf("sphere{\n");
      2.  printf("\t<%g %g %g>,\n", V3ARGS(ell->v));
      3.  printf("//<\n %g \n// %g %g>\n }", V3ARGS(ell->a));

在第三行代码中,在第一个变量之后我放了“//”,因为它是 cmets 的标志,即我在输出文件中打印第二个和第三个变量作为注释。 有什么方法可以只打印出'x'值,即第一个变量?

【问题讨论】:

  • 欢迎来到 Stack Overflow。请尽快阅读About 页面。因为您没有告诉我们任何关于 V3ARGS 是什么的信息(它可能是一个宏,并且可以扩展为多个逗号分隔值),也没有告诉我们任何关于指针变量 ell 的结构类型的信息(除此之外还有元素va,但我们不知道那是什么类型),这是无法解决的。你甚至没有提到你正在使用哪个软件包。如果没有这些辅助信息,您的问题将无法回答。
  • 请注意,// 仅标记 C 源代码中注释的开始,并且仅当它出现在字符串(或字符)文字之外时。

标签: c


【解决方案1】:

这里有一些可以代表您正在使用的代码,以及一次提取一个参数的宏:

#include <stdio.h>

#define V3ARGS(v)   (v).x, (v).y, (v).z
#define ARG_1(x, y, z)   (x)
#define ARG_2(x, y, z)   (y)
#define ARG_3(x, y, z)   (z)
#define ARG1(v)   ARG_1(v)
#define ARG2(v)   ARG_2(v)
#define ARG3(v)   ARG_3(v)


typedef struct Point_3D
{
    double x;
    double y;
    double z;
} Point_3D;;

typedef struct DoublePoint
{
    Point_3D    a;
    Point_3D    v;
} DoublePoint;

int main(void)
{
    DoublePoint d = { { 1.1, 2.2, 3.3 }, { 4.4, 5.5, 6.6 } };
    DoublePoint *ell = &d;
    printf("sphere{\n");
    printf("\t<%g %g %g>,\n", V3ARGS(ell->v));
    printf("//<\n %g \n// %g %g>\n }\n", V3ARGS(ell->a));
    printf("a.x = %g\n", ARG1(V3ARGS(ell->a)));
    printf("a.y = %g\n", ARG2(V3ARGS(ell->a)));
    printf("a.z = %g\n", ARG3(V3ARGS(ell->a)));
    printf("v.x = %g\n", ARG1(V3ARGS(ell->v)));
    printf("v.y = %g\n", ARG2(V3ARGS(ell->v)));
    printf("v.z = %g\n", ARG3(V3ARGS(ell->v)));
    return 0;
}

这里的技巧是两个级别的宏,ARG1ARG_1。请注意,ARG1() 采用单个参数,预计是对 V3ARGS 的调用,然后调用 ARG_1()。这个技巧将宏参数扩展为 ARG_1() 期望的三个逗号分隔的参数,然后它只“返回”这些参数中的第一个。

显示代码的输出(第一个输出是您在问题中显示的代码,输出末尾带有换行符):

sphere{
    <4.4 5.5 6.6>,
//<
 1.1 
// 2.2 3.3>
 }
a.x = 1.1
a.y = 2.2
a.z = 3.3
v.x = 4.4
v.y = 5.5
v.z = 6.6

【讨论】:

    【解决方案2】:

    正如@JonathanLeffler 指出的那样,无论您的V3ARGS(...) 是什么,它都可能是一个#define 宏,可以解析为x, y, z 之类的逗号列表。这意味着您实质上是在询问哪种格式字符串仅打印 x 如果您说:

    printf("some format string here", x, y, z);
    

    你很幸运,因为传递的格式说明符比你传递的参数少是合法的:

    Passing too many arguments to printf

    所以如果你只想要第一个参数,那么只使用一个说明符:

    printf("%g", x, y, z);
    

    如果您只想要第二个或第三个,这会变得更加棘手。因为没有通用的方法来跳过值;格式说明符按顺序使用(尽管有一个 POSIX 扩展可以按数字访问):

    Is there a "null" printf code that doesn't print anything, used to skip a parameter?

    因此,如果您遇到这样的情况,只想打印 z,而无法修改宏,则should work in ANSI C99

    typedef struct {
       double x,
       double y,
       double z
    } Coordinate;
    
    Coordinate temp;
    temp = (Coordinate){ V3ARGS(ell->a) };
    
    printf("%g", temp.z);
    

    这利用了结构字段可以由逗号分隔的列表在该赋值样式中初始化的事实。

    但是查看 V3ARGS 的定义可能会更好。因为它可能正在做类似的事情:

    #define V3ARGS(foo) (foo).x, (foo).y, (foo).z
    

    在这种情况下,您可以这样说:

    printf("%g", ell->a.z);
    

    【讨论】:

    • 宏定义为#define V3ARGS(a) (a)[X], (a)[Y], (a)[Z] #define VPRINT(a, b) \ fprintf(stderr , "%s (%g, %g, %g)\n", a, V3ARGS(b));所以我将我的文件编辑为 printf("sphere{\n"); printf("\t,\n", V3ARGS(ell->v)); printf("//(\n %g \n//)\n }", V3ARGS(a)[X]);但它在函数'primitive_func'中给出错误:/home/gurwinder/brlcad/src/conv/g-xxx.c:283:36: error: 'a' undeclared (first use in this function) /home/g- xxx.c:283:36: 注意:每个未声明的标识符对于它出现的每个函数只报告一次
    • 您应该将宏粘贴到实际问题中并适当格式化。
    • @user3717474:您确实应该将代码作为代码粘贴到问题中,最好是 MCVE (How to create a Minimal, Complete, and Verifiable Example?) 或 SSCCE (Short, Self-Contained, Correct Example) — 相同基本的两个名称(和链接)主意。请注意,我的答案还包含一个 MCVE(或 SSCCE)。
    • 请注意,如果您将编译器设置为 fussy(它是 GCC),那么它会警告您有关传递给 printf() 等的未使用参数。我的答案中的代码具有在严格的警告选项下编译的优点(在 Mac OS X 10.9.4 上使用 GCC 4.9.1):gcc -O3 -g -std=c11 -Wall -Wextra -Werror x3.c -o x3
    猜你喜欢
    • 1970-01-01
    • 2016-09-07
    • 2016-09-04
    • 2020-01-20
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多