2016-04-22 21 views
-1

我正在使用一個C應用程序,該應用程序由Java應用程序測試,在Eclipse中運行。 Java應用程序運行C應用程序,使用的標準方式:如何避免由Eclipse運行的C應用程序中的不可複製字符

Runtime.getRuntime().exec(cmdline) 

(該cmdline含C應用程序的可執行文件)

C應用程序最有可能使用Visual Studio的vsprintf()函數寫的東西,但在某些情況下,不可複製的字符似乎是打印的,因爲你可以看到:

put_log(LOG_INFO, "Waiting for writing thread\n"); 

put_log()是最有可能基於所提到的vsprintf()
PS -ef 這被在Eclipse中顯示爲:

INFO : aiting for writing thread 

正如你看到的,「W」已經消失,而在最重要的是,當我嘗試複製提到的線,我只看到:

INFO : 

我有信W已取代一個字符,這是不可拷貝到Windows剪貼板的印象。因爲這發生在相當大的輸出中,所以這非常煩人。

有人明白髮生了什麼事情,我該如何解決這個問題?

作爲問由Fluter,特此put_log()功能的摘錄:

void put_log(const char *fmt, ...) 
{ 
    static char str[16384]; 
    char* args; 
    char* p = str; 

    strcpy(str, "INFO: "); 

    p = str + strlen(str); 

    _crt_va_start(args, fmt); 
    vsprintf(p, fmt, args); 
    _crt_va_end(args); 
    ... 
} 

(第一個參數(LOG_INFO)從該摘錄移除和更換由"INFO: "硬編碼串爲了簡化的目的)

爲了您的信息,特此位置的低級功能:

  • _crt_va_start():c:\ P rogram文件(x86)\微軟的Visual Studio 12.0 \ VC \包括\ STDARG.H
  • _crt_va_end():C:\ Program Files文件(x86)的\微軟的Visual Studio 12.0 \ VC \包括\ STDARG.H
  • vsprintf中():C:\ Program Files文件(x86)的\微軟的Visual Studio 12.0 \ VC \ CRT \ SRC \ vsprintf.c

感謝

+2

請發佈put_log的C程序 – fluter

+1

爲什麼你的例子說'INFO:'但代碼說'INFO:'。這是錯誤還是錯誤的一部分? – Lundin

+0

你好@Lundin,確實是一個錯字。 – Dominique

回答

0

你沒有張貼如何將日誌真正得到印在控制檯上,請確保您直接功能打印,例如fprintf(stderr, str);

二,你在這裏使用了一個靜態緩衝區,當這個函數被併發地調用時,它可能受到數據競爭的影響,可能是由多個線程調用的。很顯然,每個日誌都會覆蓋緩衝區,因此在這裏使用靜態是沒有意義的,但會帶來數據損壞的問題。

void put_log(const char *fmt, ...) 
{ 
    char str[16384]; 
    char* args; 
    char* p = str; 
    va_list list; 

    strcpy(str, "INFO: "); 

    p = str + strlen(str); 

    va_start(list, fmt); 
    vsprintf(p, fmt, list); 
    va_end(list); 

    fprintf(stderr, str); 
} 
+0

正如我所提到的,函數'vsprintf(p,fmt,va);'被使用,它似乎是一個Visual Studio print()函數。 – Dominique

+0

@Dominique不,'vsprintf'將格式化的字符串打印到指向p的緩衝區中,它不會將緩衝區打印到文件中。這就是我爲什麼要調用'fprintf'的原因。 – fluter

+0

確實。我在末尾添加了'fprintf'(如源代碼) – Dominique

0

假設_crt_va_start行爲就像標準C va_start,那麼你需要聲明某個地方使用va_list,而不是使用某些未初始化的字符指針。它似乎工作的原因可能是因爲VA列表不具備類型安全性(因此使用它們開始是不好的做法)。

做這樣的事情,而不是:

#include <stdarg.h> 

void put_log(const char *fmt, ...) 
{ 
    static char str[16384]; 
    va_list va; 
    char* p = str; 

    strcpy(str, "INFO: "); 
    p = str + strlen(str); 

    va_start(va, fmt); 
    vsprintf(p, fmt, va); 
    va_end(va); 
} 
+0

對不起,Lundin,爲了有一個簡短的源代碼摘錄,我丟掉了太多的行:'va_list'是在函數的開始處聲明的,所以實際上,我的源代碼看起來和你提出的完全一致,同時我看到消息的第一個字母被ASCII代碼爲0的字符替換(零) – Dominique

+0

@Dominique因此,不要浪費每個人的時間,而是爲了不發佈複製/粘貼的確切代碼? – Lundin

+0

我明白你的問題,Lundin,但我的公司對此事非常嚴格。 – Dominique

相關問題