2016-12-28 64 views
-1

我讀的書「21世紀C」(第一的Editon),並使用asprintf 得到的字符串不使用的malloc /尺寸爲字符串的長度找到一個有趣的節目或空間分配。請閱讀同一本書附帶的圖片以瞭解上下文。以下程序也來自本書。程序編譯運行,而不是從鍵盤輸入字符串輸入,而是獲得以下消息。問題是:爲什麼程序不會從keboard獲取字符串輸入,而是顯示長(不尋常)的錯誤消息?asprintf - 如何讓字符串輸入用C

#define _GNU_SOURCE // stdio.h to include asprintf 
#include <stdlib.h> 
#include <stdio.h> 

void get_strings(char const *in) { 
    char *cmd; 
    asprintf(&cmd, "strings %s", in); 
    if (system(cmd)) 
     fprintf(stderr, "Something went Wrong %s.\n", cmd); 
    free(cmd); 
} 

int main(int argc, char **argv) { 
    get_strings(argv[0]); 
    //return 0; 
} 

當運行該程序的輸出是:

/lib64/ld-linux-x86-64.so.2 
libc.so.6 
__stack_chk_fail 
asprintf 
stderr 
system 
fprintf 
__libc_start_main 
free 
__gmon_start__ 
GLIBC_2.4 
GLIBC_2.2.5 
UH-X 
AWAVA 
AUATL 
[]A\A]A^A_ 
strings %s 
Something went Wrong %s. 
;*3$" 
GCC: (Ubuntu 5.3.1-14ubuntu2) 5.3.1 20160413 
crtstuff.c 
__JCR_LIST__ 
deregister_tm_clones 
__do_global_dtors_aux 
completed.7585 
__do_global_dtors_aux_fini_array_entry 
frame_dummy 
__frame_dummy_init_array_entry 
get_strings.c 
__FRAME_END__ 
__JCR_END__ 
__init_array_end 
_DYNAMIC 
__init_array_start 
__GNU_EH_FRAME_HDR 
_GLOBAL_OFFSET_TABLE_ 
__libc_csu_fini 
[email protected]@GLIBC_2.2.5 
_ITM_deregisterTMCloneTable 
_edata 
[email protected]@GLIBC_2.4 
[email protected]@GLIBC_2.2.5 
get_strings 
[email protected]@GLIBC_2.2.5 
__data_start 
[email protected]@GLIBC_2.2.5 
__gmon_start__ 
__dso_handle 
_IO_stdin_used 
__libc_csu_init 
__bss_start 
[email protected]@GLIBC_2.2.5 
main 
_Jv_RegisterClasses 
__TMC_END__ 
_ITM_registerTMCloneTable 
[email protected]@GLIBC_2.2.5 
.symtab 
.strtab 
.shstrtab 
.interp 
.note.ABI-tag 
.note.gnu.build-id 
.gnu.hash 
.dynsym 
.dynstr 
.gnu.version 
.gnu.version_r 
.rela.dyn 
.rela.plt 
.init 
.plt.got 
.text 
.fini 
.rodata 
.eh_frame_hdr 
.eh_frame 
.init_array 
.fini_array 
.jcr 
.dynamic 
.got.plt 
.data 
.bss 
.comment 


------------------ 
(program exited with code: 0) 
Press return to continue 

**I running it on Linux Mint 18. GCC version -5.3.1 
Build setting - gcc -Wall -c "%f" 
Compile -  gcc -Wall -o "%e" "%f"** 

enter image description here

+0

問題是......? – John3136

+0

問題是:爲什麼它不是在說鍵盤輸入的字符串? – Chandra

+1

@Chandra請將您的問題放入問題文章中,並且不要將它隱藏在評論中。 –

回答

4

該計劃的目的不是爲了從用戶獲取輸入:它使用system()功能與它自己的名字作爲唯一的參數運行strings程序。

如果您在Unix環境中運行,strings程序將掃描文件以獲取可打印的字符串。你觀察到的輸出更小於預期:由gcc產生的可執行程序包含了許多可打印的字符串:

  • 你能發現的文字出現在源代碼中的字符串: 出事了%S。
  • 衆多符號名稱是在加載時
  • 動態解析調試信息,如源文件的名稱:crtstuff.c
  • 部分名稱以.
  • 也有一些隨機的物品([]A\A]A^A_;*3$" ...),它們只是可執行文件代碼或二進制數據中可打印字符的序列,被string錯誤地解釋爲C字符串,因爲它們後面跟着空字節。
+0

同意。仔細閱讀後,系統命令運行一個外部實用程序。主題適當的實用程序,字符串,搜索二進制文件的可打印純文本。難怪由於argv [0]它會收到程序的名字。對我來說這是略微先進的概念。謝謝 – Chandra

+0

@Chandra:您可以通過點擊分數下方的灰色複選標記來接受此答案。 – chqrlie

1

。在你的程序中沒有地方,它從標準輸入/鍵盤讀取。 system("strings ...")正在傳遞一個文件名到strings命令,所以strings從該文件讀取而不是從鍵盤讀取。

如果您打算從傳遞給您的程序的文件名中讀取文件,則需要記住argv[0]是程序名稱。你需要看看argv[1]argv[2]等等。

for(int i = 1; i < argc; ++i) 
    get_strings(argv[i]); 
+0

是的,有想法。但是當我嘗試上面的代碼時,程序退出。但是argv固定值,即argv [2]。然後得到sh:1:語法錯誤:單詞意外(期待「)」) 有些事情發生了錯誤的字符串(空)。 – Chandra

+0

@Chandra'argv [2]'只有在argc> 2時纔可用,並且在調用它時將2個字符串傳遞給了您的程序。 –