Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android printf、logcat和\n_Android_Ios_C_Printf_Logcat - Fatal编程技术网

Android printf、logcat和\n

Android printf、logcat和\n,android,ios,c,printf,logcat,Android,Ios,C,Printf,Logcat,我有一个C代码,它使用了一些像 printf("hello "); // do something printf(" world!\n"); 哪个输出 你好,世界 我想在Android和iOS中重复使用该代码,但Log.d()和NSLog()实际上在我传递给它们的每个字符串的末尾添加了一个换行符,因此该代码的输出: NSLog(@"hello "); // do something NSLog(@"world!\n"

我有一个C代码,它使用了一些像

printf("hello ");
// do something
printf(" world!\n");
哪个输出

你好,世界

我想在Android和iOS中重复使用该代码,但Log.d()和NSLog()实际上在我传递给它们的每个字符串的末尾添加了一个换行符,因此该代码的输出:

NSLog(@"hello ");
// do something
NSLog(@"world!\n");
结果(或多或少)为:

你好

世界


我愿意用一些宏替换printf,使Log.d和NSLog模拟printf对“\n”的处理;有什么建议吗?

您可以一次只构建一段字符串:

String message = "Hello";
// Do Something
message += " World!";
Log.v("Example", message);

一个可行的解决方案是定义一个全局日志函数,该函数在找到换行符之前不会刷新其缓冲区

以下是一个(非常)简单的android java版本:

import java.lang.StringBuilder;

class CustomLogger {
  private static final StringBuilder buffer = new StringBuilder();

  public static void log(String message) {
    buffer.append(message);

    if(message.indexOf('\n') != -1) {
      Log.d('SomeTag', buffer);
      buffer.setLength(0);
    }
  }
}

...
CustomLogger.log("Hello, ");
// Stuff
CustomLogger.log("world!\n"); // Now the message gets logged
这完全没有经过测试,但你明白了。
此特定脚本存在一些性能问题。例如,最好检查最后一个字符是否是换行符



我刚刚意识到,您希望在C中实现这一点。移植标准库不会有什么坏处(获取字符串缓冲区之类的内容)。

对于后代,我就是这么做的:将记录的字符串存储在缓冲区中,并在缓冲区中有新行时打印新行之前的部分。

是的,NDK logcat对此一无所知。有一些方法可以将stderr/stdout重定向到logcat,但也有一些缺点(要么需要“adb shell setprop”,它只适用于根设备,要么需要类似dup()的技术,但在嵌入式设备上创建一个线程并不是一个好主意,尽管您可以在下面进一步了解这种技术)

为此,我做了自己的函数/宏。下面是一些片段。在debug.c中,执行以下操作:

#include "debug.h"
#include <stdio.h>
#include <stdarg.h>

static const char LOG_TAG[] = "jni";

void android_log(android_LogPriority type, const char *fmt, ...)
{
    static char buf[1024];
    static char *bp = buf;

    va_list vl;
    va_start(vl, fmt);
    int available = sizeof(buf) - (bp - buf);
    int nout = vsnprintf(bp, available, fmt, vl);
    if (nout >= available) {
        __android_log_write(type, LOG_TAG, buf);
        __android_log_write(ANDROID_LOG_WARN, LOG_TAG, "previous log line has been truncated!");
        bp = buf;
    } else {
        char *lastCR = strrchr(bp, '\n');
        bp += nout;
        if (lastCR) {
            *lastCR = '\0';
            __android_log_write(type, LOG_TAG, buf);

            char *rest = lastCR+1;
            int len = bp - rest; // strlen(rest)
            memmove(buf, rest, len+1); // no strcpy (may overlap)
            bp = buf + len;
        }
    }

    va_end(vl);
}
你完成了

优点:

  • C/C++库通常使用stderr作为日志。使用dup是在不修改代码的情况下将其输出保存在logcat中的唯一方法(一些大公司使用数百个直接调用fprintf(stderr,…)

  • stderr是几十年来使用的标准C。与streams相关的所有标准C库函数都可以与它一起使用。同样,对于C++,你甚至可以使用Cyr和<代码> NSlog < /C> >不应该是“代码> Prtff<代码>,<代码> Prtff<代码>打印到<代码> STDUD>代码>,而<代码> NSlog < /Cord>用于记录日志文件等。我的问题是,如何在不破坏功能的情况下将C代码printf重定向到移动日志?我意识到需要一些额外的代码。引用文档:“*请注意,换行符(“\n”)将自动附加到*日志消息中,如果还没有。不可能发送多条*消息并将它们显示在logcat的一行中。”是的,但我希望用C完成此操作。谢谢,实际上我已经在做类似的事情了。我追求的是printf的新行行为。我有遗留的C代码,它利用了printf及其新行特性,我想在iOS和Android中使用。
    #include <android/log.h>
    
    void android_log(android_LogPriority type, const char *fmt, ...);
    #define LOGI(...) android_log(ANDROID_LOG_INFO, __VA_ARGS__)
    #define LOGW(...) android_log(ANDROID_LOG_WARN, __VA_ARGS__)
    ...
    
    #define LOG(...) fprintf(stderr, ...)