2012-07-02 5 views
2

У меня есть этот код:Append строка перед strdup C

if(S_ISDIR(fileStat.st_mode)){ 
    (*ls)[count++] = strdup(ep->d_name); 
    ep = readdir(dp); 
} else{ 
    (*ls)[count++] = strdup(ep->d_name); 
    ep = readdir(dp); 
} 

Как я могу добавить строку «DIR», чтобы получить что-то вроде:

if(S_ISDIR(fileStat.st_mode)){ 
     (*ls)[count++] = "DIR "strdup(ep->d_name); 
     ep = readdir(dp); 

Так что, когда я буду печатать у меня есть это:
file1 file2

DIR: file3
ЕСС

, где ls is char ***ls
Заранее благодарен!

ответ

2

Существует несколько способов достижения этого: вы можете использовать strcat, или если вам нужно сделать несколько модификаций, вы можете использовать snprintf.

size_t len = strlen(ep->d_name); 
// You need five characters for "DIR: ", and one more for the terminating zero: 
(*ls)[count] = malloc(len+6); 
strcpy((*ls)[count], "DIR: ");  // Copy the prefix 
strcat((*ls)[count++], ep->d_name); // Append the name 
+0

'sprintf' очень опасно. Предпочитаете 'snprintf'. –

+0

@larsmans ОК, теперь это исправлено. – dasblinkenlight

+0

1) почему мне нужно 5 символов? 2) правильно делать 'free ((* ls) [count]);'? – polslinux

1

Используйте asprintf, который выделяет строку и printf s ей. Что-то вроде:

#include <stdio.h> 

asprintf(&((*ls)[count++]) "DIR%s", ed->d_name); 

Я предполагаю, что ls является указателем на массив char *. Не забудьте освободить строки позже!

+0

Ls является символом *** ls :) – polslinux

+0

Да, вы можете прочитать 'char *** ls' как 'указатель на массив char *'. – Joe

+0

но где asprintf inclued ?? Я не могу это найти! – polslinux

2

Самый простой способ использует (нестандартные) функции asprintf

if(asprintf(&(*ls)[count++], "DIR %s", ep->d_name) == -1) /* error */; 

Он выделяет указатель в (*ls)[count++] так же, как malloc (и ваш strdup).

+0

где он включен ?? Я на Linux, и я не могу его найти! – polslinux

+0

'asprintf' - это специфичная для GNU функция с действительно неуклюжим интерфейсом, но в принципе это правильный способ сделать это. Вы всегда можете написать свою собственную версию 'asprintf' в терминах' snprintf' в любом случае. –

+0

@R ..: Почему неуклюжий? Мне кажется, это прекрасно, так же просто, как и получается. Комитет, похоже, одобрил его в [TR 24731-2] (http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1337.pdf). – jpalecek

0

Некоторых вспомогательных функций, которые будут CONCATENATE произвольного количества строк в динамически выделенный буфер:

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

/* 
    vstrconcat() - return a newly allocated string that is the concatenation of 
       all the string passed in the variable length argument list. 

     The argument list *must* be terminated with a NULL pointer. 

     All other arguments must be char* to ASCIIZ strings. 

     Thre return value is a pointer to a dynamically allocated 
     buffer that contains a null terminated string with 
     all the argument strings concatenated. 

     The returned pointer must be freed with the standard free() 
     function. 

*/ 

char* vstrconcat(char const* s1, ...) 
{ 
    size_t len = 0; 
    char const* src = NULL; 
    char* result = NULL; 
    char* curpos = NULL; 

    va_list argp; 

    if (!s1) { 
     return NULL;   // maybe should return strdup("")? 
    } 

    // determine the buffer size needed 

    src = s1; 
    va_start(argp, s1); 

    while (src) { 
     len += strlen(src);  //TODO: protect against overflow 

     src = va_arg(argp, char const*); 
    } 

    va_end(argp); 

    result = malloc(len + 1); 
    if (!result) { 
     return NULL; 
    } 

    // copy the data 

    src = s1; 
    va_start(argp, s1); 
    curpos = result; 

    while (src) { 
     size_t tmp = strlen(src); 

     memcpy(curpos, src, tmp); 
     curpos += tmp; 

     src = va_arg(argp, char const*); 
    } 
    va_end(argp); 

    result[len] = '\0'; 

    return result; 
} 

/* 
    strconcat() - simple wrapper for the common case of concatenating exactly 
        two strings into a dynamically allocated buffer 

*/ 
char* strconcat(char const* s1, char const* s2) 
{ 
    return vstrconcat(s1, s2, NULL); 
} 

Вы могли бы назвать его, как это в вашем примере:

(*ls)[count++] = strconcat("DIR ", ep->d_name); 
Смежные вопросы