2014-02-23 75 views
0

我一直在使用strcat加入幾個字符串。一切似乎是正確的,打印:字符串字符脫落?

/proc/573/fd/ <- with the backslash 
13   <- length 

後,我嘗試了「SRC」字符串strcpy複製到另一個字符串,尾隨字符不無論是在「目標」或「源」字符串打印:

/proc/573/fd <- same string prints without the backslash? 
13   <- length is unchanged? 

如果我打電話strlen長度顯示它不變,但?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

// This function counts the number of digit places in 'pid' 
int pid_digit_places(int pid) 
{ 
    int n = pid; 
    int places = 0; 
    while (n) 
     n /= 10; 
     places++; 
    return places; 
} 

char *construct_path(int pid, char *dir) 
{ 
    // get count of places in pid 
    int places = pid_digit_places(pid); 
    char *pid_str = calloc(places, sizeof(char)); 

    // create string of pid 
    sprintf(pid_str, "%d", pid); 

    char *proc = "/proc/"; 
    size_t plen = strlen(proc); 
    size_t dlen = strlen(dir) + 1; 
    char *path = calloc(plen + dlen + places, sizeof(char)); 

    strcat(path, proc); 
    strcat(path, pid_str); 
    strcat(path, dir); 

    return path; 
} 

void fd_walk(int pid) 
{ 
    char *fd = "/fd/"; 
    char *fdpath = construct_path(pid, fd); 

    // prints "/proc/573/fd/ - as expected  
    printf("Before: %s\n", fdpath); 

    // shows a length of 13 
    printf("Size Before: %d\n", (int)strlen(fdpath)); 


    char *test = calloc(strlen(fdpath) + 1, sizeof(char)); 
    strcpy(test, fdpath); 

    // prints "/proc/573/fd" no trailing "/" 
    printf("Copied Str: %s\n", test); 

    //shows a length of 13 though 
    printf("Copied Size: %d\n", (int)strlen(test)); 

    // prints "/proc/573/fd" no trailing "/" now  
    printf("After: %s\n", fdpath); 

    // still shows length of 13 
    printf("Size After: %d\n", (int)strlen(fdpath));   
} 

int main(void) 
{ 
    // integer to create path around 
    int pid = 573; 
    fd_walk(pid); 
    return 0; 
} 

我在編譯與gcc-4.8.2-Wall

gcc -o src src.c -Wall 

我彈出這個小例子爲ideone

分配內存時,我已經確保爲null-terminator添加額外的空間。

我想過重新檢查我是如何初始化我的指針並沒有看到任何錯誤?如何按照預期的方式打印字符串printf,然後複製它,printf打印出不同的東西 - 未定義的行爲?

+3

零終止。你可能沒有分配空間來容納他們...... – Roddy

+0

@Roddy關鍵的事情是「終結者」(複數)我只佔一個終結者。謝謝 – tijko

+2

請注意:'pid_digit_places'永遠不會返回大於1的數字。 –

回答

3

我已經執行你的確切代碼沒有麻煩。儘管如此,我看到了兩個可能的問題:

// This function counts the number of digit places in 'pid' 
int pid_digit_places(int pid) 
{ 
    int n = pid; 
    int places = 0; 
    while (n) { // <-- The braces were missing here. 
     n /= 10; 
     places++; 
    } 
    return places; 
} 

char *construct_path(int pid, char *dir) 
{ 
    // get count of places in pid 
    int places = pid_digit_places(pid); 

    // You need "places" bytes for the digits, plus one for the zero 
    char *pid_str = calloc(places + 1, sizeof(char)); 

然而,在一般情況下,我不會浪費時間來分配正是我所需要的內存;額外的代碼在尺寸和複雜性方面都有很大的補償。

只是要在最大可能值猜測,並執行是猜測:

// avoid pid_digit_places altogether 
pid_str = malloc(16); 
if (pid > 999999999999L) { 
    // fprintf an error and abort. 

    // Better yet, see whether this is a limit #define'd in the OS, 
    // and place an appropriate compile-time # warning. Chances are 
    // that unless your code's trivial, running it on a system with 
    // such large PIDs (and therefore likely so different an arch!) 
    // would cause some other troube to pop up. 
    // With an # error in place, you save also the pid check! 
} 
+0

我甚至沒有想過使用限制。謝謝您的幫助! – tijko