【问题标题】:How to print a string multiple times referencing it only once?如何多次打印一个字符串,只引用一次?
【发布时间】:2015-04-30 21:51:40
【问题描述】:

这段代码:

#include <stdio.h>

void main()
{
    char *csv_delimiter = ",";
    printf("col1%scol2%scol3%scol4\n", csv_delimiter, csv_delimiter, csv_delimiter);
}

有这个输出:

col1,col2,col3,col4

这正是我所需要的。但我必须多次引用指针csv_delimiter。如果我有一千列怎么办?有没有办法只引用一次csv_delimiter 并多次打印以分隔尽可能多的列?我正在寻找这样的代码:

#include <stdio.h>

void main()
{
    char *csv_delimiter = ",";
    printf("col1[REF1]col2[REF1]col3[REF1]col4\n", csv_delimiter);
}

从这个例子可以看出,我不是在寻找循环(由于与实现相关的原因,我无法在原始代码中循环)。我需要一些方法将大量%s 放在一行中,并将它们全部引用到同一个指针,在本例中为csv_delimiter。我确信这是可能的。我记得在 Deitel 读过类似的东西,但我找不到他解释如何做到这一点的地方。

【问题讨论】:

  • 循环是标准 ANSI-C 中的唯一选择。另外为什么你不能只使用循环?无论如何,我想在 Windows 上应该可以:msdn.microsoft.com/en-us/library/bt7tawza.aspx
  • 回复。不得不描述整个实现,你能不能试着给出一个简化的例子来说明为什么你不能循环呢?
  • @pfannkuchen_gesicht 它与 FANN 结构输出格式、我从中读取输入的文件以及我需要如何一起处理这些信息以输出供另一个函数使用的 CSV 文件有关.
  • 称我为天真,但我想不出任何可以想象的原因为什么循环不可能。我认为您真正的问题可能不在您向我们展示的内容。

标签: c string printf


【解决方案1】:

在 Windows 上有一个 _printf_p() 函数,它实现了位置参数。 所以改为

printf("col1%1$scol2%1$scol3%1$scol4\n", csv_delimiter);

你应该可以使用

_printf_p("col1%1$scol2%1$scol3%1$scol4\n", csv_delimiter);

请参阅https://msdn.microsoft.com/en-us/library/bt7tawza.aspx 了解更多信息。

编辑:

对于 Linux/Windows 交叉编译,请使用如下代码:

#if defined (__WIN32__)
  _printf_p(...);
#elif defined (__linux__)
  printf(...);
#endif

【讨论】:

  • 这非常接近我的需要。我测试过,但找不到“_printf_p”。你知道这个功能是否只能在 Visual Studio 中使用吗?我更喜欢使用 MinGW。
  • 不适用于 linux,但是,您应该能够使用它创建一个宏,或者至少您可以使用预编译器指令在两者之间切换,具体取决于您编译的平台。
  • 你是否包含了conio.h头文件?
  • 这个答案没有解决问题,但对我帮助最大,所以我选择它来结束这个话题。
【解决方案2】:

您可以使用格式说明符位置修饰符:

void main()
{
    char *csv_delimiter = ",";
    printf("col1%1$scol2%1$scol3%1$scol4\n", csv_delimiter);
}

这里的 %1$s 是格式后第一个参数的格式说明符。

【讨论】:

  • 你应该指出这(和void main(),就此而言)是非标准的。
  • 是的,我正在寻找“位置修饰符”。我会测试你的答案。如果有效,我会将其标记为正确。
  • 它没有用。 printf("col1%1$scol2%1$scol3%1$scol4\n", csv_delimiter); 行具有以下输出:col1$scol2$scol3$scol4。无论如何我都赞成你的回答,因为这正是我想要的。
  • @PaulGriffiths...我不知道它是非标准的...它在这个标准中列出:pubs.opengroup.org/onlinepubs/009695399/functions/printf.html...
  • @GradyPlayer:这是 a 标准,但不是 C 标准。
【解决方案3】:

OP 断言“由于与实现相关的原因,我无法在原始代码中循环)”。

假设此限制不涉及所有代码,而仅涉及打印命令本身,请调用辅助函数而不是 printf()。由于 OP 想要“......以某种方式将大量 %s 放在一行中并将它们全部引用到同一个指针”,因此处理该单行很容易。

#include <stdio.h>

void printf_renatov(const char *format, const char *csv_delimiter) {
  while (*format) {
    if (format[0] == '%' && format[1] == 's') {
      fputs(csv_delimiter, stdout);
      format += 2;
    } else {
      fputc(*format, stdout);
      format++;
    }
  }
}

int main(void) {
  char *csv_delimiter = ",";
  printf_renatov("col1%scol2%scol3%scol4\n", csv_delimiter);
}

col1,col2,col3,col4

【讨论】:

    【解决方案4】:

    为什么不能使用循环?

    int i, max;
    for(i=0; i<max-1; i++){
        printf("col%d%s ", i, csv_delimiter);
    }
    printf("col%d%\n", max);
    

    其中 max 是您希望打印的最大值。

    【讨论】:

    • 由于与实现的特殊性相关的原因,我不能在原始代码中使用循环。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多