2014-02-23 76 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